Como reverter um commit do Git sem perder alterações

GitBeginner
Pratique Agora

Introdução

Git é um poderoso sistema de controle de versão que permite aos desenvolvedores gerenciar seu código-fonte de forma eficaz. Uma tarefa comum é desfazer alterações. Enquanto comandos como git reset podem alterar o histórico de commits, git revert oferece uma maneira mais segura e não destrutiva de desfazer commits, especialmente em projetos colaborativos. Este laboratório irá guiá-lo através do uso de git revert para desfazer um commit e como usar suas opções para preservar suas alterações para modificações futuras.

Inspecionando o Histórico de Commits

Antes de fazermos quaisquer alterações, é essencial entender o estado atual do nosso projeto. O ambiente de laboratório foi pré-configurado com um repositório Git contendo um arquivo chamado story.txt e alguns commits. Vamos inspecionar o histórico de commits.

Primeiro, use o comando git log com a opção --oneline para obter uma visualização compacta do histórico de commits. Este comando lista cada commit em uma única linha, mostrando o hash do commit e a mensagem do commit.

git log --oneline

Você deverá ver uma saída semelhante a esta. Observe que seus hashes de commit serão diferentes:

c7a3e69 (HEAD -> master) Add a second, unwanted line
a9b2d5f Add the first line to the story
f3e1c8a Initial commit: Add story.txt

Este log mostra três commits. O commit mais recente, no topo, tem a mensagem "Add a second, unwanted line". Vamos fingir que este commit introduziu um erro que precisamos desfazer.

Vamos também visualizar o conteúdo atual do arquivo story.txt:

cat story.txt

A saída será:

Once upon a time, in a land of code.
The hero of our story was a brave developer.
Suddenly, a wild bug appeared!

Nosso objetivo é remover a última linha, "Suddenly, a wild bug appeared!", que foi adicionada em nosso commit mais recente.

Usando git revert para um Desfazer Seguro

O comando git revert é usado para criar um novo commit que desfaz as alterações de um commit anterior. Este é um método seguro para desfazer alterações porque não altera o histórico do projeto.

Primeiro, copie o hash do commit que você deseja reverter. Da saída da etapa anterior, este é o commit com a mensagem "Add a second, unwanted line".

Agora, execute o comando git revert com esse hash.

Por favor, substitua <your-commit-hash> pelo hash real do seu terminal.

git revert <your-commit-hash>

Após executar este comando, o Git abrirá seu editor de texto padrão (nano) para permitir que você edite a mensagem do commit para este novo commit de reversão. A mensagem padrão geralmente é suficiente.

Para salvar e sair do nano:

  1. Pressione Ctrl+O (Write Out) e depois Enter para confirmar o nome do arquivo.
  2. Pressione Ctrl+X para sair.

Agora, vamos verificar o histórico de commits novamente:

git log --oneline

Você verá um novo commit no topo:

e0d5f1b (HEAD -> master) Revert "Add a second, unwanted line"
c7a3e69 Add a second, unwanted line
a9b2d5f Add the first line to the story
f3e1c8a Initial commit: Add story.txt

Observe que o commit original "indesejado" ainda está no histórico, mas um novo commit de "Reversão" foi adicionado. Este novo commit reverte as alterações feitas pelo commit indesejado.

Finalmente, verifique o conteúdo de story.txt para confirmar que a alteração foi desfeita:

cat story.txt

A saída agora deve ser:

Once upon a time, in a land of code.
The hero of our story was a brave developer.

A linha indesejada foi removida com sucesso.

Revertendo Mantendo Alterações com --no-commit

Às vezes, você deseja desfazer as alterações de um commit, mas mantê-las em seu diretório de trabalho para modificá-las. Por exemplo, você pode querer corrigir um erro no commit em vez de descartá-lo completamente. A opção --no-commit (ou -n) é perfeita para isso.

Primeiro, vamos redefinir nosso repositório para o estado anterior ao nosso último revert, para que possamos tentar uma abordagem diferente. Usaremos git reset para isso. Este comando move o ponteiro HEAD e --hard atualiza os arquivos em seu diretório de trabalho para corresponder.

git reset --hard HEAD~1

Este comando remove o commit de "Reversão" que acabamos de fazer. Você pode confirmar isso executando git log --oneline.

Agora, vamos reverter o commit "indesejado" novamente, mas desta vez usando a opção --no-commit. Lembre-se de usar o hash do commit "Add a second, unwanted line".

Por favor, substitua <your-commit-hash> pelo hash real do seu terminal.

git revert --no-commit <your-commit-hash>

Desta vez, nenhum editor aparece. A reversão é preparada, mas não commitada. Verifique o status do seu repositório:

git status

A saída mostrará que story.txt está preparado para commit:

On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	modified:   story.txt

As alterações do commit revertido agora estão na sua área de staging. Você pode modificá-las agora. Vamos substituir a linha indesejada por uma melhor. Abra story.txt com nano:

nano story.txt

O arquivo ficará como estava após a reversão na Etapa 2. Adicione uma nova linha, melhor, ao final do arquivo:

And they lived happily ever after.

Salve e saia do nano (Ctrl+O, Enter, Ctrl+X).

Agora, adicione suas alterações à área de staging e faça o commit delas com uma nova mensagem descritiva:

git add story.txt
git commit -m "Replace unwanted line with a proper conclusion"

Finalmente, verifique o log e o conteúdo do arquivo para ver o resultado:

git log --oneline
cat story.txt

O log mostra seu novo commit, e story.txt tem o conteúdo corrigido. Você reverteu com sucesso um commit, preservando e modificando suas alterações.

Resumo

Neste laboratório, você aprendeu como reverter com segurança um commit do Git sem perder seu trabalho. Você praticou a inspeção do histórico de commits com git log, a execução de um git revert padrão para criar um novo commit que desfaz alterações anteriores e o uso da opção git revert --no-commit para reverter alterações para sua área de staging, permitindo que você as modifique antes de criar um novo commit. Essas técnicas são essenciais para gerenciar o histórico do seu projeto de forma limpa e segura, especialmente em um ambiente de equipe.