How to Revert to a Previous Commit in Git without Modifying History


What is a safe way to rollback to a previous state in our Git repository without destroying or altering the history?

Revert using git revert --no-commit

Suppose we want to revert back to a commit with the hash 521dd125.

git revert --no-commit 521dd125..HEAD
git commit -m "revert all in one"

This will revert everything from the HEAD back to the commit hash. We are restoring the state of the repository to that of the commit with hash 521dd125 by creating one single commit that is “undoing” all the changes in this commit tree.

The --no-commit flag allows us to revert all the commits in this tree at once. Without it, we’ll create commits for every commit we want to revert.

Error: no -m option was given

We might end up with an error like this:

fatal: Commit <SHA1> is a merge but no -m option was given.

We might get this error because we are trying to revert a merge commit.

When resetting or reverting a commit, it will try to figure out what changed in that commit by comparing it to its parent commit. However, in a merge commit, there will be multiple parent commits.

If this is the case, we have to specify which parent of the merge to revert to using the -m flag followed by an ordinal number representing where the parent commit ID resides in the merge commit.

git revert --no-commit 521dd125..HEAD -m 1

Decide the -m flag with git cat-file

We can use cat-file to display the parent branches in order and determine which parent to choose.

git cat-file -p merge_commit_id

The first one listed would be -m 1, the second would be -m 2, and so on.

Decide the -m flag with git log

We can also use git log to search for the merge commit.

commit 121d31d2a4da5d315da2345d35d435d2345dad2
Merge: da12195 1a87d98
Author: Author <author@example.com>
Date:   Date
    Merge branch 'feature' into 'develop'

In this case, da12195 would be -m 1 and 1a87d98 would be -m 2.

In most cases, we want to use -m 1, but this may not be true all the time.