Como Reverter Múltiplos Commits no GIT

Recorrentemente, o desenvolvedor de software necessita retroceder vários commits a fim de voltar seu código para uma versão estável. Um exemplo disso é quando temos um fluxo de trabalho onde um repositório GIT tem suas branches associadas à ambientes de implantação através de pipelines DevOps, tal como o exemplo da Figura 1, a seguir:

Figura 1: Exemplo de GIT Flow com pipeline típico.

Para que uma versão “suba” para homologação, seria necessário que se fizesse um merge request da branch “feature-new-func” em “develop” e, por sua vez, de “develop” em “master”. Enquanto o ambiente de homologação está em uma dada versão, associada a um commit específico, é possível que a branch “develop” fique bem mais atualizada conforme as atividades de desenvolvimento ocorrem, conforme mostra a Figura 2:

Figura 2: Exemplo de diferenças de histórico entre as branches citadas no exemplo anterior.

Como fazer então para que, caso necessitemos ter em “develop” a versão estável do commit A novamente, possamos reverter sem quebrar o fluxo e perder o histórico?

Encontrei a solução recentemente, ao passar por esse problema no meu trabalho, no Stack Overflow, onde o autor da resposta dá os créditos da abordagem a Jeff Ferland e Charles Bailey. Ela pode ser resumida assim:

$ git reset --hard A # A é o commit alvo
$ git reset --soft D # D é o commit mais recente
$ git commit -am "Rollback to commit A"

Basicamente, o git reset –hard destrói todas as mudanças que aconteceram após o commit A, voltando para ele. Em seguida, o git reset –soft “voltará” para o commit D, o mais atual, mais as mudanças necessárias para que se chegasse ao commit A. O resultado será um novo commit idêntico ao commit que se quer reverter, preservando-se o histórico. Observe que se você por o código do alvo na mensagem do novo commit, o ambiente de GIT poderá criar um link para que você possa saber a que commit ele reverteu para.

Se chamarmos o código do commit resultante de A’ e utilizarmos o seguinte comando:

$ git diff A A'

Verificaremos que não obtivemos saída, ou seja, apesar de commits diferentes, eles são idênticos.

Espero que a dica de hoje seja útil nos reverts do dia a dia.

Deixe uma resposta