Duas formas de combinar branches: fast-forward e merge de três vias
Todo branch existe para voltar a se juntar
O curso de Branching construiu uma linha de histórico a partir do main e a deixou lá de propósito. O add-discount-percentage está dois commits à frente, intocado pelo main. Um branch que nunca se junta de volta não é trabalho terminado: é um experimento que ninguém aproveitou. O git merge é como ele volta para casa.
Caso um: fast-forward
Se o main não mudou desde que o branch se separou, juntar os dois é trivial. O Git só move o ponteiro do main para frente:
Antes: a ─▶ b (main)
\
c ─▶ d (feature)
Depois: a ─▶ b ─▶ c ─▶ d (main, feature)
git switch main
git merge feature
Updating b8e3f1a..7c6b5a4
Fast-forward
app/models/product.rb | 3 +++
1 file changed, 3 insertions(+)
Nenhum commit novo é criado: o main vira um ponteiro para o mesmo commit que o feature já aponta. Esse é o exato mecanismo que o git pull usou lá no curso de Remotos sempre que seu branch local não tinha nada próprio.
Caso dois: merge de três vias
Em qualquer projeto ativo, o main ganha commits próprios enquanto o branch está em andamento. Aí o fast-forward é impossível. Os dois históricos divergiram e os dois precisam ser mantidos:
Antes: e (main)
/
a ─▶ b ─▶ c ─▶ d
\
f ─▶ g (feature)
Depois: e ─────────────┐
/ ▼
a ─▶ b ─▶ c ─▶ d h (main)
\ ▲
f ─▶ g ──────────┘
git switch main
git merge feature
Merge made by the 'ort' strategy.
app/models/product.rb | 3 +++
1 file changed, 3 insertions(+)
O Git cria o commit h: um commit de merge com dois pais (e e g), combinando as duas linhas de histórico em uma só. Para descobrir o que mudou em cada lado, o Git compara três commits: o ancestral comum (d, o último commit que os dois branches compartilham) e as duas pontas. Daí "três vias".
Confirmando qual tipo acabou de acontecer
git log --oneline --graph -5
Um fast-forward mostra uma única linha reta, sem bifurcação. Um merge de três vias mostra a bifurcação explicitamente, com um commit de merge juntando as linhas de volta: visualmente, justamente os diagramas acima.
Forçando um commit de merge mesmo quando fast-forward é possível
Alguns times preferem que toda feature deixe uma marca visível no histórico do main, mesmo quando um fast-forward funcionaria tecnicamente:
git merge --no-ff feature
Isso sempre cria um commit de merge, e "esse grupo de commits foi uma feature só" fica legível como unidade no log. Alguns times adotam isso como padrão; o Git não exige.
Pontos-chave
- Um merge fast-forward só move o ponteiro do
mainpara frente, sem commit novo. Ele só é possível quando omainnão tem commits próprios desde a separação. - Um merge de três vias cria um commit de merge com dois pais, combinando históricos que divergiram usando o ancestral comum deles.
git log --oneline --graphmostra qual tipo aconteceu: uma linha reta versus uma bifurcação visível se juntando de volta.git merge --no-ffforça um commit de merge mesmo quando um fast-forward é possível, para times que querem os limites de feature visíveis no histórico.
Continue com a aula 2
Quando o Git não consegue fazer merge automático: conflitos
Mostra como surge um conflito quando os dois lados mudam as mesmas linhas e o que o git status mostra.
Com uma conta grátis você também tem os quizzes, seu progresso e suas anotações, e a discussão.