Não apenas os desenvolvedores novatos, mas também os profissionais fervorosos precisam desfazer todas as alterações. E então, a primeira coisa que vem à mente é o comando git revert, como o caminho mais seguro. E há armadilhas sobre as quais quero falar.
Vejamos uma situação simples: um desenvolvedor decide implementar funções matemáticas. Mas no meio do caminho, ele percebe que seria bom decompor essa tarefa, digamos, em duas subtarefas:
- Implementar operações aritméticas (adição, subtração, divisão, etc.)
- Implementar operações numéricas (valor máximo, valor mínimo, módulo de um número, etc.)
Será mais fácil verificar e testar. Mas ele já começou a implementar, os commits já foram criados, e o que fazer? Não reescreva o mesmo!

Considere uma árvore de commits. Vemos que nosso desenvolvedor criou um branch functions, a classe Aritmética , que é responsável pela implementação das operações aritméticas (commit A ), e a classe Numérica , que é responsável pela implementação das operações numéricas (commit N ). No total, são duas classes e dois commits.

git revert
, , functions numerical arithmetic. . git revert N arithmetic git revert A numerical. !

— .

? Arithmetic, Numerical!
, git revert . 4 :
A ⟶ N ⟶ revert A ⟶ revert N
revert .
git reset
, reset, revert . … . , .
git rebase
— git rebase .
numerical arithmetic
git rebase -i –root
, pick drop. . numerical:

.
master .

Este método só funciona se você trabalhar em um branch privado, mas se essas manipulações forem feitas em um branch compartilhado, ao publicar ( git push), gitele informa que o branch está desatualizado, já que não há commits nele e cancela a publicação.
Para não ter dificuldades com o git, tente decompor as tarefas com antecedência, caso contrário, você pode se surpreender. Você já se deparou com essas situações e, em caso afirmativo, como saiu delas?