Comparação

git fetch vs git pull: qual a diferença e qual usar

Atualizado: · Skillaria.Top

O git fetch apenas baixa os novos commits do servidor e atualiza as branches remotas como origin/main, sem mexer nos seus arquivos nem nas suas branches. O git pull faz o mesmo e logo em seguida integra as alterações na branch atual via merge ou rebase. O fetch é sempre seguro; o pull é prático quando você está pronto para aceitar as alterações dos outros na hora.

Resposta curta

O git fetch baixa os novos commits do servidor e atualiza as referências das branches remotas (origin/main, origin/feature-x), mas não altera nem a sua branch atual nem os arquivos da pasta de trabalho. O git pull é um git fetch mais a integração imediata do que foi baixado com a branch atual: via merge (padrão) ou via rebase.

Daí a regra prática: o fetch pode ser executado a qualquer momento, ele não quebra nada. O pull altera a sua branch e pode terminar em conflito, então vale rodá-lo com a pasta de trabalho limpa e sabendo o que está para chegar.

Onde vivem as branches remotas

Para a diferença ficar clara, é preciso entender que no repositório local existem dois tipos de branch. As locais — main, feature-x — são movidas por você, com seus commits. As branches remotas de rastreamento — origin/main — são marcadores do tipo "era assim que o servidor estava na última sincronização". Elas não podem ser movidas à mão; só a comunicação com o servidor as atualiza: fetch, pull e push.

git branch -a
* main
  remotes/origin/HEAD -> origin/main
  remotes/origin/main
  remotes/origin/feature-x

O git status compara a sua branch justamente com o marcador origin/main, e não com o servidor ao vivo. Por isso a mensagem "Your branch is up to date with 'origin/main'" pode enganar: se você não faz fetch há tempos, o Git simplesmente não sabe dos novos commits dos colegas.

O que o git fetch faz

$ git fetch
remote: Enumerating objects: 7, done.
remote: Counting objects: 100% (7/7), done.
Unpacking objects: 100% (4/4), done.
From github.com:team/project
   3f2a1c9..8b7d4e2  main       -> origin/main

A última linha diz o principal: a referência origin/main passou de 3f2a1c9 para 8b7d4e2. A sua main ficou onde estava. Agora você pode ver com calma o que chegou:

git status                       # Your branch is behind 'origin/main' by 2 commits
git log main..origin/main --oneline   # commits que você não tem
git diff main origin/main        # o que vai mudar nos arquivos

Variações úteis do fetch:

  • git fetch --all — traz as alterações de todos os remotes (útil quando um fork tem origin e upstream);
  • git fetch --prune (-p) — remove os marcadores locais de branches que não existem mais no servidor;
  • git fetch origin main — traz só uma branch;
  • git fetch --tags — traz também todas as tags.

Para o prune funcionar sempre, ative-o uma vez: git config --global fetch.prune true.

O que o git pull faz

O git pull executa duas etapas seguidas. Primeiro, o fetch da branch upstream da branch atual; depois, a integração de origin/<branch> com a sua branch. Literalmente, equivale a:

git fetch origin
git merge origin/main      # ou git rebase origin/main com pull --rebase

O resultado da integração depende de como os históricos divergiram:

  • você não tem commits novos — acontece um fast-forward, a branch simplesmente avança;
  • há commits novos tanto seus quanto no servidor — com merge é criado um commit de merge, com rebase os seus commits são reposicionados por cima dos do servidor;
  • as mesmas linhas foram alteradas dos dois lados — conflito, que precisa ser resolvido à mão.

Comparação entre git fetch e git pull

git fetchgit pull
Baixa commitsSimSim
Atualiza origin/*SimSim
Altera a branch atualNãoSim
Altera arquivos na pasta de trabalhoNãoSim
Pode causar conflitoNãoSim
Exige pasta de trabalho limpaNãoDe preferência
Afeta outras branchesAtualiza todos os marcadores rastreadosIntegra só na atual
Quando usarVer o que mudou; antes de um rebase; em scriptsAlcançar rapidamente o servidor na sua branch

git pull: merge ou rebase

Desde o Git 2.27, quando o histórico diverge e não há configuração explícita, o pull mostra um aviso, e nas versões novas, em vez de um merge silencioso, ele para com o erro "Need to specify how to reconcile divergent branches". O Git pede que você escolha a estratégia uma vez:

git config --global pull.rebase false   # merge (o comportamento padrão antigo)
git config --global pull.rebase true    # rebase
git config --global pull.ff only        # só fast-forward, senão recusa

Merge preserva o histórico como estava e adiciona o commit "Merge branch 'main' of github.com:...". Se você faz pull todo dia numa branch com commits locais, o histórico se enche desses merges técnicos.

Rebase reposiciona os seus commits ainda não enviados por cima dos mais recentes do servidor. O histórico fica linear, e os conflitos são resolvidos um commit por vez. Para commits locais não publicados, costuma ser a melhor escolha. O rebase só é perigoso para commits já enviados, sobre os quais outras pessoas estão trabalhando.

ff only é o modo mais rigoroso: o pull só funciona quando você não tem commits próprios. Se o histórico divergiu, você decide explicitamente o que fazer. Muitos desenvolvedores experientes usam exatamente esse modo nas branches principais.

Se a pasta de trabalho tem alterações não commitadas e o pull é necessário agora, use git pull --rebase --autostash: o Git guarda as alterações, faz o rebase e as devolve.

Cenário típico: fetch, olhar, integrar

A abordagem "primeiro o fetch" dá controle sobre o que entra na sua branch. Ela é especialmente útil antes de abrir um pull request e depois de um longo intervalo.

git fetch
git log --oneline --graph HEAD origin/main   # como as branches divergiram
git rebase origin/main                       # ou git merge origin/main
git push

Outro caso frequente é atualizar a sua branch de feature com a main mais recente, sem mudar para ela:

git switch feature-x
git fetch
git rebase origin/main

Aqui o pull não serve: git pull na branch de feature traz as alterações do upstream dela (origin/feature-x), e não da branch principal. Claro que dá para escrever git pull --rebase origin main, mas a variante com fetch é mais clara.

Sincronização com o servidor: como manter a branch atualizada

Quem procura por "git sync" normalmente quer dizer o ciclo "trazer o que é dos outros, enviar o que é seu". No Git puro não existe um comando sync (o botão Sync existe nas IDEs e nos clientes gráficos e, por dentro, faz pull e depois push). Manualmente, um ciclo confiável é assim:

  1. git status — garantir que tudo foi commitado ou guardado com git stash;
  2. git pull --rebase — trazer as alterações e reposicionar os seus commits por cima;
  3. resolver conflitos, se houver: corrigir os arquivos, git add, git rebase --continue;
  4. rodar os testes;
  5. git push.

Para sincronizar um fork com o repositório original:

git remote add upstream https://github.com/original/project.git
git fetch upstream
git switch main
git merge --ff-only upstream/main
git push origin main

Problemas comuns com git pull

Your local changes would be overwritten by merge

O pull quer alterar arquivos que você está editando e não commitou. Opções: commitar, guardar (git stash, depois o pull e git stash pop) ou usar --autostash. Não é preciso apagar as alterações por causa do pull.

Conflito depois do pull

O Git para e mostra os arquivos com conflito no git status. Abra-os, escolha a versão certa entre os marcadores <<<<<<< e >>>>>>>, depois git add e git commit (no merge) ou git rebase --continue (no rebase). Mudou de ideia? git merge --abort ou git rebase --abort devolvem tudo ao estado anterior ao pull.

There is no tracking information for the current branch

A branch não tem upstream configurado, e o Git não sabe de onde puxar. Indique explicitamente: git pull origin main, ou configure a ligação uma vez: git branch --set-upstream-to=origin/main.

refusing to merge unrelated histories

Os repositórios local e remoto foram criados de forma independente — por exemplo, ao criar o repositório no servidor foi adicionado um README. Se tiver certeza de que precisa juntá-los: git pull origin main --allow-unrelated-histories.

Pull que deu errado: como reverter

Se o merge após o pull já foi concluído e o resultado não serve, volte a branch ao estado anterior: git reset --hard ORIG_HEAD. O comando apaga as alterações não commitadas, então confira o git status antes. Em último caso, a posição anterior da branch pode ser encontrada no git reflog.

Qual escolher

  • Quer saber o que há de novo sem mudar nada — git fetch.
  • Trabalha na sua branch e só quer alcançar o servidor — git pull --rebase (ou pull com pull.rebase true configurado).
  • Atualiza a branch principal sem commits seus — git pull --ff-only.
  • Precisa integrar a main numa branch de feature — git fetch e depois git rebase origin/main ou git merge origin/main.
  • Está escrevendo um script ou CI — fetch e comandos explícitos, sem pull.

Como isso fica no grafo de commits

Imagine que você e um colega partiram do commit C. Você fez localmente o commit D, e o colega enviou E ao servidor. Depois do git fetch, o seu repositório conhece as duas linhas: main aponta para D, origin/main para E, e elas têm o ancestral comum C.

          D   <- main (HEAD)
         /
A---B---C
         \
          E   <- origin/main

A partir daí, tudo depende da forma de integração. git merge origin/main cria um commit M com dois pais, D e E. git rebase origin/main copia D por cima de E como um novo commit D', com outro hash, e o histórico vira uma linha reta. O git pull apenas executa esses mesmos passos automaticamente, sem pausa entre eles. É justamente essa pausa — a chance de olhar o grafo antes de integrar — o principal valor de um fetch separado.

Fetch e pull na IDE

No VS Code, no IntelliJ IDEA e em outros editores, os botões têm nomes diferentes, mas por trás estão os mesmos comandos. "Fetch" é o git fetch, "Pull" ou "Update Project" é o pull com a estratégia escolhida nas configurações (merge ou rebase), e "Sync Changes" é pull seguido de push. Antes de clicar em Sync numa branch compartilhada, vale saber qual estratégia está configurada, senão commits de merge aparecem no histórico de surpresa. Muitas IDEs também fazem fetch periodicamente em segundo plano, então o contador de commits recebidos na barra de status costuma estar atualizado.

Resumo

O git fetch atualiza o que você sabe sobre o servidor; o git pull ainda aplica esse conhecimento à branch atual. O fetch é seguro a qualquer momento; o pull é prático, mas altera a branch e pode trazer conflitos, então configure a estratégia dele uma vez e mantenha a pasta de trabalho limpa. A diferença entre push, pull e fetch, o trabalho com remotes e com o GitHub são praticados no curso de Git.

Perguntas frequentes

Preciso fazer git fetch antes do git pull?

Não, o pull já faz o fetch como primeira etapa. O fetch separado serve quando você quer primeiro ver as alterações e só depois decidir como integrá-las.

O git fetch pode apagar minhas alterações?

Não. O fetch altera apenas as referências remotas como origin/main e não mexe nas branches locais, no índice nem na pasta de trabalho.

O git pull atualiza todas as branches?

Não, o pull integra as alterações só na branch atual. Os marcadores origin/* das outras branches são atualizados graças ao fetch, mas as branches locais ficam onde estão.

Com que frequência fazer git fetch?

Antes de começar a trabalhar, antes de abrir um pull request e antes do push. Muitas IDEs fazem fetch automaticamente em segundo plano, e isso é seguro.

O que é FETCH_HEAD?

Uma referência interna em que o fetch grava o que foi baixado por último. Por exemplo, depois de git fetch origin main você pode executar git merge FETCH_HEAD.

Aprenda este tema em vídeo

Este tema é abordado em profundidade, com prática, no curso “Git do zero ao desenvolvedor confiante”.

Ir para o curso