Quando fazer um merge ou um rebase?

Olá todos!

Achei a explicação do livro sobre em que situações deve ser feito um merge ou rebase muito sucinta. O pessoal aqui do fórum poderia elencar situações do dia-a-dia que é preferível um ou outro? Gostaria de exemplos o mais práticos possíveis!

Agradeço a atenção!

1 curtida

Olá, Fabrício.

Você chegou a ver a discussão sobre git pull x git pull --rebase no capítulo de branches remotas (Cap. 7)?
Além disso, há uma discussão sobre maneiras de trabalhar com o git no capítulo 10.

No fim das contas, o lance é não usar só rebase ou só merge, mas os dois juntos.


Recapitulando

O git merge e o git rebase servem para a mesma coisa: mesclar alterações de duas branches diferentes.

O merge, na maioria das vezes, gera um novo commit, o que pode complicar o histórico, mas nunca o reescreve. Já o rebase, deixa o histórico linear e mais simples, mas alguns commits são reescritos.

Quando não há novos commits na branch que vai receber os novos commits, é só mexer os apontadores do git. Esse tipo de mesclagem é o fast-forward, que tem o mesmo resultado tanto pra merge como pra rebase.

Ao trabalharmos com branches remotas (o que é inevitável num projeto), precisamos decidir entre git pull (que não passa de um fetch seguido de um merge) e git pull --rebase (um fetch com um rebase).

Usar sempre merge ou sempre rebase é uma ideia muito ruim.

A política de sempre merge leva a históricos desse tipo (de um projeto real):

Se você fizer sempre rebase, você vai ter problemas com branches remotas porque o git não vai deixar você fazer push de um histórico alterado. Só se você forçar a barra com o --force (perigo!).

Detalhe: há ainda o rebase interativo, em que você pode mudar o histórico do seu projeto do jeito que você quiser, reescrevendo mensagens de commits, agrupando vários commits em um só, etc… Aí já é mais complicado. Tem equipe que gosta de adotar pra limpar ainda mais o histórico, mas eu não acho legal.


Regra: não fazer rebase na master

Quando você trabalha em equipe, a master é uma branch pública, compartilhada sua equipe pela remota origin/master.

É importante evitar fazer rebase de outra branch na master.

Porém, você pode fazer rebase da master na sua outra branch. Assim, você vai recriar a sua branch com o commit base da branch sendo o último commit da master e os novos commits da branch logo depois. A vantagem é que você vai poder, depois disso, o merge da branch na master vai gerar um fast-forward, deixando o histórico linear.

Algumas equipes gostam de fazer o merge só quando a funcionalidade/correção terminar e usar a opção --no-ff no merge para forçar um commit de merge. Assim, fica o histórico fica linearizado na branch, mas o último commit fica destacado com um commit de merge.

É uma boa usar o pull --rebase, porque vai pegar as novidades da branch remota e recriar o commit base da sua branch local, colocando depois os novos commits que você ainda não compartilhou.


Um workflow com rebase

Se você procurar sobre merge vs rebase que você vai encontrar boa parte dos posts falando sobre o seguinte workflow:

a) Pegar as novidades da master remota (origin/master)
$ git checkout master $ git pull --rebase origin master
Obs.: os novos commits locais da master ficariam linearizados

b) Pegar as novidades remotas da sua branch
$ git checkout sua-branch $ git pull --rebase origin sua-branch

c) Mesclar com rebase a master na sua branch
$ git rebase master

d) Ir comitando e repetindo os passos acima diariamente.
Assim, você vai pegar novidades da master e da sua branch remota.

e) Quando você terminar a funcionalidade/correção, fazer merge da sua branch na master com no-ff pra evitar o fast-forward.
$ git checkout master $ git merge sua-branch --no-ff
Uma das empresas que segue esse workflow em seus projetos comerciais é a brasileira Plataformatec, uma empresa com vários commiters do Rails. A australiana Atlassian que mantém o JIRA e o Bitbucket, também.

2 curtidas

@alexandre.aquiles,

excelente explicação! Sanou TODAS as minhas dúvidas! Parabéns e muito orbigado! :slight_smile: