Controle de Versão Git: A Referência Técnica Completa para Desenvolvedores
Git é um sistema de controlo de versões distribuído (DVCS) que regista instantâneos da árvore de ficheiros de um projeto ao longo do tempo, permitindo que qualquer número de colaboradores trabalhe em paralelo sem sobrescrever as alterações uns dos outros. Cada programador possui uma cópia completa do repositório — incluindo todo o histórico de commits — na sua máquina local, eliminando qualquer ponto único de falha e permitindo fluxos de trabalho totalmente offline.
Criado por Linus Torvalds em abril de 2005 para substituir o BitKeeper no desenvolvimento do kernel Linux, o Git foi concebido desde os primeiros princípios em torno de três requisitos inegociáveis: velocidade, integridade dos dados e suporte para fluxos de trabalho não lineares e distribuídos. Esses objetivos de design ainda definem o que torna o Git categoricamente diferente dos seus predecessores e por que continua a ser o VCS dominante mais de duas décadas depois.
Como o Git Difere do Controlo de Versões Centralizado
Compreender a arquitetura do Git requer uma comparação direta com sistemas centralizados como o Subversion (SVN) ou o CVS, onde um único servidor autoritativo aloja o repositório canónico e os programadores obtêm cópias de trabalho superficiais.
| Dimensão | Git (Distribuído) | SVN (Centralizado) |
|---|---|---|
| — | — | — |
| Modelo de repositório | Clone completo em cada nó | Cópia de trabalho superficial, servidor guarda o histórico |
| Capacidade offline | Commit, branch, diff, log completos | Apenas leitura; commits requerem servidor |
| Custo de branching | Quase zero (manipulação de ponteiros) | Cópia de diretório dispendiosa |
| Ponto único de falha | Nenhum — qualquer clone pode restaurar | Falha do servidor interrompe todos os commits |
| Estratégia de merge | Merge de três vias + rebase | Apenas merge de três vias |
| Integridade do histórico | Hashing de conteúdo SHA-1/SHA-256 | Números de revisão sequenciais |
| Dependência de rede | Apenas para push/pull/fetch | Quase todas as operações |
| Checkout parcial | Não suportado nativamente | Suportado (sparse checkout) |
| Curva de aprendizagem | Curva inicial mais acentuada | Mais suave para veteranos do SVN |
| Adoção (2024) | ~95% das equipas profissionais | Ambientes empresariais legados |
O modelo distribuído significa que mesmo que uma plataforma de alojamento como o GitHub sofra uma interrupção, o clone local de cada programador é uma cópia de segurança completa e autoritativa de todo o histórico do projeto.
Arquitetura Central: O Que o Git Realmente Armazena
O Git não armazena diffs. Armazena instantâneos. Cada commit aponta para um objeto de árvore que representa o estado completo de cada ficheiro rastreado naquele momento. Se um ficheiro não foi alterado entre dois commits, o Git armazena um ponteiro para o blob anterior em vez de o duplicar — é assim que o Git alcança simultaneamente completude e eficiência de armazenamento.
Os quatro tipos de objetos fundamentais no repositório de objetos do Git (.git/objects/) são:
- Blob — conteúdo bruto do ficheiro, endereçado por hash SHA
- Tree — uma listagem de diretório que mapeia nomes de ficheiros para hashes de blob ou subárvore
- Commit — um ponteiro para uma árvore, zero ou mais commits pai, metadados do autor e uma mensagem
- Tag — um ponteiro anotado para um commit específico, utilizado para marcadores de versão
Cada objeto é imutável e endereçado por conteúdo. Alterar um único byte em qualquer ficheiro produz um hash SHA completamente diferente, que se propaga pelos objetos de árvore e commit. É por isso que o histórico do Git é criptograficamente resistente a adulterações — não é possível alterar silenciosamente um commit passado sem alterar todos os hashes de commits subsequentes.
A área de staging (também chamada de índice, armazenada em .git/index) é um ficheiro binário que contém o próximo commit proposto. Este modelo de três zonas — diretório de trabalho, índice, repositório — é a funcionalidade arquitetural mais incompreendida do Git e a fonte da maior parte da confusão dos iniciantes.
Instalar e Configurar o Git
Antes de executar qualquer comando, verifique a sua instalação e configure a sua identidade. O Git incorpora informações do autor em cada objeto de commit, e uma identidade mal configurada é uma das causas mais comuns de históricos de commits confusos em repositórios partilhados.
# Verify installation
git --version
# Set global identity (stored in ~/.gitconfig)
git config --global user.name "Your Name"
git config --global user.email "you@example.com"
# Set default branch name to 'main' (modern convention)
git config --global init.defaultBranch main
# Set preferred editor for commit messages
git config --global core.editor "vim"
# Enable colored output
git config --global color.ui auto
# Verify configuration
git config --listA configuração é em camadas: --system (todos os utilizadores, /etc/gitconfig), --global (utilizador atual, ~/.gitconfig) e --local (repositório, .git/config). Âmbitos mais específicos substituem os mais abrangentes.
Comandos Essenciais do Git: Referência Completa
Inicializar e Clonar
git init cria um novo repositório escrevendo um diretório .git/ na pasta atual. Não cria nenhum commit — o repositório começa vazio.
git init
git init my-project # Initialize into a new subdirectory
git init --bare repo.git # Bare repository (no working tree, used for servers)Um repositório bare contém apenas o repositório de objetos e refs — sem diretório de trabalho. Este é o formato correto para um repositório remoto para o qual múltiplos programadores fazem push. Se estiver a alojar o Git por conta própria num servidor de VPS Hosting, inicialize sempre os repositórios partilhados como bare.
git clone cria uma cópia local completa de um repositório remoto, incluindo todos os branches, tags e histórico.
git clone https://github.com/user/repo.git
git clone git@github.com:user/repo.git # SSH transport (preferred for auth)
git clone --depth 1 https://github.com/user/repo.git # Shallow clone (latest commit only)
git clone --branch develop https://github.com/user/repo.git # Clone specific branchClones superficiais (--depth) são úteis para pipelines de CI/CD onde apenas precisa do estado mais recente, não do histórico completo. Reduzem drasticamente o tempo de clone em repositórios grandes, mas impedem algumas operações dependentes do histórico como git bisect.
Inspecionar o Estado
git status é o comando executado com mais frequência em qualquer fluxo de trabalho. Mostra o estado das três zonas do seu repositório.
git status
git status -s # Short format: two-column status codes
git status -sb # Short format with branch infogit diff compara conteúdo entre zonas ou commits.
git diff # Working directory vs. index (unstaged changes)
git diff --staged # Index vs. last commit (what will be committed)
git diff HEAD # Working directory vs. last commit (all changes)
git diff main..feature # Compare tips of two branches
git diff abc123..def456 # Compare two specific commits
git diff --stat # Show changed files and line counts onlygit log percorre o grafo de commits. As suas opções de filtragem estão entre as funcionalidades mais poderosas e subutilizadas do Git.
git log
git log --oneline --graph --decorate --all # Visual branch graph
git log -p # Show patch (diff) for each commit
git log --author="Jane" # Filter by author
git log --since="2 weeks ago" # Filter by date
git log --grep="fix:" # Filter by commit message pattern
git log -- path/to/file # History of a specific file
git log --follow -- path/to/file # Follow renamesA combinação --graph --oneline --decorate --all é tão universalmente útil que a maioria dos engenheiros cria um alias para ela:
git config --global alias.lg "log --oneline --graph --decorate --all"Staging e Commits
git add filename.py # Stage a specific file
git add src/ # Stage an entire directory
git add . # Stage all changes in current directory
git add -p # Interactive patch staging (stage hunks, not whole files)
git add -u # Stage modifications and deletions, but not new filesStaging interativo (git add -p) é uma das funcionalidades mais poderosas e subutilizadas do Git. Permite rever e selecionar individualmente hunks dentro de um ficheiro, possibilitando commits precisos e atómicos mesmo quando o seu diretório de trabalho contém múltiplas alterações não relacionadas.
git commit -m "feat: add OAuth2 token refresh logic"
git commit --amend # Modify the most recent commit (message or content)
git commit --amend --no-edit # Amend content without changing the message
git commit -v # Open editor showing full diff of staged changesRegra crítica: Nunca altere commits que já foram enviados para um remoto partilhado. Alterar um commit reescreve o seu hash, forçando os colaboradores a fazer rebase ou reset dos seus branches locais.
Push e Pull
git push origin main
git push origin feature/auth # Push a specific branch
git push -u origin feature/auth # Push and set upstream tracking
git push --force-with-lease # Safer force push (fails if remote has new commits)
git push origin --delete old-branch # Delete a remote branch
git push --tags # Push all local tagsPrefira --force-with-lease em vez de --force quando tiver de reescrever o histórico remoto. Verifica que ninguém mais fez push desde o seu último fetch, prevenindo perda acidental de dados.
git pull origin main
git pull --rebase origin main # Fetch and rebase instead of merge
git pull --ff-only # Only fast-forward; abort if a merge commit would be createdgit fetch descarrega alterações remotas sem tocar no seu diretório de trabalho ou branch atual. Esta é a forma segura de inspecionar alterações upstream antes de as integrar.
git fetch origin
git fetch --all # Fetch from all remotes
git fetch --prune # Remove remote-tracking branches that no longer exist upstreamBranching e Merging: O Fluxo de Trabalho Central
O modelo de branching do Git é a sua funcionalidade arquiteturalmente mais significativa. Um branch é simplesmente um ponteiro com nome (um ficheiro de 41 bytes em .git/refs/heads/) para um hash de commit. Criar um branch é instantâneo independentemente do tamanho do repositório.
Gestão de Branches
git branch # List local branches
git branch -a # List all branches (local and remote-tracking)
git branch -v # List branches with last commit info
git branch feature/user-auth # Create a new branch
git branch -d feature/user-auth # Delete merged branch
git branch -D feature/user-auth # Force delete (even if unmerged)
git branch -m old-name new-name # Rename a branchMudar de Branch
O Git moderno (2.23+) separa as responsabilidades de git checkout em dois comandos dedicados:
git switch main # Switch to existing branch
git switch -c feature/payments # Create and switch in one step
git restore filename.py # Discard working directory changes to a file
git restore --staged filename.py # Unstage a file (remove from index)git checkout ainda funciona para todos estes casos, mas git switch e git restore têm semânticas mais claras e menos ambíguas e devem ser preferidos em fluxos de trabalho modernos.
Estratégias de Merge
git merge feature/user-auth # Standard merge (creates merge commit if needed)
git merge --no-ff feature/user-auth # Always create merge commit (preserves branch topology)
git merge --squash feature/user-auth # Squash all branch commits into one staged change
git merge --abort # Abort an in-progress conflicted mergeMerge fast-forward ocorre quando o branch de destino não divergiu do branch de origem — o Git simplesmente avança o ponteiro. Não é criado nenhum commit de merge. --no-ff força um commit de merge mesmo neste caso, o que preserva o histórico visual dos branches de funcionalidades em git log --graph.
Squash merge colapsa todos os commits de um branch de funcionalidade numa única alteração em staging, que depois é confirmada manualmente. Isto produz um histórico linear limpo em main mas descarta o histórico de commits granular do branch de funcionalidade.
Rebase
git rebase reproduz commits de um branch sobre outro, reescrevendo os seus hashes para criar um histórico linear.
git rebase main # Rebase current branch onto main
git rebase -i HEAD~5 # Interactive rebase: edit last 5 commits
git rebase --onto main server client # Transplant client branch onto main, excluding server
git rebase --abort # Abort a rebase in progress
git rebase --continue # Continue after resolving a conflictRebase interativo (-i) é a ferramenta de higiene de commits do profissional. Permite reordenar, juntar, editar, eliminar ou dividir commits antes de os partilhar. Caso de uso comum: limpar um branch de funcionalidade confuso antes de abrir um pull request.
| Estratégia | Histórico | Caso de Uso | Risco |
|---|---|---|---|
| — | — | — | — |
| Merge (padrão) | Não linear, preserva branches | Branches de funcionalidades de longa duração | `git log` ruidoso |
| Merge `–no-ff` | Não linear, commits de merge explícitos | Topologia de branch imposta | Igual ao anterior |
| Merge `–squash` | Linear, um commit por funcionalidade | Branch principal limpo | Perde histórico granular |
| Rebase | Linear, sem commits de merge | Branches pessoais, limpeza pré-PR | Reescreve hashes; perigoso em branches partilhados |
| Cherry-pick | Seletivo, linear | Backporting de correções | Commits duplicados entre branches |
A regra de ouro do rebase: Nunca faça rebase de commits que existam num branch público e partilhado. O rebase reescreve hashes de commits. Se um colega baseou trabalho nesses commits, o seu histórico irá divergir e ele enfrentará uma reconciliação dolorosa.
Resolver Conflitos de Merge
Os conflitos ocorrem quando dois branches modificam a mesma região do mesmo ficheiro. O Git marca o conflito no ficheiro com marcadores de conflito padrão:
<<<<<<< HEAD
const timeout = 30000;
=======
const timeout = 60000;
>>>>>>> feature/increase-timeoutFluxo de trabalho de resolução:
# After a conflicted merge or rebase
git status # Identify conflicted files (marked as "both modified")
# Edit each conflicted file, remove markers, keep correct content
git add resolved-file.js # Mark as resolved
git commit # Complete the merge (message is pre-populated)Para conflitos complexos, uma ferramenta de merge de três vias fornece uma visão mais clara:
git mergetool # Launch configured merge tool (vimdiff, meld, etc.)
git config --global merge.tool vimdiffDesfazer Alterações: A Matriz de Decisão
Escolher o comando de desfazer errado é uma das formas mais comuns de os programadores perderem trabalho ou corromperem o histórico partilhado. A escolha correta depende de duas variáveis: onde a alteração reside e se já foi enviada com push.
| Cenário | Comando | Reescreve o Histórico | Seguro em Branch Partilhado |
|---|---|---|---|
| — | — | — | — |
| Remover ficheiro do staging | `git restore –staged file` | Não | Sim |
| Descartar alterações no diretório de trabalho | `git restore file` | Não | Sim |
| Desfazer último commit, manter alterações em staging | `git reset –soft HEAD~1` | Sim | Não |
| Desfazer último commit, manter alterações fora do staging | `git reset HEAD~1` | Sim | Não |
| Desfazer último commit, descartar todas as alterações | `git reset –hard HEAD~1` | Sim | Não |
| Desfazer um commit enviado com push de forma segura | `git revert <hash>` | Não | Sim |
| Remover um ficheiro de todo o histórico | `git filter-repo` | Sim | Não |
git reset --soft HEAD~1 # Undo commit, keep changes in index
git reset HEAD~1 # Undo commit, keep changes in working dir
git reset --hard HEAD~1 # Undo commit, discard all changes permanently
git revert abc1234 # Create new commit that inverts abc1234
git revert HEAD~3..HEAD # Revert last 3 commits (creates 3 revert commits)
git revert -n HEAD~3..HEAD # Stage the reversals without committing (batch revert)git reset --hard é irreversível através dos comandos normais do Git. Se o executar acidentalmente, o único caminho de recuperação é git reflog, que regista cada posição para a qual HEAD apontou durante aproximadamente 90 dias.
git reflog # Show HEAD movement history with hashes
git checkout -b recovery abc1234 # Recover by creating a branch at the lost commitComandos Avançados para Fluxos de Trabalho em Produção
git stash
git stash guarda o estado atual do seu diretório de trabalho e do índice numa pilha, dando-lhe uma árvore de trabalho limpa para mudar de contexto.
git stash # Stash tracked changes
git stash -u # Include untracked files
git stash push -m "WIP: auth refactor" # Stash with a descriptive name
git stash list # List all stash entries
git stash pop # Apply most recent stash and remove it from stack
git stash apply stash@{2} # Apply specific stash without removing it
git stash drop stash@{2} # Delete a specific stash entry
git stash branch feature/wip # Create a new branch from a stashgit cherry-pick
git cherry-pick abc1234 # Apply a single commit to current branch
git cherry-pick abc1234 def5678 # Apply multiple commits
git cherry-pick abc1234 --no-commit # Apply changes without committing
git cherry-pick main~3..main # Apply a range of commitsO cherry-pick é o mecanismo padrão para backporting de correções de bugs para branches de manutenção. Se corrigir uma vulnerabilidade de segurança crítica em main, faz cherry-pick desse commit para v2.1-stable e v2.0-stable sem fazer merge de funcionalidades não relacionadas.
git bisect
git bisect realiza uma pesquisa binária através do histórico de commits para encontrar o commit exato que introduziu um bug. É uma das ferramentas de depuração mais poderosas e menos conhecidas do Git.
git bisect start
git bisect bad # Mark current commit as broken
git bisect good v2.3.0 # Mark a known-good commit or tag
# Git checks out the midpoint commit automatically
# Test your code, then:
git bisect good # If this commit is fine
git bisect bad # If this commit is broken
# Repeat until Git identifies the first bad commit
git bisect reset # Return to original HEAD when doneNum repositório com 1.000 commits entre os pontos bom e mau, git bisect encontra o culpado em no máximo 10 passos.
git tag
As tags marcam commits específicos como significativos — tipicamente versões de lançamento.
git tag v1.4.2 # Lightweight tag (just a pointer)
git tag -a v1.4.2 -m "Release 1.4.2" # Annotated tag (recommended; stores metadata)
git tag -a v1.4.2 abc1234 # Tag a specific past commit
git push origin v1.4.2 # Push a specific tag
git push origin --tags # Push all tags
git tag -d v1.4.2 # Delete local tag
git push origin --delete v1.4.2 # Delete remote tagUtilize sempre tags anotadas para lançamentos. Armazenam o nome, email, data e uma mensagem do criador da tag, e podem ser assinadas com GPG. As tags leves são adequadas apenas para marcadores locais temporários.
git worktree
git worktree permite que múltiplos diretórios de trabalho sejam obtidos do mesmo repositório simultaneamente — cada um num branch diferente. Isto elimina a necessidade de fazer stash ou commit de trabalho em curso quando precisa de mudar para uma correção urgente.
git worktree add ../hotfix-branch hotfix/critical-auth-bug
git worktree list
git worktree remove ../hotfix-branchIsto é particularmente valioso num Servidor Dedicado a executar um pipeline de CI/CD onde múltiplos trabalhos de compilação precisam de acesso simultâneo a diferentes branches do mesmo repositório sem interferir uns com os outros.
Fluxos de Trabalho Git para Equipas
A estratégia de branching correta depende do seu ritmo de lançamento e do tamanho da equipa. Existem três modelos dominantes:
Fluxo de Trabalho de Branch por Funcionalidade
Cada funcionalidade ou correção reside no seu próprio branch. Os programadores abrem pull requests para fazer merge em main. Simples e eficaz para a maioria das equipas.
Gitflow
Define branches de longa duração main e develop, mais branches de curta duração feature/, release/ e hotfix/ com regras de merge estritas. Adequado para software com lançamentos versionados explícitos (bibliotecas, aplicações empacotadas).
Desenvolvimento Baseado em Trunk
Os programadores fazem commit diretamente em main (ou utilizam branches de muito curta duração fundidos num dia). Depende fortemente de feature flags para ocultar trabalho incompleto. Preferido por equipas de alta velocidade que praticam implementação contínua.
| Fluxo de Trabalho | Cadência de Lançamento | Tamanho da Equipa | Complexidade de CI/CD |
|---|---|---|---|
| — | — | — | — |
| Branch por Funcionalidade | Flexível | Qualquer | Baixa |
| Gitflow | Lançamentos agendados | Média–Grande | Média |
| Baseado em Trunk | Implementação contínua | Qualquer | Alta |
Alojamento de Repositórios Git: Auto-Alojado vs. Plataformas Geridas
Para equipas que requerem soberania de dados, conformidade ou infraestrutura privada, alojar um servidor Git por conta própria é uma escolha viável e muitas vezes necessária. As opções incluem Gitea (leve, baseado em Go), GitLab CE (plataforma DevOps completa) e Forgejo (fork do Gitea com governação comunitária).
Uma instância Gitea auto-alojada mínima funciona confortavelmente num plano de VPS Hosting com 2 vCPUs e 2 GB RAM. Para equipas maiores ou GitLab CE com runners de CI, 4–8 GB RAM é o mínimo prático.
Ao auto-alojar, proteja o seu servidor Git com:
- Autenticação por chave SSH (desative completamente a autenticação por palavra-passe)
- HTTPS com um certificado válido — os Certificados SSL são essenciais para proteger credenciais em trânsito
- Regras de firewall que limitam a exposição da porta Git (22 ou porta SSH personalizada, 443 para HTTPS)
- Cópias de segurança automatizadas regulares dos diretórios de repositório bare
.git - Segredos de webhook para integrações de CI/CD
Para equipas que utilizam pipelines de implementação baseados em Git que também gerem infraestrutura web, combinar um servidor Git auto-alojado com um VPS com cPanel oferece hooks de implementação integrados juntamente com ferramentas familiares de gestão de alojamento.
Git Hooks: Automatizar Controlos de Qualidade
Os Git hooks são scripts que são executados automaticamente em pontos específicos do ciclo de vida do Git. Residem em .git/hooks/ e não são confirmados no repositório por padrão (utilize uma ferramenta como pre-commit ou husky para os partilhar).
Hooks principais para fluxos de trabalho em produção:
| Hook | Acionador | Uso Comum |
|---|---|---|
| — | — | — |
| `pre-commit` | Antes de o commit ser criado | Executar linters, formatadores, testes |
| `commit-msg` | Após a mensagem de commit ser escrita | Impor formato de commit convencional |
| `pre-push` | Antes do push para o remoto | Executar suite de testes completa |
| `post-receive` | Após o remoto receber um push | Acionar implementação, enviar notificações |
| `pre-rebase` | Antes de o rebase começar | Impedir rebase de branches partilhados |
# Example pre-commit hook: reject commits with debug print statements
#!/bin/bash
if git diff --cached | grep -E '^+.*(console.log|debugger|print("DEBUG)'; then
echo "ERROR: Debug statement detected. Remove before committing."
exit 1
fiO hook post-receive num repositório de servidor bare é a base da implementação simples baseada em Git: faz push para o servidor, o hook obtém o novo HEAD para a raiz web, executa passos de compilação e reinicia serviços — sem necessidade de plataforma de CI externa.
.gitignore: Manter os Repositórios Limpos
O ficheiro .gitignore indica ao Git quais os ficheiros e padrões a deixar sem rastreamento. Deve ser confirmado no repositório e mantido com cuidado.
# Dependencies
node_modules/
vendor/
# Build artifacts
dist/
build/
*.o
*.pyc
__pycache__/
# Environment and secrets — NEVER commit these
.env
.env.local
*.pem
*.key
config/secrets.yml
# IDE files
.idea/
.vscode/
*.swp
# OS files
.DS_Store
Thumbs.dbArmadilha crítica: Se um ficheiro já estava a ser rastreado antes de ser adicionado ao .gitignore, o Git continuará a rastreá-lo. Deve explicitamente deixar de o rastrear:
git rm --cached path/to/sensitive-file
git commit -m "chore: stop tracking secrets file"Nunca confirme credenciais, chaves de API ou chaves privadas num repositório — mesmo que seja privado. Utilize variáveis de ambiente, gestores de segredos (HashiCorp Vault, AWS Secrets Manager) ou ficheiros .env que estejam no .gitignore.
Otimização de Desempenho para Repositórios Grandes
O Git padrão degrada em repositórios com milhões de ficheiros ou gigabytes de recursos binários. Estratégias de mitigação:
- Git LFS (Large File Storage): Substitui ficheiros binários grandes por ficheiros de ponteiro no repositório e armazena o conteúdo real num servidor LFS separado. Essencial para repositórios que contêm multimédia, pesos de modelos de ML ou binários compilados.
- Clone parcial:
git clone --filter=blob:nonedescarrega commits e árvores mas obtém blobs a pedido. Reduz drasticamente o tamanho do clone inicial para monorepos grandes. - Sparse checkout:
git sparse-checkout set path/to/subdirobtém apenas um subconjunto da árvore de trabalho. Útil em monorepos onde um programador trabalha apenas num diretório de serviço. - Ficheiro commit-graph:
git commit-graph write --reachablepré-computa o grafo de commits, acelerando operações comogit log --graphe consultas de acessibilidade em históricos grandes. git maintenance start: Agenda tarefas de manutenção em segundo plano (empacotamento de objetos soltos, atualizações do commit-graph, prefetch de fetch) para manter as operações do repositório rápidas ao longo do tempo.
Lista de Verificação de Pontos-Chave Técnicos
Antes de considerar a sua configuração Git pronta para produção, verifique cada um dos seguintes pontos:
- Identidade configurada:
user.nameeuser.emaildefinidos corretamente no âmbito de configuração apropriado - Chaves SSH em uso: Autenticação por palavra-passe para remotos substituída por pares de chaves SSH ou HTTPS baseado em token
.gitignoreconfirmado: Segredos, artefactos de compilação e ficheiros do SO excluídos antes do primeiro commit- Branch padrão com o nome
main:init.defaultBranchdefinido globalmente para evitar a nomenclatura legadamaster - Mensagens de commit seguem uma convenção: Conventional Commits (
feat:,fix:,chore:) ou formato acordado pela equipa imposto via hookcommit-msg git revertpara histórico público:git reset --hardutilizado apenas em commits locais não enviados com push--force-with-leaseem vez de--force: Previne a sobreescrita acidental dos pushes de colegas- Tags anotadas para lançamentos:
git tag -acom uma mensagem, não tags leves - Hooks partilhados via
pre-commitouhusky: Controlos de qualidade impostos de forma consistente em toda a equipa - Git LFS configurado se o repositório contiver recursos binários acima de 1 MB
- Repositório bare no servidor: Remotos auto-alojados inicializados com
git init --bare git fetch --pruneregular: Refs de rastreamento remoto mantidos em sincronização com o estado real do remoto
Perguntas Frequentes
Qual é a diferença entre git fetch e git pull?
git fetch descarrega commits, branches e tags do remoto para as suas refs de rastreamento remoto local (por exemplo, origin/main) sem tocar no seu diretório de trabalho ou branch atual. git pull é git fetch seguido imediatamente de git merge (ou git rebase se configurado). Utilize git fetch quando quiser inspecionar alterações upstream antes de as integrar.
Quando devo usar git rebase em vez de git merge?
Utilize rebase para linearizar o seu branch de funcionalidade local antes de abrir um pull request, mantendo o histórico do projeto legível. Nunca faça rebase de um branch que outros programadores já clonaram ou no qual basearam trabalho — reescrever hashes de commits publicados força todos os outros a reconciliar históricos divergentes manualmente.
Como posso remover permanentemente um ficheiro sensível que foi acidentalmente confirmado?
Utilize git filter-repo (o substituto moderno de git filter-branch): git filter-repo --path secrets.env --invert-paths. Isto reescreve todo o histórico do repositório, removendo o ficheiro de cada commit. Após reescrever, force-push de todos os branches e tags, depois rode as credenciais expostas imediatamente — assuma que estão comprometidas independentemente da rapidez com que agir.
O que é o estado HEAD desanexado e como me recupero dele?
HEAD desanexado significa que o seu ponteiro HEAD referencia diretamente um hash de commit específico em vez de um nome de branch. Quaisquer commits que faça não pertencerão a nenhum branch e tornar-se-ão inacessíveis depois de mudar. Para recuperar: git switch -c new-branch-name para anexar os commits a um novo branch, ou git switch main para os descartar.
Como é que o Git trata os ficheiros binários de forma diferente dos ficheiros de texto?
O Git armazena ficheiros binários como blobs opacos — não consegue calcular diffs significativos ao nível de linha nem realizar merges automáticos neles. Os conflitos em ficheiros binários devem ser resolvidos escolhendo inteiramente uma versão. Para repositórios com recursos binários significativos, configure o Git LFS para armazenar binários externamente e manter o próprio repositório leve e rápido.
