When working in Git, the need will arise from time to time to undo, or revert a particular commit, or a set of commits.
Why would you want to revert a commit in Git? Let’s say a commit introduces a problem in your repository’s codebase; the ability to undo a Git commit can save the day with the git revert command.
To undo a commit using the terminal, you will use the git revert command in this fashion:
git revert <commit>
The value of <commit> can be anything that meets the criteria of a gitrevision, as defined by Git.
Commonly, gitrevisions are part of the commit sha; you will need to include enough of the sha to identify the commit as unique among that repository.
git revert 45111a
Other common gitrevisions are branch names followed by ~, followed by the number of commits behind the head commit your target commit is.
git revert HEAD~2
In this example, the target commit is 2 commits behind the head commit on the currently checked out branch.
git revert master~2
In this example, the target commit is 2 commits behind the head commit on the master branch.
By default, the git revert command will open a prompt to edit your Git commit message. If you don’t wish to change your message, you can skip right over that step by including the --no-edit flag before the gitrevision.
git revert --no-edit 45111a
If you want to revert a set of Git commits, you can add .. between two gitrevisions. The older commit should come first, followed by the newer commit.
git revert HEAD~5..HEAD~2
This will revert these two commits, plus every commit in between them.
If you need to make additional code changes before you undo the Git commit, you will use the -n flag (you can also use --no-commit).
git revert -n 45111a
This will modify your working tree and index without creating a commit, allowing you to make additional changes before you revert the Git commit.
When you revert a Git commit, the new commit is made up of exactly the opposite changes as the target commit you’re reverting; most of the time, you won’t need to make additional code changes.
Sometimes you might need to make an edit, since reverting the commit completely might break something. For example, maybe you want to revert most of the commit but there's a line or two you need to keep.
Even the most diligent of developers run into mistakes from time to time when working with Git repositories. But the process of fixing these mistakes can differ depending on the circumstances of each case. Furthermore, if you aren't careful with how you undo these errors, you could end up losing work.
Let’s imagine you’re an artist. You’ve been hard at work creating what will eventually be a beautiful masterpiece, but as you step back to admire your work, you notice you’ve added the wrong hue of grey to one of your clouds. Mistakes like this can make their way into commit history all the time.
Thankfully, Git offers several tools that allow you to undo mistakes introduced by a commit. As with any other toolbox, it’s important to understand the purpose, advantages, and related risks of every tool before using them.
The philosophy behind Git revert is that we can undo past mistakes with "forward change". In other words, rather than going back in time, we can introduce an "equal but opposite" action to neutralize the effect of our original action.
The git revert command follows this principle: it introduces a new commit to the commit history whose sole purpose is to undo the changes of a targeted commit. Importantly, this means that the existing commit history prior to the newly added "undo" commit, including the original error commit, is preserved.
The most common scenario for reverting a Git commit is that you’ve accidentally committed something and it was merged into a shared branch or repo that your teammates work from; Git revert can be particularly useful when you publish to and work off shared branches.
Another advantage is that the commit you target can be arbitrary; you can target any commit at any point in history. However, because of the freedom you have with targeting any commit, you can more easily introduce a conflict when attempting a Git revert.
While Git revert uses forward change to undo commits, the operation of Git reset is just the opposite.
Git reset is a way to move back in time to a particular commit, and to reset our active position to the chosen commit in a branch's commit history.
However, just as science fiction movies depict, there are all sorts of side effects that can come from altering the course of history. For example, if you travel back to a commit with a reset, all the commits you passed may enter a dangling state where they exist but nothing references them. Furthermore, if you perform a “hard” reset, you can lose local work that wasn't backed up properly.
If you need to make revisions to a commit that is not your last commit, the best solution is to create a new commit by reverting the old commit. As a Git best practice, you should avoid doing anything that will require you to force push, and rewrite history, of your main branch(es).
Now, let’s say you want to undo a Git commit by going back in time, but you don’t want to completely reset history.
Rather than abandoning the commits after the erroneous commit, you want to apply them again and deal with the impacts of your changed history commit by commit.
For those who want a bit more manual control over the history revision process, Git provides the interactive rebase tool. With interactive rebase, you are presented with a list of commits up to a specified point on your branch's history. From this point, you have various options for each commit:
In many cases, you catch your mistake right after you complete a commit. Perhaps you forgot to stage a file in the last commit, or had a typo in the commit message, or even made mistakes in the code, but you have not yet committed anything else on top of it.
If you want to modify the last commit in your history, you have the ability to amend the Git commit with changes. For example, you can amend the previous commit by changing the Git commit message or description, or you can even stage a file you forgot to include.
Similarly, if there is a mistake in your previous commit’s code, you can fix the mistake and even add more changes before you amend it. Git amend is a single-commit undo tool which only affects the last commit in the branch's history.
As with Git reset and Git rebase, amending is a history-rewriting process, or a reverse change, rather than a forward change. Under the hood, Git amend creates a brand new commit and replaces your last commit with the new one. It should therefore receive the same level of caution; once you have pushed a commit into a shared branch, amending that commit and pushing the amended change can result in side effects for all of those working off of that commit.
Compared to how you revert a Git commit in the command line, reverting a commit is simple using the helpful visual context of a Git client, like GitKraken.
To revert a commit, simply right-click on any commit from the central graph and select Revert commit from the context menu.
You will then be asked if you want to immediately commit the changes; from here you can choose to save the reverted commit, or select No to make additional code changes or change the Git commit message.
If you're reverting more than one commit in GitKraken, you will need to revert them one at a time and should do so in order of newest to oldest. This will decrease the chance of introducing a conflict.
Plus, if you need to make additional code changes or change your Git commit message, GitKraken makes it easy and intuitive. Giving you more confidence in your workflow.
Rather than remember complicated commit shas and branch names, you can revert a commit in just two clicks using GitKraken. Do yourself a favor and download the cross-platform GitKraken Git GUI for Windows, Mac, & Linux free today.