When managing code with Git, accidentally committing incorrect content is a common occurrence. For example, committing passwords, files with sensitive information, or code that hasn’t been completed yet. In such cases, mastering version rollback methods becomes crucial. This article will explain how to undo erroneous commits and recover accidentally deleted code through simple language and scenario-based examples.

一、Why Version Rollback?

Suppose you just executed git commit -m "Quick commit" but realize the commit includes unintended files (e.g., local test configuration files) or you committed incomplete code. In this situation, you need to:
- Undo the erroneous commit to prevent sensitive information leakage
- Restore to the previously correct code state
- Recommit the correct changes if necessary

二、Git Basics: Key Concepts

Before rolling back, familiarize yourself with these essential concepts to avoid mistakes:
- commit: A version snapshot of each commit, acting like a “time marker.” Each commit has a unique hash (e.g., a1b2c3d).
- HEAD: Points to the latest commit of the current branch, representing the current version.
- Working Directory: Files modified locally (e.g., files not yet staged with git add).
- Staging Area: Files prepared for commit after git add is executed.
- Remote Repository: A repository hosted on platforms like GitHub or GitLab, where code is synchronized during collaborative development.

三、Scenario 1: Erroneous Commit Not Pushed to Remote

If the incorrect commit exists only locally (not yet pushed to the remote repository), use git reset to undo it. reset has three parameters, ranging from “mild” to “risky”:

1. Mildest: Preserve Changes (–soft)

If you only need to undo the commit while preserving working directory and staging area changes (e.g., the commit message was incorrect but the code logic is sound):

# View recent commits to identify the hash of the previous valid version (HEAD~1)
git log --oneline  

# Undo the most recent commit while preserving changes
git reset --soft HEAD~1  

# Recommit the correct changes
git add .  # Re-stage modified files
git commit -m "Correct commit message"  # Commit the corrected changes

Effect: The erroneous commit is removed, but working directory and staging area remain intact for re-submission.

2. Most Thorough: Discard Changes (–hard)

If the commit includes unwanted files (e.g., temporary test files) and you confirm these changes can be discarded, use --hard (WARNING: This operation is irreversible! Proceed with extreme caution):

# Undo the most recent commit and discard all changes (DANGER!)
git reset --hard HEAD~1  

# If you regret this action, recover using the following method:

Risk Warning: --hard directly deletes the commit and discards all changes in the working directory and staging area. If not backed up, use git reflog to recover (see Scenario 5).

四、Scenario 2: Erroneous Commit Already Pushed to Remote

If the incorrect commit has been pushed to the remote repository (e.g., GitHub), directly using git reset --hard will disrupt team collaboration (others’ code will conflict). Instead, use git revert to create a new commit that undoes the previous one, ensuring remote repository consistency and no impact on other collaborators.

Undo the Most Recent Pushed Commit:

# 1. View the commit hash of the erroneous commit (e.g., the most recent one)
git log --oneline  

# 2. Undo the most recent commit by creating a new "revert" commit
git revert HEAD  

# 3. Push the new revert commit to the remote repository
git push origin <branch-name>  # e.g., git push origin main

Effect: The remote repository will add a new commit like Revert "Erroneous Commit", and all team members will see this revert without losing intermediate code.

Undo a Specific Commit (e.g., an older error):

If the erroneous commit is not the most recent (e.g., the 3rd commit), specify its hash to revert:

# 1. View all commit hashes to identify the erroneous commit (e.g., a1b2c3d)
git log --oneline  

# 2. Revert the specified commit by creating a new commit
git revert a1b2c3d  

# 3. Push the revert to the remote repository
git push origin <branch-name>  

五、Scenario 3: Recover Accidentally Deleted Code (reflog Saves the Day)

If you used git reset --hard HEAD~1 and regret it, or accidentally lost changes, use git reflog to recover. reflog records all local operations, including commits reset to history.

# 1. View all operation logs to find the commit hash to recover
git reflog  

# 2. Restore to the desired commit (e.g., hash a1b2c3d)
git reset --hard a1b2c3d  

# 3. Ensure alignment with the latest remote state
git reset --hard HEAD  

六、Summary of Key Notes

  1. Prioritize reset for unpushed commits:
    - --soft: Safest (retains changes, only undoes the commit)
    - --hard: Risky (permanently discards changes, use only if confirmed unnecessary)
  2. Must use revert for pushed commits:
    - Avoid disrupting remote history; “create a new revert commit” instead
  3. Recover lost code:
    - Use git reflog to list all operations, then restore via commit hash
  4. Taboo in collaborative environments:
    - Never execute git reset --hard on public branches to prevent conflicts

七、Quick Reference Table

Scenario Recommended Command Key Point
Unpushed, preserve changes git reset --soft HEAD~1 Undo commit without losing changes
Unpushed, discard changes git reset --hard HEAD~1 Danger! Permanently deletes changes
Pushed, undo most recent commit git revert HEAD && git push Create new commit for safe remote sync
Recover lost code git refloggit reset --hard <hash> Restore from operation history

By following these methods, you can handle 90% of Git version rollback scenarios. Remember: Always verify commit hashes with git log before acting. Prefer --soft or revert over --hard when uncertain; safety first!

Xiaoye