Git merge vs rebase: diferenças, exemplos e quando usar cada um

  1. Início
  2. Blog
  3. Desenvolvimento de software
Desenvolvimento de software

Git merge vs rebase: diferenças, exemplos e quando usar cada um

Git merge vs rebase decide como fica o histórico do seu projeto. Veja os dois no mesmo exemplo com saída real do log, aprenda a regra que evita desastres e copie um fluxo de trabalho seguro para equipes.

7 min de leitura
Git merge vs rebase: diferenças, exemplos e quando usar cada um
Pontos principais
  • Merge une duas branches com um novo commit de merge e mantém o histórico exatamente como aconteceu.
  • Rebase reaplica seus commits sobre outra branch, o que dá uma linha reta, mas hashes novos.
  • Nunca faça rebase de commits que outras pessoas já baixaram.
  • Faça rebase da sua própria branch de funcionalidade antes de abrir um pull request e use merge ao levá-la para a branch principal.

Sua branch de funcionalidade está atrás da main e você precisa do trabalho novo. Git merge vs rebase é a escolha entre duas formas de obtê-lo, e ambas estão corretas. Elas diferem em como o histórico fica depois.

Criamos um repositório minúsculo, executamos os dois comandos e colamos a saída real abaixo, para você comparar o resultado em vez de imaginá-lo. Novo no Git? Comece pelo nosso tutorial de Git para iniciantes (em inglês).

O que git merge e git rebase fazem

git merge pega as pontas de duas branches e as combina. Se ambas têm commits novos, o Git cria um commit de merge com dois pais. Nada do que já existe é alterado.

git rebase pega os commits exclusivos da sua branch, deixa-os de lado, move sua branch para a ponta da outra e depois os reaplica um a um. Os commits reaplicados são commits novos com hashes novos, mesmo que as mudanças sejam as mesmas.

Git merge na prática

Nosso ponto de partida: commit A na main, dois commits (F1, F2) na feature e mais um commit (M1) adicionado depois à main. Agora fazemos merge da main na feature.

git switch feature
git merge main
git log --oneline --graph

*   f507aab Merge main into feature
|\
| * 8842fb5 M1
* | 082cc6a F2
* | 5a71e3c F1
|/
* 8766865 A

O gráfico mostra a história real: duas linhas de trabalho que foram unidas. Os commits originais F1 e F2 mantêm seus hashes. O custo é um commit de merge extra e, em um projeto movimentado, o gráfico vira uma teia.

Git rebase na prática

Mesmo ponto de partida, mas desta vez fazemos rebase da feature sobre a main.

git switch feature
git rebase main
git log --oneline --graph

* 1ff474b F2
* bf9149e F1
* 8842fb5 M1
* 8766865 A

O histórico é uma linha reta, como se você tivesse começado depois do M1. Olhe os hashes: F1 era 5a71e3c e agora é bf9149e, e F2 passou de 082cc6a para 1ff474b. O Git os reescreveu, e é por isso que o rebase exige cuidado.

Merge vs rebase lado a lado

AspectoMergeRebase
Forma do históricoGráfico ramificado com commits de mergeUma linha reta
Commits existentesInalteradosReescritos com hashes novos
ConflitosResolvidos uma vez, no commit de mergePodem precisar de correção em cada commit reaplicado
Seguro em branches compartilhadasSimNão
Melhor paraIntegrar trabalho concluído na mainAtualizar sua própria branch antes da revisão

Dica: se não conseguir decidir, pergunte quem mais tem a sua branch. Se ninguém, o rebase é seguro. Se um colega a baixou, use merge.

A regra de ouro do rebase

Não faça rebase de commits que existem fora do seu próprio repositório. Depois de um rebase, sua branch não corresponde mais à cópia do servidor, então o push exige força. Se um colega construiu trabalho sobre os commits antigos, o histórico dele agora diverge do seu, e resolver isso é doloroso.

Fazer rebase da sua branch privada de funcionalidade é aceitável. Fazer da main ou de qualquer branch usada por outros, não.

Um fluxo de trabalho seguro para equipes

Esta rotina mantém o histórico limpo sem surpreender ninguém. É também o que a maioria das equipes usa antes do pipeline de CI, como o do nosso guia de GitHub Actions CI/CD (em inglês).

git switch feature
git fetch origin
git rebase origin/main        # or: git pull --rebase
# fix conflicts, then: git add <file> && git rebase --continue
git push --force-with-lease   # only on your own branch

--force-with-lease se recusa a sobrescrever a branch do servidor se alguém tiver feito push desde o seu último fetch, o que um --force simples destruiria em silêncio. Quando o pull request for aprovado, faça merge dele na main.

Como desfazer um rebase ruim

Um rebase parece destrutivo, mas os commits antigos ficam por um tempo no reflog do Git, então você pode voltar atrás.

git reflog                    # find the commit before the rebase
git reset --hard HEAD@{5}     # example position, check reflog first

Crie uma branch de backup com git branch backup antes de qualquer rebase arriscado e a recuperação vira um único comando. Rodando um banco de dados ou ferramentas em contêineres? Veja nosso tutorial de Docker para iniciantes (em inglês).

Considerações finais

Merge preserva a verdade, rebase a mantém organizada. Use rebase para atualizar sua própria branch, merge para entregá-la e nunca reescreva um histórico do qual outras pessoas dependem.

Perguntas frequentes

Qual é a diferença entre git merge e git rebase?

Merge combina duas branches com um commit de merge e mantém todos os commits existentes. Rebase move seus commits para cima de outra branch e os reescreve, o que produz um histórico linear.

Devo usar merge ou rebase?

Faça rebase da sua própria branch de funcionalidade para mantê-la atualizada e use merge ao entregá-la numa branch compartilhada como a main. Use merge sempre que outras pessoas compartilharem a branch.

O git rebase é perigoso?

É seguro em branches privadas e arriscado em compartilhadas, porque reescreve os hashes dos commits. Use uma branch de backup e o reflog para se recuperar se algo der errado.

O que faz o force-with-lease?

Ele força o push apenas se a branch remota ainda estiver onde você a viu pela última vez, para que você não sobrescreva por acidente commits novos de um colega.

O rebase apaga meus commits?

Não. Ele cria commits novos com as mesmas mudanças, e os antigos permanecem no reflog até o Git limpá-los.

Continue aprendendo (artigos em inglês)

Trabalhe com a Stack Quora

Precisa de ajuda com testes, WordPress ou SEO?

Ajudamos equipes a entregar software melhor e a fazer seus sites crescerem. Conte no que você está trabalhando e sugeriremos um próximo passo claro.

Continue lendo

Mais guias sobre testes, IA e desenvolvimento moderno

Gostou deste artigo? Escolha um tópico e vá direto para nossos tutoriais mais recentes.

Inteligência artificial

Explicação das alucinações de IA: por que os modelos de linguagem inventam as coisas e como reduzi-las

Explicação das alucinações de IA: o que são, por que os modelos de linguagem as produzem, tipos comuns, como reduzi-las com aterramento e instruções…

Leia o artigo →
DevOps

Variáveis de ambiente explicadas: arquivos .env, segredos e configuração bem feitos

Variáveis de ambiente explicadas com exemplos de Python que executamos: leitura e configuração, por que cada valor é uma string, arquivos .env, hera…

Leia o artigo →
Desenvolvimento de software

Explicação da limitação de taxa de API: algoritmos, cabeçalhos e tratamento de erros 429

Limitação de taxa de API explicada com uma simulação que executamos: token bucket, janela fixa, janela deslizante, 429 respostas, cabeçalhos de limi…

Leia o artigo →
Automação de testes

Zombando em Python: unittest.mock, patch e os erros que fazem os testes mentirem

Zombaria em Python com unittest.mock, testado: Mock e return_value, side_effect, patch onde um nome é usado, especificação e autospec, zombaria de d…

Leia o artigo →
Teste de software

Cobertura de código explicada: cobertura de linha versus filial e o que 100% realmente significa

Cobertura de código explicada com uma execução cobertura.py real: cobertura de linha, ramal e condição, leitura de um relatório, por que 100% de cob…

Leia o artigo →
Bancos de dados e SQL

DELETE vs TRUNCATE vs DROP em SQL: diferenças, reversão e quando usar cada um

DELETE vs TRUNCATE vs DROP explicado com SQL testado: o que cada um remove, rollback, aciona, redefinição de identidade, velocidade e como PostgreSQ…

Leia o artigo →
Bancos de dados e SQL

Exibições SQL explicadas: crie, use e evite as armadilhas, com exemplos

Visualizações SQL explicadas com consultas que executamos: criação de uma visualização, resultados ao vivo, ocultação de colunas, desempenho, visual…

Leia o artigo →
Desenvolvimento de software

Interface TypeScript vs tipo: diferenças reais, testadas com o compilador

Interface TypeScript versus tipo, verificada com o compilador real: o que ambos podem fazer, o que apenas um pode fazer, mesclagem de declarações, e…

Leia o artigo →
Desenvolvimento de software

Python *args e **kwargs explicados: funções flexíveis com exemplos claros

Python *args e **kwargs explicados com o código que executamos: empacotamento e descompactação, ordem dos parâmetros, argumentos somente de palavras…

Leia o artigo →
Desenvolvimento de software

Funções Python Lambda: sintaxe, usos reais e quando não usá-los

Funções lambda do Python explicadas com o código que executamos: sintaxe, classificação com chave, mapa e filtro, fechamentos, armadilha de ligação …

Leia o artigo →
Inteligência artificial

O que são agentes de IA? Como eles funcionam, com um loop de agente simples que você pode executar

O que são agentes de IA? Um guia simples para o loop do agente, ferramentas, memória e proteções, com um pequeno loop Python que executamos, riscos …

Leia o artigo →
DevOps

Monitoramento versus observabilidade: a verdadeira diferença, com logs, métricas e rastreamentos

Explicação do monitoramento versus observabilidade: falhas conhecidas e desconhecidas, logs, métricas e rastreamentos, um passo a passo do incidente…

Leia o artigo →
DevOps

Docker Volumes vs Bind Mounts: persista os dados do contêiner da maneira certa

Volumes Docker versus montagens de ligação explicadas: por que os dados do contêiner desaparecem, volumes nomeados, montagens de ligação, tmpfs, exe…

Leia o artigo →
Automação de testes

TDD vs BDD: principais diferenças, um recurso criado de ambas as maneiras e quando usar cada um

TDD vs BDD explicado com um recurso de desconto construído em ambos os sentidos: refatoração vermelho-verde com o código que executamos, cenários da…

Leia o artigo →
Desenvolvimento de software

Git merge vs rebase: diferenças, exemplos e quando usar cada um

Git merge vs rebase explicado com saída real do log, uma tabela comparativa, a regra de ouro do rebase e um fluxo de trabalho seguro para equipes.

Leia o artigo →
Desenvolvimento de software

List comprehension em Python: sintaxe, exemplos e quando evitar

List comprehension em Python explicada: sintaxe, filtros, if-else, laços aninhados, tempos medidos e quando um laço for comum é a melhor escolha.

Leia o artigo →
Bancos de dados e SQL

SQL JOIN explicado com exemplos (Inner, Left, Right, Full)

Entenda os joins SQL passo a passo com tabelas e consultas de exemplo: INNER, LEFT, RIGHT, FULL, CROSS e SELF, além de erros comuns e dicas de desem…

Leia o artigo →