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 bisect e 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-parent e 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/trunk deve 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.