If we have already shared our work with other people, then we cannot rewrite its history. Other people may have already built more features or fixed new bugs on top of our code and rewriting the history of the project could break their work. For these situations we use git revert.
Suppose we want to revert the last commit. So we run
git revert HEAD
Git will create a new commit after our HEAD that undoes all changes done in the HEAD commit. The message for this commit will be Revert "original_commit_message".
We can also revert earlier commits with git revert HEAD~n where n refers to the commit n steps prior to HEAD.
We can revert ranges of commits by running, for example
git revert HEAD~3..HEAD
With this, Git will revert all commits from HEAD~2 to HEAD. So, Git will not include the oldest commit. When we revert a range of commits, Git will revert them one by one, starting from HEAD. At each commit, Git will open VS Code and ask us to supply a commit message (or confirm the default one).
Because our last commit is HEAD, we can omit it and run git revert HEAD~3.. and Git will start from the HEAD pointer.
When reverting a range of commits, is better to produce only one revert commit. This will leave us with a cleaner history. To do so, we run
git revert --no-commit HEAD~3..
With this, Git will figure out what changes need to be done, and apply those changes to the staging area. We can review the changes and then run
git revert --continue
Git will open VS Code so that we can write our commit message. If while reviewing the changes we realize that we don't want to go ahead with the revert, we can run
git revert --abort