Sobre nós Guias Projetos Contactos
Админка
please wait

Introdução

A proficiência em Git vai além de commits básicos. Engenheiros sénior precisam de gerir estratégias de branching complexas, resolver conflitos de forma eficiente e manter um histórico de projeto limpo. Este guia aborda workflows e técnicas práticas de Git para equipas de desenvolvimento profissionais.

Gestão de Branches

Workflow de Feature Branch

# Comece a partir de main atualizada
git checkout main
git pull origin main
# Criar feature branch
git checkout -b feature/user-authentication
# Trabalhar, fazer commit, fazer push
git add .
git commit -m "Add login form component"
git push -u origin feature/user-authentication
# Manter a branch atualizada com main
git fetch origin
git rebase origin/main
# Ou faça merge, se preferir
git merge origin/main
# Após revisão, fazer merge para main
git checkout main
git merge --no-ff feature/user-authentication
git push origin main
# Limpeza
git branch -d feature/user-authentication
git push origin --delete feature/user-authentication

Convenções de Nomenclatura de Branches

feature/add-user-auth # Novas funcionalidades
bugfix/fix-login-error # Correções de bugs
hotfix/security-patch # Correções urgentes em produção
release/v1.2.0 # Preparação de release
docs/update-readme # Documentação
refactor/cleanup-models # Refatoração de código

Boas Práticas de Commits

Commits Atómicos

Cada commit deve ser uma única alteração lógica:

# Mau: um commit com várias alterações
git commit -m "Add login, fix header, update styles"
# Bom: commits separados
git commit -m "Add login form validation"
git commit -m "Fix header alignment on mobile"
git commit -m "Update button styles for consistency"

Formato da Mensagem de Commit

<type>(<scope>): <subject>
<body>
<footer>

Exemplo:

feat(auth): add JWT token refresh mechanism
Implement automatic token refresh when access token expires.
The refresh happens 5 minutes before expiration to prevent
interruption of user sessions.
Closes #123

Tipos:

  • feat: Nova funcionalidade
  • fix: Correção de bug
  • docs: Documentação
  • style: Formatação (sem alteração de código)
  • refactor: Reestruturação de código
  • test: Adição de testes
  • chore: Tarefas de manutenção

Staging Interativo

# Fazer stage de hunks específicos
git add -p
# y: fazer stage deste hunk
# n: ignorar este hunk
# s: dividir em hunks mais pequenos
# e: editar o hunk manualmente
# Fazer stage de ficheiros específicos de forma interativa
git add -i

Estratégias de Merge

Merge vs Rebase

# Merge: preserva o histórico, cria um merge commit
git checkout main
git merge feature/branch
# Rebase: histórico linear, reescreve commits
git checkout feature/branch
git rebase main
git checkout main
git merge feature/branch # Fast-forward

Quando Usar Cada Um

CenárioEstratégia
Branches públicasMerge
Branches pessoais de funcionalidadeRebase
Branches de funcionalidade partilhadasMerge
Atualizar a partir de mainRebase (normalmente)

Resolução de Conflitos

# Durante o merge
git merge feature/branch
# CONFLICT in file.txt
git status # Ver ficheiros em conflito
# Editar ficheiros para resolver conflitos
# Remover marcadores de conflito: <<<<<<<, =======, >>>>>>>
# Marcar como resolvido
git add file.txt
git commit
# Durante o rebase
git rebase main
# CONFLICT in file.txt
# Resolver conflitos
git add file.txt
git rebase --continue
# Ou abortar, se necessário
git rebase --abort

Manter a Versão Local ou Remota

# Manter a nossa versão (branch atual)
git checkout --ours file.txt
# Manter a versão deles (branch recebida)
git checkout --theirs file.txt
# Para ficheiros binários
git checkout --ours -- path/to/binary.png
git add path/to/binary.png

Reescrever o Histórico

Amend ao Último Commit

# Corrigir mensagem de commit
git commit --amend -m "New message"
# Adicionar ficheiros esquecidos
git add forgotten-file.txt
git commit --amend --no-edit

Rebase Interativo

# Editar os últimos 5 commits
git rebase -i HEAD~5
# No editor:
# pick abc1234 Primeiro commit
# reword def5678 Segundo commit # Alterar mensagem
# squash ghi9012 Terceiro commit # Combinar com o anterior
# fixup jkl3456 Quarto commit # Combinar, descartar mensagem
# drop mno7890 Quinto commit # Remover por completo
# edit pqr1234 Sexto commit # Parar para editar
# Durante a paragem para edição
# Fazer alterações
git add .
git commit --amend
git rebase --continue

Squash de Commits Antes do Merge

# Fazer squash de todos os commits da feature branch num só
git checkout feature/branch
git rebase -i main
# Marcar todos, exceto o primeiro, como «squash»
# Ou squash merge
git checkout main
git merge --squash feature/branch
git commit -m "Add complete feature"

Stashing de Alterações

Stash Básico

# Fazer stash das alterações atuais
git stash
# Fazer stash com mensagem
git stash save "WIP: working on login form"
# Incluir ficheiros não rastreados
git stash -u
# Incluir ficheiros não rastreados e ignorados
git stash -a
# Listar stashes
git stash list
# Aplicar e remover
git stash pop
# Aplicar sem remover
git stash apply
# Aplicar stash específico
git stash apply stash@{2}
# Eliminar stash
git stash drop stash@{0}
# Limpar todos os stashes
git stash clear

Workflow de Stash

# A trabalhar numa funcionalidade, entra um bug urgente
git stash save "feature: in progress"
# Corrigir bug em main
git checkout main
git checkout -b hotfix/urgent
# ... corrigir bug ...
git commit -m "fix: urgent bug"
git checkout main
git merge hotfix/urgent
# Voltar à funcionalidade
git checkout feature/branch
git stash pop

Comparar e Rever

Comandos Diff

# Diretório de trabalho vs. staging
git diff
# Staging vs. último commit
git diff --staged
git diff --cached
# Entre commits
git diff abc123..def456
# Entre branches
git diff main..feature/branch
# Ficheiro específico
git diff HEAD~3 -- path/to/file.txt
# Apenas resumo
git diff --stat

Comparar Branches

# Commits em feature que não estão em main
git log main..feature/branch
# Commits em qualquer uma, mas não em ambas
git log main...feature/branch
# Que branch contém um commit
git branch --contains abc123

Recuperar de Erros

Anular Alterações

# Descartar alterações no diretório de trabalho
git checkout -- file.txt
git restore file.txt # Git 2.23+
# Retirar ficheiro do staging
git reset HEAD file.txt
git restore --staged file.txt # Git 2.23+
# Anular o último commit (manter alterações)
git reset --soft HEAD~1
# Anular o último commit (descartar alterações)
git reset --hard HEAD~1
# Reverter commit (cria novo commit)
git revert abc123

Recuperar Branches Eliminadas

# Encontrar o commit
git reflog
# Recriar branch
git checkout -b recovered-branch abc123

Recuperar Commits Perdidos

# Encontrar no reflog
git reflog
# Cherry-pick ou reset para recuperar
git cherry-pick abc123
# ou
git reset --hard abc123

Git Hooks

Hook pre-commit

# .git/hooks/pre-commit
#!/bin/sh
# Executar linter
npm run lint
if [ $? -ne 0 ]; then
echo "Lint failed. Commit aborted."
exit 1
fi
# Executar testes
npm test
if [ $? -ne 0 ]; then
echo "Tests failed. Commit aborted."
exit 1
fi

Hook commit-msg

# .git/hooks/commit-msg
#!/bin/sh
# Impor conventional commits
commit_regex='^(feat|fix|docs|style|refactor|test|chore)(\(.+\))?: .{1,50}'
if ! grep -qE "$commit_regex" "$1"; then
echo "Invalid commit message format."
echo "Example: feat(auth): add login functionality"
exit 1
fi

Trabalhar com Repositórios Remotos

Configuração de Chave SSH

# Gerar chave SSH
ssh-keygen -t ed25519 -C "[email protected]"
# Iniciar o agente SSH
eval "$(ssh-agent -s)"
# Adicionar chave ao agente
ssh-add ~/.ssh/id_ed25519
# Copiar chave pública
cat ~/.ssh/id_ed25519.pub
# Adicionar nas definições do GitHub/GitLab

Múltiplas Chaves SSH

# ~/.ssh/config
Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/github_key
Host gitlab.company.com
HostName gitlab.company.com
User git
IdentityFile ~/.ssh/gitlab_key

Remover Ficheiros do Repo mas Manter Localmente

# Remover do repo, manter ficheiro local
git rm --cached sensitive-file.txt
echo "sensitive-file.txt" >> .gitignore
git commit -m "Remove sensitive file from tracking"
# Remover ficheiros ignorados do repo
git rm -r --cached .
git add .
git commit -m "Remove files listed in .gitignore"

Compactar Repositório

# Remover objetos não referenciados
git gc --prune=now --aggressive
# Verificar o tamanho do repositório
git count-objects -vH

Corrigir Problemas de Encoding Durante o Merge

# Para ficheiros com encodings mistos
git config --global merge.renormalize true
# Ou corrigir manualmente um ficheiro específico
git checkout --ours problematic-file.txt
iconv -f WINDOWS-1252 -t UTF-8 problematic-file.txt > temp.txt
mv temp.txt problematic-file.txt
git add problematic-file.txt
git commit

Configuração

Aliases Úteis

# Adicionar a ~/.gitconfig
[alias]
st = status -sb
co = checkout
br = branch
ci = commit
lg = log --oneline --graph --decorate -20
lga = log --oneline --graph --decorate --all
last = log -1 HEAD --stat
unstage = reset HEAD --
amend = commit --amend --no-edit
undo = reset --soft HEAD~1
wip = !git add -A && git commit -m 'WIP'
cleanup = !git branch --merged | grep -v main | xargs git branch -d
# Mostrar o nome da branch atual
current = rev-parse --abbrev-ref HEAD
# Mostrar ficheiros alterados no último commit
changed = diff-tree --no-commit-id --name-only -r HEAD
# Listar branches ordenadas pelo último commit
recent = for-each-ref --sort=-committerdate refs/heads --format='%(committerdate:short) %(refname:short)'

Configuração Global

git config --global user.name "Your Name"
git config --global user.email "[email protected]"
git config --global init.defaultBranch main
git config --global pull.rebase true
git config --global core.editor "vim"
git config --global merge.tool vimdiff
# Gerir finais de linha
git config --global core.autocrlf input # Linux/Mac
git config --global core.autocrlf true # Windows
# Melhor algoritmo de diff
git config --global diff.algorithm histogram
# Mostrar diretórios não rastreados
git config --global status.showUntrackedFiles all

Workflows Avançados

Rebase Interativo para um Histórico Limpo

Limpe o seu histórico antes de fazer merge para main:

# Editar os últimos 5 commits
git rebase -i HEAD~5
# Ações disponíveis:
# - Squash: combinar commits «WIP» em «Feature X»
# - Reword: corrigir gralha nas mensagens de commit
# - Drop: remover commits acidentais
# - Edit: parar para modificar um commit

Dica Sénior: Trate o seu histórico de git como um produto. Um histórico limpo (linear, commits atómicos) permite reverter funcionalidades específicas sem reverter toda a release.

Encontrar Bugs com Bisect e Pesquisa Binária

Quando é que o bug apareceu?

  • Pesquisa manual: n passos de log
  • git bisect: Pesquisa binária (O(log n))
git bisect start
git bisect bad HEAD
git bisect good v1.0
# Automatize os testes!
git bisect run npm test

O Git fará checkout do commit do meio, executará o teste e reduzirá o intervalo automaticamente até encontrar o commit exato que introduziu o bug.

Submodules vs. Monorepo

Submodules: Apontadores para commits específicos de outros repos.

  • Dor: Esqueceu-se de atualizar o apontador? O build falha.
  • Perspetiva Sénior: Evite submodules a menos que seja estritamente necessário. Prefira monorepos (Nx, Turborepo) ou package managers (npm private registry).
# Se tiver mesmo de usar submodules
git submodule update --init --recursive
git submodule foreach git pull origin main

Conclusão

Dominar workflows de Git melhora a colaboração da equipa e a qualidade do código. Use feature branches para isolamento, commits significativos para o histórico e rebase para merges limpos. Conheça as suas opções de recuperação — o reflog é o seu amigo quando algo corre mal. Lembre-se: um histórico de git limpo é documentação — faça com que conte uma história clara de como o seu código evoluiu.

 
 
 
Языки
Темы
Copyright © 1999 — 2026
ZK Interactive