Git Reverter Commit de Mesclagem: Um Guia Com Exemplos

Podemos comprometer uma aplicação mesclando código problemático, seja por integrar acidentalmente trabalho inacabado no branch principal ou por passar despercebido um bug crítico que escapou aos testes automatizados.

Neste artigo, vou guiá-lo pelo processo de usar git revert para desfazer uma mesclagem de forma segura, garantindo que o histórico de commits permaneça intacto e a integridade do projeto seja preservada.

Como git revert Funciona

Podemos pensar no git revert como o comando de desfazer do Git. No entanto, o comando git revert não exclui commits ou salta para um estado anterior do branch. Em vez disso, ele cria um novo commit que reverte as mudanças de um commit específico.

A sintaxe para reverter um commit com o hash <commit_hash> é:

git revert <commit_hash>

Podemos listar os commits juntamente com seus identificadores de hash usando o comando git log. A saída do git log lista os commits do mais recente ao mais antigo, como segue:

Por exemplo, para reverter o commit que implementa a função de subtração, usariamos o comando:

git revert 7ba24a3e62d4d37182428ccfaa070baa222b1151

Usando git revert podemos desfazer as mudanças de um commit específico sem afetar o histórico de commits.

Note que o git revert não é mágico, e dependendo do histórico de commits, pode resultar em um conflito que precisa ser resolvido manualmente.

Vantagens do git revert Sobre Mudanças Manuais

Por que o git revert é útil se podemos precisar resolver um conflito manualmente? Não seria mais fácil apenas desfazer as mudanças manualmente? Vamos ver suas vantagens:

  • Preserva o histórico: o git revert cria um novo commit que desfaz as mudanças de um commit específico, enquanto preserva todo o histórico de commits. Isso ajuda a manter um histórico transparente de mudanças e reversões.
  • Reversão atômica: Garante que as reversões são atômicas e consistentes. Quando deletamos e commitamos mudanças manualmente, há um risco de erro humano. 
  • Consciência de conflitos: Assegura que somos alertados por meio de conflitos se há alguma integração ou mudanças dependentes do commit original. Isso pode parecer inconveniente, mas protege contra efeitos colaterais indesejados.
  • Metadados: O novo commit criado pelo git revert inclui metadados e uma mensagem de commit que descreve contextualmente o que foi revertido, ajudando na compreensão futura. Sem o git revert, esse contexto pode ser perdido.

Reverter uma Mesclagem em Diferentes Cenários

Nesta seção, aprendemos como desfazer uma mesclagem. Por exemplo, estamos假设 que estamos mesclando um branch chamado feature no branch main executando o comando do branch main:

git merge feature

O que aprendemos aqui pode ser aplicado a qualquer dois branches, substituindo os nomes apropriadamente.

Revertendo uma mesclagem que não tem commit associado

O comando git merge nem sempre cria um novo commit. Um commit é criado apenas se o branch main divergiu do branch feature. Como o git revert requer um commit para operar, não podemos usá-lo neste caso.

Os branches main e feature divergem quando novos commits são criados no main que não são ancestrais do branch feature. Em outras palavras, novos commits foram criados no main após a criação do feature.

Se os branches não divergiram, ao executar o comando git merge feature no branch principal, o Git usará o fast-forward para mesclar. Isso significa que ele move o HEAD do branch main para o HEAD do branch feature.

Podemos observar que isso aconteceu olhando para o resultado do git merge:

Para desfazer essa mesclagem, precisamos apenas mover o HEAD do branch main de volta para onde estava. Para isso, nós:

  1. Identificamos o HEAD anterior usando o git reflog
  2. Reverta o HEAD para o anterior usando git reset --hard <previous_head>, substituindo <previous_head> pelo HEAD anterior.

A saída do git reflog será algo como isto:

Podemos identificar o HEAD anterior olhando para a linha que diz “checkout: moving from feature to main” (escreve feature e main porque esses são os nomes dos nossos branches). 

Neste caso, o HEAD anterior é fe59838. Para mover o HEAD do branch main de volta a ele e desfazer a fusão, usamos o comando:

git reset --hard fe59838

Revertendo uma fusão que tem um commit associado

Se o branch main e o branch feature se separaram, então quando mesclamos dois branches, um novo commit é criado, chamado commit de fusão. 

O commit de fusão aplica as mudanças de um branch para o outro. Neste caso, as mudanças no feature são aplicadas ao branch main.

Para reverter as mudanças no branch main, usamos o git revert no commit de fusão. Isso criará um novo commit que desfaça as mudanças trazidas para o branch main com a fusão, eficazmente restaurando o estado do branch main para o que era antes da fusão.

Primeiro, precisamos identificar o hash do commit de mesclagem. Podemos fazer isso usando o comando git log:

Porque o commit de mesclagem tem dois pais, a sintaxe do git revert é ligeiramente diferente. Precisamos usar a opção -m 1 para especificar que queremos reverter as mudanças em relação ao branch main:

git revert -m 1 b8dab2c8611e324ed0d273133987415350e6d10d

Resolução de Conflitos Ao Reverter um Commit

Algumas vezes, podem surgir conflitos ao reverter um commit, especialmente se o commit a ser revertido conflita com mudanças posteriores no código. Nestes casos:

  1. Git pausará a reversão: Precisamos resolver manualmente os conflitos. Git marcará os arquivos em conflito e exigirá intervenção.
  2. Resolver os conflitos: Abrimos cada arquivo em conflito, resolvemos os conflitos marcados pelo Git e salvamos as mudanças.
  3. Adicionar os arquivos resolvidos ao índice: git add <caminho-do-arquivo>
  4. Continuar a reversão: git revert --continue

Conclusão

Usar git revert para desfazer commits de mesclagem garante que todas as mudanças e correções sejam documentadas dentro do histórico de commits.

Além disso, entender os cenários apropriados para aplicar git reset versus git revert nos permite tomar melhores decisões, especialmente quando consideramos workflows colaborativos ou mudanças apenas locais.

Você pode ler mais sobre este tópico na seção de FAQ abaixo. Se você quiser aprender mais sobre Git, recomendo esses recursos:

Source:
https://www.datacamp.com/tutorial/git-revert-merge