Git
How to Revert to a Previous Commit in Git?
Git is a powerful version control system widely used by developers to track changes in code and collaborate with teams. One of the most valuable features Git offers is the ability to revert or go back to a previous commit.
Whether you’ve made an error, need to review old code, or wish to experiment with different changes, knowing how to navigate through Git history is essential.
In this blog, we’ll walk you through several ways to go back to a previous commit in Git, explaining the pros and cons of each method.
1. Using git checkout
(Deprecated for Branching)
Previously, git checkout
was the go-to command for switching between commits. It allowed developers to check out a specific commit in a detached HEAD state. However, this approach has since been replaced with more specialized commands, as git checkout
now has multiple uses, including switching branches.
Example:
git checkout <commit-hash>
This command checks out a specific commit, but your working directory will be in a detached HEAD state. This means you are not on any branch, and any changes you make won’t be associated with a branch until you create one.
When to Use:
- If you need to examine the contents of a previous commit without making permanent changes.
- For temporary changes or viewing the state of your repository as of a past commit.
Caveat:
- Once you make changes in this state and switch back to another branch, those changes may be lost unless committed to a new branch.
2. Using git reset
The git reset
command is one of the most commonly used tools for going back to a previous commit. It resets the current HEAD to a specified state, and depending on the options used, it can also affect your working directory and staging area. There are three types of resets you can perform: soft, mixed, and hard.
Soft Reset
A soft reset keeps your working directory and staging area intact. It simply moves the HEAD pointer to the previous commit.
git reset --soft <commit-hash>
Mixed Reset (Default)
A mixed reset moves the HEAD to a previous commit, and it also un-stages the changes made since that commit. Your working directory remains unchanged.
git reset --mixed <commit-hash>
Hard Reset
A hard reset moves the HEAD and updates the working directory to match the state of the specified commit, discarding any local changes. Be cautious, as this will delete uncommitted changes.
git reset --hard <commit-hash>
When to Use:
- Soft reset: If you want to go back to a commit but keep your current changes staged.
- Mixed reset: If you want to unstage your changes but keep them in your working directory.
- Hard reset: If you need to completely discard changes and align with a previous commit, making your working directory identical to that commit.
Caveat:
git reset --hard
is destructive as it deletes changes from your working directory, so use it carefully.
3. Using git revert
Unlike git reset
, which rewrites history, git revert
creates a new commit that undoes the changes made by a previous commit. This is useful when working on a shared repository, as it maintains the history without rewriting commit history.
Example:
git revert <commit-hash>
This command will undo the changes introduced by the specified commit, creating a new commit that effectively cancels out the changes. If the commit you want to revert was merged, Git will attempt to create a reverse merge commit.
When to Use:
- If you want to undo a commit without altering the commit history (useful for public/shared branches).
- To safely revert a commit in a collaborative project.
Caveat:
git revert
doesn’t remove the commit from the history but rather adds a new one that undoes its changes.
4. Using git reflog
Git keeps a log of all the changes to the HEAD and references, known as the reflog. If you’ve accidentally lost some commits, git reflog
is a useful tool for tracking down recent changes to the branch and returning to a previous state.
Example:
git reflog
The git reflog
command will show you a history of where your HEAD and branch references have been. You can then use the commit hash from the reflog output to check out or reset to the desired commit.
git reset --hard <reflog-commit-hash>
When to Use:
- If you have lost commits (e.g., after a bad reset or branch switch) and need to recover them.
Caveat:
- The reflog is local and might expire depending on your Git configuration.
5. Using git switch
(for Simplicity)
Git introduced git switch
as a more intuitive way to handle branch switching and commit checkout. Although it is specifically for switching branches, it can also be used in combination with git reset
to revert to previous commits while staying on a branch.
Example:
git switch --detach <commit-hash>
This will detach HEAD at the specified commit. You can then either make changes and commit them, or switch back to a branch.
When to Use:
- If you want a clearer distinction between switching branches and checking out commits.
Caveat:
- Works only for temporarily viewing the state of a commit without altering branch history.
Conclusion
Choosing the right method to go back to a previous commit in Git depends on your goals and how you want to manage your commit history. Here’s a quick summary:
git checkout
(detached HEAD): For temporary exploration of past commits.git reset
: To move back to a commit and modify the staging area or working directory.git revert
: To undo a commit and add a new commit that reverses the change.git reflog
: For recovering lost commits and references.git switch
: For safer commit and branch management.
By mastering these Git commands, you can confidently navigate your repository history, correct mistakes, and experiment without fear of permanently losing progress.