15%

Poupe 15% em todos os serviços

Teste as suas habilidades e obtenha Desconto em qualquer plano

Utilizar o código:

Skills
Começar a trabalhar
14.10.2024

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ãoGit (Distribuído)SVN (Centralizado)
Modelo de repositórioClone completo em cada nóCópia de trabalho superficial, servidor guarda o histórico
Capacidade offlineCommit, branch, diff, log completosApenas leitura; commits requerem servidor
Custo de branchingQuase zero (manipulação de ponteiros)Cópia de diretório dispendiosa
Ponto único de falhaNenhum — qualquer clone pode restaurarFalha do servidor interrompe todos os commits
Estratégia de mergeMerge de três vias + rebaseApenas merge de três vias
Integridade do históricoHashing de conteúdo SHA-1/SHA-256Números de revisão sequenciais
Dependência de redeApenas para push/pull/fetchQuase todas as operações
Checkout parcialNão suportado nativamenteSuportado (sparse checkout)
Curva de aprendizagemCurva inicial mais acentuadaMais suave para veteranos do SVN
Adoção (2024)~95% das equipas profissionaisAmbientes 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 --list

A 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 branch

Clones 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 info

git 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 only

git 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 renames

A 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 files

Staging 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 changes

Regra 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 tags

Prefira --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 created

git 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 upstream

Branching 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 branch

Mudar 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 merge

Merge 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 conflict

Rebase 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égiaHistóricoCaso de UsoRisco
Merge (padrão)Não linear, preserva branchesBranches de funcionalidades de longa duração`git log` ruidoso
Merge `–no-ff`Não linear, commits de merge explícitosTopologia de branch impostaIgual ao anterior
Merge `–squash`Linear, um commit por funcionalidadeBranch principal limpoPerde histórico granular
RebaseLinear, sem commits de mergeBranches pessoais, limpeza pré-PRReescreve hashes; perigoso em branches partilhados
Cherry-pickSeletivo, linearBackporting de correçõesCommits 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-timeout

Fluxo 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 vimdiff

Desfazer 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árioComandoReescreve o HistóricoSeguro em Branch Partilhado
Remover ficheiro do staging`git restore –staged file`NãoSim
Descartar alterações no diretório de trabalho`git restore file`NãoSim
Desfazer último commit, manter alterações em staging`git reset –soft HEAD~1`SimNão
Desfazer último commit, manter alterações fora do staging`git reset HEAD~1`SimNão
Desfazer último commit, descartar todas as alterações`git reset –hard HEAD~1`SimNão
Desfazer um commit enviado com push de forma segura`git revert <hash>`NãoSim
Remover um ficheiro de todo o histórico`git filter-repo`SimNã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 commit

Comandos 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 stash

git 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 commits

O 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 done

Num 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 tag

Utilize 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-branch

Isto é 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 TrabalhoCadência de LançamentoTamanho da EquipaComplexidade de CI/CD
Branch por FuncionalidadeFlexívelQualquerBaixa
GitflowLançamentos agendadosMédia–GrandeMédia
Baseado em TrunkImplementação contínuaQualquerAlta

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:

HookAcionadorUso Comum
`pre-commit`Antes de o commit ser criadoExecutar linters, formatadores, testes
`commit-msg`Após a mensagem de commit ser escritaImpor formato de commit convencional
`pre-push`Antes do push para o remotoExecutar suite de testes completa
`post-receive`Após o remoto receber um pushAcionar implementação, enviar notificações
`pre-rebase`Antes de o rebase começarImpedir 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
fi

O 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.db

Armadilha 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:none descarrega 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/subdir obté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 --reachable pré-computa o grafo de commits, acelerando operações como git log --graph e 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.name e user.email definidos 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
  • .gitignore confirmado: Segredos, artefactos de compilação e ficheiros do SO excluídos antes do primeiro commit
  • Branch padrão com o nome main: init.defaultBranch definido globalmente para evitar a nomenclatura legada master
  • Mensagens de commit seguem uma convenção: Conventional Commits (feat:, fix:, chore:) ou formato acordado pela equipa imposto via hook commit-msg
  • git revert para histórico público: git reset --hard utilizado apenas em commits locais não enviados com push
  • --force-with-lease em vez de --force: Previne a sobreescrita acidental dos pushes de colegas
  • Tags anotadas para lançamentos: git tag -a com uma mensagem, não tags leves
  • Hooks partilhados via pre-commit ou husky: 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 --prune regular: 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.

15%

Poupe 15% em todos os serviços

Teste as suas habilidades e obtenha Desconto em qualquer plano

Utilizar o código:

Skills
Começar a trabalhar