POTHIEDU Não Decore a Resposta. Entenda o Caminho

Divisão Da História

Divisão Da História

O problema com branches que nunca são mesclados

A gente vê isso todo dia em repositórios de qualquer tamanho. Alguém cria um branch, trabalha uma feature por três semanas, e aí o branchevaporiza. Ou pior: fica lá, parado, com commits desatualizados em relação ao main. Quando alguém finalmente vai mesclar, o merge é um inferno de conflitos porque o branch já não reflete mais a realidade do código. Dividir a história do git é basicamente o processo de reescrever os commits de um branch para limpar tudo antes de subir um pull request ou mesclar. Não é magia. É só usar rebase interativo e alguns comandos que a maioria dos desenvolvedores conhece de nome mas nunca aplica na prática.

Por que ninguém faz divisão da história direito

O principal obstáculo não é técnico. É cultural. As pessoas têm medo de reescrever história porque foram ensinados que git é imutável. É parcialmente verdade, mas essa regra existe para proteger branches compartilhados, não branches locais. Se ninguém mais está usando o branch, você pode fazer o que quiser com ele. Eu trabalhava num projeto com um repositório que tinha um branch de refactor que ficou dois meses parado. Quando foi submeter, tinha 47 commits misturando refatoração, ajustes de formatação, debugs abandonados e três tentativas diferentes da mesma solução. O code review levou duas sessões de equipe inteiras. Depois a gente aprendeu a pedir squash antes de tudo.

Como fazer na prática

O fluxo básico funciona assim. Você está no branch que quer limpar. Verifica onde estão os commits problemáticos usando log --oneline. Conta quantos commits precisam ser revisitados a partir do ponto de divergência. O número de commits que você vai reescrever determina o parâmetro n do comando. Execute git rebase -i HEAD~n, substituindo n pela quantidade. O editor vai abrir mostrando todos os commits listados de cima para baixo, sendo o mais antigo no topo. Cada linha começa com a palavra pick. É ali que acontece a mágica. Se você quer fundir aquele commit com o anterior, troca pick por squash. O git vai juntar os dois e abrir outro editor pedindo o commit message final. Se o commit é lixo puro, sem valor histórico nenhum, usa drop. Ele simplesmente desaparece da história. Cuidado com drop em commits que têm informação importante mesmo que você não queira manter o commit separado.

Divisão da História: períodos históricos e principais acontecimentos ...
Divisão da História: períodos históricos e principais acontecimentos ...

No caso do branch que citei, eu tinha 47 commits para revisar. A estratégia foi mais simples do que parecia. Primeiro eu selecionava squashes em cadeia para agrupar commits relacionados à mesma funcionalidade. Depois identificava commits de debug que podiam ser drops. No final, o branch que tinha 47 commits ficou com 5 commits limpos, cada um com uma função clara e message descritiva.

Pegadinhas que ninguém conta

Rebase interativo vai te surpreender se você não prestar atenção em dois detalhes. O primeiro é a ordem dos commits na lista. O git mostra do mais antigo para o mais recente. Se você colocar um squash antes de um pick que deveria vir antes, a história fica inconsistente e o rebase falha. Sempre revise a lista antes de salvar. O segundo detalhe é mais perigoso. Se você forçar o push após o rebase em um branch que já foi enviado para o remoto, todo mundo que tiver clonado esse branch vai ter que resolver o conflito manualmente. Isso é válido apenas para branches locais ou branches seus que ninguém mais mexe. Para branches de equipe, o rebase costuma ser proibido por política. Eu já vi um desenvolvedor fazer rebase em um branch compartilhado sem avisar. Três pessoas perderam meio dia de trabalho tentando recuperar commits que sumiram. Desde a gente adotou a regra de nunca reescrever branches que já estão no remoto sem autorização explícita do time.

Dica avançada: amend vs squash

Muita gente confunde git commit --amend com squash. Eles fazem coisas diferentes. Amend modifica o commit mais recente adicionando mudanças do working tree a ele. Squash funde dois commits consecutivos durante um rebase. Use amend quando você esqueceu um arquivo no commit anterior e quer corrigir antes de push. Use squash quando está reescrevendo uma sequência de commits. Uma técnica que economiza bastante tempo é usar fixup em vez de squash quando você não precisa editar a mensagem do commit resultante. O fixup pega o conteúdo do commit mas descarta a mensagem dele, herdando automaticamente a mensagem do commit que está sendo fundido. Útil quando você tem commits como "wip" ou "testando" que só existem para registro temporário.

Divisão da história: o que é, períodos, resumo - Brasil Escola
Divisão da história: o que é, períodos, resumo - Brasil Escola

O que dividir nem sempre é a melhor resposta

Às vezes o problema não é a história do branch mas a própria natureza do que está sendo committado. Se você está com muitos commits bagunçados porque estava testando coisas aleatórias, o rebase resolve a apresentação mas não o processo. Nesse caso, um reset --soft volta para o estado anterior mantendo as mudanças no staging, permitindo recommitar de forma organizada do zero. Outro cenário onde rebase falha é quando os commits têm dependências complexas entre si. Se o commit B depende do commit A e você tentar reorder ou drop o A, o B vai quebrar. O git vai reclamar e parar o rebase. Nesse caso, a solução é voltar com git rebase --abort e pensar na estrutura dos commits antes de tentar de novo. Repositórios grandes com milhares de commits históricos raramente se beneficiam de rebase. O tempo de processamento aumenta exponencialmente e o risco de erro é alto. Nesses casos, é melhor trabalhar com cherrypick seletivo ou simplesmente aceitar a história como está e focar em commits futuros mais organizados.

A divisão da história é uma ferramenta, não um ritual obrigatório. Use quando fizer sentido. Deixe bagunçado quando a pressa for maior que a perfeição. O importante é saber que o controle está nas suas mãos e não na máquina.