O debate entre merge e rebase
Os usuários de Git continuam divididos sobre se commits de merge, rebasing ou squash‑merging produzem o histórico de projeto mais útil. Os defensores de workflows com rebase e squash valorizam uma branch principal linear e “curada” que simplifica `git bisect`, reversões e o raciocínio sobre mudanças, especialmente em escala ou em desenvolvimento trunk-based. Os críticos respondem que reescrever o histórico é frágil, obscurece o que realmente aconteceu e pode ser excessivamente propenso a erros para equipes menos experientes, argumentando em vez disso por fluxos de trabalho baseados em merge ou em patches, nos quais históricos bagunçados, porém precisos, são preservados e a complexidade é absorvida por ferramentas — não pelos desenvolvedores.
Merge vs. Rebase (e Bisectability)
- Muitos argumentam que históricos lineares geridos por rebase tornam
git bisecte o raciocínio sobre mudanças muito mais fáceis; históricos pesados em merges são descritos como “novelos de cabelo” que muitas vezes reduzem o bisect a “algum lugar neste grande merge”. - Outros contrapõem que
git log --first-parente opções de bisect mitigam a complexidade dos merges, e que commits de merge bem estruturados podem ser tão compreensíveis quanto commits squashed. - Alguns enfatizam que rebases grandes e cheios de conflitos são dolorosos e propensos a erros, especialmente em repositórios ativos, com múltiplos colaboradores.
Squash Merges e Granularidade de Commits
- Pró-squash:
main/trunkdeve conter unidades atômicas e reversíveis (PRs ou conjuntos de mudanças), não ruído de “wip/fix typo”; o squash é visto como a forma mais simples de manter o histórico limpo quando a higiene dos commits é ruim. - Anti-squash: o squash pode enterrar passos lógicos importantes (por exemplo, introdução de helper, refactors mecânicos, mudança complicada de caso extremo) em um único diff gigante, complicando blame, review e entendimento futuro.
- Vários adotam uma estratégia mista: squash em PRs barulhentos, preservar commits bem estruturados via merges
rebase+ff.
Fluxos de Trabalho e Modelos de Branching
- Exemplo de fluxos de trabalho:
- Fazer squash de branches de feature em staging, depois fazer merge de staging → master para releases.
- Trunk-based ou branches de vida muito curta com deploys frequentes vs. branches de feature de 2–3 semanas.
- Algumas equipes valorizam regras consistentes e simples (por exemplo, “sempre fazer squash”) para reduzir a carga cognitiva; outras preferem “depende”, escolhendo caso a caso por PR.
Ferramentas e Alternativas
- Ferramentas como Sapling e git-absorb são elogiadas por facilitar diffs empilhados e a limpeza de commits (por exemplo, reaplicar automaticamente edições no commit correto).
- Alguns veem o modelo do Git (branches como ponteiros, histórico de merge desajeitado) como uma limitação fundamental; alternativas como Mercurial ou fluxos de trabalho baseados em patches/stacked são mencionadas como conceitualmente mais limpas.
Filosofia: Histórico “Preciso” vs. “Curado”
- Um lado quer que o histórico reflita o que realmente aconteceu, incluindo falsos começos e commits bagunçados, argumentando que reescrever o histórico é “mentir” e pode dificultar auditorias ou depuração.
- O outro lado vê o histórico como uma narrativa curada de mudanças lógicas, não um caderno de laboratório imutável; prioriza legibilidade, passos lógicos menores e arqueologia mais fácil em vez de registrar cada passo em falso.
- Ambos os lados concordam que disciplina de commits e um “git style guide” compartilhado importam mais do que qualquer regra única.