Como fazer commit de parte de um arquivo no Git

Dividir mudanças em commits pequenos e focados no Git é elogiado como vital para depuração, revisão de código e rollbacks seguros, mas muitos desenvolvedores acabam fazendo squash de PRs inteiros ou agrupando edições não relacionadas. Os comentários comparam fluxos que exigem commits atômicos e sempre verdes com aqueles que preferem históricos de um commit por PR, e debatem os méritos de ferramentas de linha de comando como `git add -p` versus GUIs e integrações de IDE (VS Code, JetBrains, Magit, lazygit etc.) para stage de partes de arquivos. No geral, a conversa destaca que dominar commits parciais e moldar o histórico com cuidado é uma habilidade central, porém frequentemente negligenciada, no desenvolvimento profissional de software.

Granularidade dos commits e valor de um bom histórico

  • Muitos argumentam que dividir mudanças em commits pequenos e coerentes é subestimado e muito útil, especialmente para depuração e reversão de incidentes.
  • Outros observam que, na prática, algumas equipes raramente revertem commits específicos; em vez disso, fazem rollback de deploys ou escrevem um novo commit de “fix”.
  • Há um forte sentimento de que elaborar bons commits (e aprender bem Git) é uma habilidade subestimada, ligada a preocupações mais amplas sobre qualidade de software versus produtividade de “só entregar”.

Squash vs commits incrementais, e reversões

  • Um grupo prefere squash-merge por PR:
    • O PR é a unidade de revisão, não cada commit intermediário.
    • Resulta em um histórico linear, fácil de bisectar, sem estados intermediários quebrados.
    • Squashes ajudam a remover commits ruidosos como “corrigir typo / agora funciona” e reescrever uma única boa mensagem.
  • O grupo oposto prefere commits atômicos, sem squash:
    • Cada commit deve compilar e passar nos testes, facilitando bisect e reversões granulares.
    • Squash pode perder contexto importante (por exemplo, movimentações de arquivos e refatorações) e dificulta a caça a bugs sérios.
  • Alguns apontam que, se o squash resulta em blocos ilegíveis, o PR provavelmente é grande demais ou mistura assuntos.
  • Tópico separado sobre estratégias de merge:
    • Alguns recomendam usar rebase em branches de feature, mas commits de merge na branch principal, obtendo tanto commits agrupados de PR quanto histórico linear por commit (--first-parent vs --no-merges).
    • Outros simplesmente voltam para a última versão boa em vez de caçar commits ruins individuais.

Ferramentas e fluxos de trabalho para commits parciais

  • Forte divisão entre CLI e GUI/TUI:
    • Fãs da CLI: git add -p/--patch, além de ferramentas relacionadas em git reset e git checkout; elogiados por serem rápidos, onipresentes e bons para forçar uma revisão cuidadosa. Opções como “split” e “edit” permitem staging detalhado, incluindo edições de uma única linha.
    • Críticos: consideram a UI interativa do git add -p confusa, pobre em contexto e inferior à seleção por linha em GUIs.
  • Alternativas populares mencionadas:
    • TUI/CLI: lazygit, tig, stgit, git gui, git-cola, git-crecord, magit (Emacs), vim-fugitive.
    • IDE/GUI: VS Code (“stage selected ranges”, mas com bugs antigos de CRLF), changelists do JetBrains, GitHub Desktop, SourceTree, Sublime Merge.
  • Vários observam que o staging parcial é fácil e ergonômico em IDEs modernas, e que ferramentas diferentes combinam com fluxos de trabalho diferentes.

Tensão mais ampla entre qualidade e velocidade

  • Alguns argumentam que “ser produtivo” muitas vezes significa entregar rapidamente à custa da qualidade do código e do histórico.
  • Outros enfatizam o custo de longo prazo de protocolos e código “ruins”, que se tornam difíceis de substituir depois de amplamente adotados.