O comando `git history`

O novo comando experimental `history` do Git, que simplifica tarefas comuns de rebase interativo como fixups, splits e rewords, está gerando reações mistas entre desenvolvedores. Alguns acolhem a maneira menos friccionada de reescrever e limpar o histórico de commits — especialmente para ensinar juniores ou manter logs bem estruturados e bissetáveis — enquanto outros argumentam que a edição complexa de histórico é usada em excesso, preferem merges simples com squash ou se preocupam com armadilhas de UX e conflitos. A discussão se expande para uma crítica à usabilidade do Git, ao valor de históricos curados versus lineares e a ferramentas alternativas como jj, Magit, stgit e ajudantes semânticos de diff/merge.

Papel e utilidade de git history

  • Os novos subcomandos de git history (fixup, split, reword) são vistos como wrappers ergonômicos para fluxos comuns de trabalho de git rebase -i.
  • Alguns preferem continuar com o rebase interativo para um controle preciso e “visual” sobre a ordem e a edição dos commits.
  • A capacidade de git history fixup de reescrever automaticamente todos os branches descendentes é apreciada, especialmente em comparação com rebase --update-refs, que se comporta de forma mais restrita.
  • Uma limitação observada: git history atualmente remove assinaturas GPG de commits reescritos, o que leva alguns usuários de volta ao rebase -i.

Tratamento de conflitos e dores de UX

  • Há forte discordância sobre o quão “assustadores” rebases e conflitos realmente são.
    • Um lado: conflitos são uma parte normal da composição de intenções diferentes; o medo reflete pouco entendimento do código ou do modelo do git.
    • Outro lado: mesmo com bom entendimento, a UX em torno de estados de rebase, “ours/theirs”, ferramentas interativas e edições no meio do rebase parece frágil e mentalmente cansativa.
  • Alguns argumentam que o Git trata código como texto simples; outros rebatem que diffs baseados em linhas são uma aproximação pragmática e podem ser melhorados com ferramentas baseadas em tree-sitter.

Redes de segurança e recuperação

  • Vários lembretes de que git rebase --abort, git reflog, tags/branches leves e git reset tornam a experimentação segura.
  • Várias pessoas criam rotineiramente branches “before-rebase” ou usam a sintaxe do reflog (por exemplo, branch@{1}) para recuperar estados anteriores.

Fluxos de trabalho: granularidade de commits, reescrita de histórico e squash

  • Divisão clara:
    • Grupo “curar o histórico”: commits pequenos, lógicos e que possam ser bissetados; o histórico é usado para depuração, regressões e entendimento da intenção. Reescrever histórico não mesclado é encorajado; squash é visto como jogar fora valor.
    • Grupo “squash/apenas anexar”: PRs como unidades atômicas; commits internos são “logs de trabalho” barulhentos e devem ser reduzidos antes do merge. Ênfase na eficiência do revisor e no valor de negócio em vez de histórico fino.
  • Debate sobre se manter commits de teste falhando, commits de fixup e cadeias de revert é útil (como evidência de TDD e arqueologia) ou prejudicial (quebra um git bisect simples, complica blame).

Ferramentas e alternativas

  • Vários recomendam ferramentas de nível mais alto para domar a complexidade:
    • GUIs como TortoiseGit, Magit e lazygit.
    • Ferramentas de patch-stack como stgit.
    • Sistemas mais novos como jj, que muitos elogiam conceitualmente, mas acham cru em relação à interoperabilidade com Git.
  • Há consenso de que UIs melhores e visões com estado reduzem significativamente a carga cognitiva das operações avançadas do Git.

Curva de aprendizado do Git e modelos mentais

  • Alguns insistem que entender o modelo de dados interno do Git (por meio de docs/livros) faz tudo “clicar” e que muitas reclamações decorrem de não ter investido esse tempo.
  • Outros respondem que a confusão generalizada indica problemas reais de UX, independentemente da simplicidade teórica.