Git fetch vs git pull: diferenças importantes

1. Fundamentos: O que são git fetch e git pull?

Git fetch e git pull são comandos utilizados para sincronizar seu repositório local com um repositório remoto. Embora pareçam similares, suas funções e implicações no fluxo de trabalho são bastante distintas.

git fetch baixa os metadados e objetos (commits, branches, tags) do repositório remoto, mas não altera o estado do seu branch local. Ele atualiza apenas as referências remotas (como origin/main ou origin/feature), permitindo que você veja o que mudou no remoto sem integrar essas mudanças ao seu trabalho.

git pull é uma combinação de dois comandos: primeiro executa git fetch para baixar as informações do remoto e, em seguida, executa git merge (ou git rebase, dependendo da configuração) para integrar essas mudanças ao seu branch local ativo.

Uma analogia útil: git fetch é como baixar o catálogo de uma loja online — você vê todos os produtos disponíveis, mas não compra nada ainda. git pull é como baixar o catálogo e já clicar em "comprar tudo" — você obtém as informações e já integra ao seu carrinho.

2. Como git fetch funciona na prática

Quando você executa git fetch, o Git se conecta ao repositório remoto especificado, baixa todos os novos commits, branches e tags, e atualiza as referências remotas armazenadas localmente. Seu branch de trabalho permanece intocado.

Exemplo básico:

$ git fetch origin
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 5 (delta 2), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (5/5), 1.21 KiB | 310.00 KiB/s, done.
From https://github.com/usuario/repositorio
   1234abc..5678def  main       -> origin/main
   90ab12c..3456def  feature-x  -> origin/feature-x

Após o fetch, você pode inspecionar as diferenças sem risco:

$ git log main..origin/main --oneline
5678def (origin/main) Adiciona nova funcionalidade de busca
9012abc Corrige bug no formulário de login

Para buscar de todos os remotos configurados:

$ git fetch --all

3. Como git pull funciona na prática

git pull executa git fetch seguido de git merge (por padrão). Isso significa que, após baixar as mudanças, o Git tenta automaticamente mesclá-las ao seu branch atual.

Exemplo básico:

$ git pull origin main
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), 732 bytes | 366.00 KiB/s, done.
From https://github.com/usuario/repositorio
 * branch            main       -> FETCH_HEAD
   5678def..9012abc  main       -> origin/main
Updating 5678def..9012abc
Fast-forward
 index.html | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Se houver commits divergentes, o Git cria um merge commit automaticamente:

$ git pull origin main
Merge made by the 'ort' strategy.
 arquivo.txt | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

Para usar rebase em vez de merge:

$ git pull --rebase origin main

Ou configure globalmente:

$ git config --global pull.rebase true

4. Diferenças cruciais no fluxo de trabalho

A principal diferença reside no controle granular. Com git fetch, você decide quando e como integrar as mudanças. Com git pull, a integração é automática e imediata.

Vantagens do fetch:
- Permite revisar o que mudou antes de integrar
- Evita conflitos inesperados durante o merge automático
- Possibilita usar git log origin/main..main para ver commits locais ainda não enviados
- Permite comparar diferenças com git diff main origin/main

Riscos do pull:
- Pode gerar merge commits indesejados
- Conflitos podem interromper seu fluxo de trabalho
- Em branches com histórico não linear, o merge automático pode criar confusão

Exemplo de inspeção segura com fetch:

$ git fetch origin
$ git log --oneline main..origin/main
$ git diff main origin/main -- arquivo.txt
$ git merge origin/main  # integração manual e controlada

5. Quando usar git fetch em vez de git pull

Use git fetch quando:
- Você trabalha em branches compartilhadas com revisão de código (code review)
- Precisa comparar diferenças antes de mesclar
- Gerencia múltiplos remotos (como origin e upstream em forks)
- Deseja evitar merge commits acidentais

Exemplo em um fork de repositório:

$ git fetch upstream
$ git log --oneline upstream/main..main
$ git checkout -b revisao upstream/main
$ git diff main revisao

6. Quando usar git pull em vez de git fetch

Use git pull quando:
- Trabalha em branches pessoais onde você é o único contribuidor
- Utiliza fluxo de integração contínua (CI/CD) sem revisão prévia
- Possui pull.rebase configurado para manter histórico linear
- Precisa de sincronização rápida em repositórios com poucos colaboradores

Exemplo com rebase:

$ git config pull.rebase true
$ git pull origin feature-pessoal
Successfully rebased and updated refs/heads/feature-pessoal.

7. Boas práticas e armadilhas comuns

Armadilhas:
- git pull em branches com histórico não linear pode gerar merge commits confusos
- Pull automático pode sobrescrever alterações locais não commitadas (se houver conflitos)
- Tags não são atualizadas por git pull — é necessário git fetch --tags

Boas práticas:
- Configure pull.ff only para evitar merge commits acidentais:

$ git config --global pull.ff only
  • Prefira git fetch + git merge manual em branches compartilhadas
  • Use git stash antes de pull para evitar conflitos com mudanças não commitadas

Estratégia recomendada:

$ git stash
$ git fetch origin
$ git log --oneline main..origin/main
$ git merge --ff-only origin/main
$ git stash pop

8. Relação com temas vizinhos da série

  • Tags: git pull não atualiza tags automaticamente. Use git fetch --tags para sincronizá-las.
  • Repositórios remotos: Tanto fetch quanto pull interagem com remotos como origin e upstream. Fetch permite buscar de múltiplos remotos sem integração.
  • Git push: Antes de fazer push, é recomendável fazer fetch (ou pull) para evitar rejeições por divergência de histórico.
  • Fork: Em forks, git fetch upstream é essencial para manter o fork sincronizado com o repositório original. git pull do próprio fork é opcional e mais arriscado.

Referências