In any programming project, you're faced with two primary commands to undo a commit: git revert and git reset. Making a mistake, like pushing a bug or forgetting a file, is a common problem for everyone, from seasoned developers to those just learning how to start coding.
Using the wrong command to fix it, especially on a shared branch, can disrupt your entire team's workflow and create significant merge conflicts. This guide explains exactly which command to use for which scenario, with clear, practical examples.
Quick Comparison: Git Revert vs. Git Reset
Here is the fundamental difference you need to know before choosing a command.
| Feature | git revert (Safe Way) | git reset (Powerful / Risky Way) |
|---|---|---|
| How it Works | Creates a new commit that undoes the changes from a previous commit. | Moves the branch pointer, effectively erasing commits. |
| Project History | Preserved and chronological. A new revert commit is added to the log. | Altered and rewritten. Commits can be permanently lost. |
| Best Use Case | Undoing commits on public/shared branches (e.g., main, develop). | Cleaning up local-only commits (not yet pushed). |
| Risk Level | Low. Safe for all collaboration. | High. Dangerous on shared branches. |
Method 1: git revert (The Safe Way: Undoing with History)
git revert is the safest way to undo changes because it does not rewrite the commit history. Instead, it creates a new commit that applies the inverse (opposite) changes of the commit you want to undo.
When Should You Use git revert?
You should always use git revert in these scenarios:
- Shared Branches: When the commit you want to undo has already been pushed to a public or shared branch (like
mainordevelop) where other developers have access to it. - Maintaining History: When you need a clear and transparent project history that shows exactly when a change was made and when it was undone.
How to Use git revert Step-by-Step
- Find the Commit Hash: First, find the unique ID (hash) of the commit you want to revert.
git log --onelineThis will show a simplified log. Copy the hash (e.g., a1b2c3d) of the commit you need to undo.
- Run the Revert Command:
git revert a1b2c3d(Replace a1b2c3d with your actual commit hash.)
- Edit the Commit Message: This command will open your default text editor (like Vim or Nano) so you can edit the commit message for the new revert commit. The default message is usually fine (e.g., "Revert 'fix: added new feature'").
- Simply save and close the editor to complete the revert. Your project history now has a new commit that undoes the previous one.
\[Expert Tip\] How to Revert a Merge Commit
If you try to revert a merge commit (git revert <merge-hash>), Git will get confused and stop. This is because Git doesn't know which parent side of the merge you want to keep.
You must manually tell Git which parent is the "mainline" using the -m flag.
# This will fail
git revert 4s9f6b1
# This is the correct way
# '-m 1' usually means 'keep the main branch'
git revert -m 1 4s9f6b1Method 2: git reset (The Powerful Way: Rewriting History)
git reset is a powerful and more complex command. It doesn't create a new commit; it moves the HEAD pointer (and the current branch) to a different commit, effectively rewriting your project's history.
This power comes with risk.
Warning: Never usegit reseton a public or shared branch (e.g.,main) that other developers have pulled from. Rewriting shared history will cause severe conflicts and break your team's workflow. This is a destructive operation, similar in risk to how you would carefully manage other repository-level changes, like learning when to delete a Git branch or how to safely rename a branch that others might be using. \\Only usegit reseton your local-only commits that you have not pushed yet.
git reset Modes: --soft vs. --mixed vs. --hard
The behavior of git reset depends on its mode. These modes determine what happens to the files from the commits you are "resetting."
1. git reset --soft
This is the most delicate reset. It moves the HEAD pointer, but it keeps all your changes in the "Staged" area.
- Command:
git reset --soft HEAD~1(Undoes the last 1 commit) - Use Case: You just committed, but you want to undo the commit and immediately re-commit the same files, perhaps with a different message or by adding one more file.
2. git reset --mixed (The Default)
This is the default mode if you don't specify one. It moves the HEAD pointer and keeps your changes in the "Working Directory" (unstaged).
- Command:
git reset HEAD~1 - Use Case: You want to undo the last commit, and you also want to re-evaluate which files to include. The changes are safe in your folder, but you will need to
git addthem again.
3. git reset --hard (The Dangerous One)
This is the most destructive mode. It moves the HEAD pointer and permanently deletes all changes from the undone commits. The files are not in Staged, nor are they in your Working Directory. They are gone.
- Command:
git reset --hard HEAD~1 - Use Case: You are 100% certain you want to destroy the last commit and all the work it contained. There is no undo for this.
Common Undo Scenarios and Their Solutions
Let's put it all together. Here are the most common problems and the exact command to use.
Scenario A: "I just made a commit, I haven't pushed, but I misspelled the message."
Do not use revert or reset for this. The best tool is:
git commit --amendThis lets you edit the message of the most recent commit.
Scenario B: "I just made a local commit, I haven't pushed, but I want to undo it and keep my files to re-work them."
This is the perfect case for a soft or mixed reset.
# Keeps files in Staged area
git reset --soft HEAD~1Scenario C: "I pushed a bad commit to main, and my team already has it."
You must use git revert.
# Find the hash with 'git log'
git revert <bad-commit-hash>
git pushThis creates a new "revert" commit that safely undoes the bad one without rewriting the shared history.
Scenario D: "I made 3 local commits, and they are all a mess. I want to delete them and start over."
This is a local-only problem, so reset is fine.
# WARNING: This destroys the last 3 commits and all their changes.
git reset --hard HEAD~3
Comments (0)
Sign in to comment
Report