Skip to main content

Undoing Changes

  • git reset HEAD <file> → Unstage a file
  • git reset --hard → Reset to last commit (discard all changes)
  • git revert <commit> → Create a new commit that undoes changes

git reset

git reset [options] [<commit>]
git reset [<commit>] -- <pathspec>...
# Unstage files (keep changes):
git reset         # default --mixed
git reset <file>  # unstage a specific file
# Unstages changes while preserving modifications in your working directory.

# Rewrite the last commit (keep staged):
git reset --soft HEAD~1
# Moves HEAD back one commit; your changes remain staged to recommit differently.

# Discard local changes:
git reset --hard
git reset --hard <commit>
# Resets index and working directory to match the target; all local changes are lost.

# Reset specific paths to HEAD:
git reset -- path/to/file
# Restores the index entry for that path to the last commit’s version (HEAD) without moving HEAD.
  • Description: Moves the current branch (HEAD) to a specified commit and optionally updates the staging area (index) and working directory.
  • Usage: It move HEAD backward to an earlier commit, reset files from the staging area back to the working directory, reset both index and working directory to match a commit.
  • Think Tank: Reset options to work with:
Option Description
--soft Reset only HEAD to the target commit
--mixed Reset HEAD and index (default)
--hard Reset HEAD, index, and working directory
--merge Keep non-conflicting local changes when resetting
--keep Reset only if working tree content can be preserved

How it works: HEAD, index, and working directory:

  • Three areas: Git tracks state in the commit tree (HEAD), the staging index, and the working directory. git resetmanipulates one or more of these depending on the mode you choose.
  • Core idea: Choose a target commit, then decide whether to update only HEAD, HEAD+index, or HEAD+index+working directory.
  • Best Practices:
    • Always write clear, descriptive commit messages
    • Stage only relevant changes to keep commits focused
    • Use --amend for quick fixes before pushing, but avoid rewriting public history
    • Sign commits for security in collaborative projects
    • Follow team conventions (e.g., Conventional Commits, semantic messages)
Git - git-reset Documentation

git revert

git revert [--no-edit | --edit] [-n] [-m <parent-number>] [-s] [-S[<keyid>]] <commit>...
git revert (--continue | --skip | --abort | --quit)
# Revert a single commit by hash:
git revert <commit>

# Revert the latest commit (HEAD):
git revert HEAD

# Revert multiple commits (one after another):
git revert <commit1> <commit2> <commit3>

# Stage changes but don’t commit (accumulate reverts):
git revert -n <commit>

# resolve if needed, then later:
git commit -m "Revert <commit> and batch changes"

# Continue/abort during conflicts:
git revert --continue
git revert --abort
git revert --quit
  • Description: The git revert safely undoes past commits by creating new commits that apply inverse changes. 
  • Usage: It creates a new commit that undoes the changes introduced by a specified earlier commit (or commits) without rewriting history. It’s the “safe undo” for shared repositories.
  • Think Tank: Reset options to work with:
Option Description
--no-edit Use the default generated revert message without opening the editor
--edit Open editor to customize the revert commit message (default behavior)
-n, --no-commit Apply the revert changes to index and working tree without creating a commit
-m  When reverting a merge commit, specify which parent is the “mainline” to keep
-s, --signoff Add a “Signed-off-by” line to the revert commit message
-S[] GPG/SSH-sign the revert commit
--continue Continue a revert after resolving conflicts
--abort Abort the ongoing revert and restore the pre-revert state
--quit Stop the revert process, leaving the index and work tree as-is
  • Best Practices:
    • Verify the target commit: Inspect with git show <commit> to confirm what you’re undoing.
    • Prefer revert on shared branches: Keep history intact and avoid force-pushes.
    • Commit messages: Keep the default “Revert <hash>” context and add a clear reason for traceability.
    • Test after revert: Run builds and tests to ensure the reverse patch doesn’t introduce regressions.
    • Use -n thoughtfully: Batch related reverts to reduce noise and ease review, but avoid hiding unrelated changes in a single commit.

How it works

  • Inverse patch: Git computes the diff introduced by the target commit and applies the inverse of that diff to your working tree and index.
  • New commit: The result is recorded as a new commit that references the original commit in its message, preserving an auditable history.
  • Clean state required: Revert requires a clean working tree (no unstaged or staged changes) before starting; otherwise it will refuse to run.
  • Conflicts possible: If the inverse patch overlaps with newer changes, Git stops and asks you to resolve conflicts, then continue.

Advanced Workflows:

Reverting merge commits

  • Mainline parent selection: A merge commit has multiple parents; to revert it, you must choose which parent’s history you’re keeping with -m <parent-number>. Without -m, Git will refuse to revert a merge commit.
  • Conflict likelihood: Reverting merges is more prone to conflicts; resolve them and run git revert --continue.

Reverting a range of commits

  • Order matters: Reverting multiple commits applies them in the order you specify; ensure the sequence makes sense to minimize conflicts.
  • Batch reverts: Use -n across several commits, review the combined changes, then commit once.

Reverting an already reverted change

  • Double revert: Reverting a revert re-applies the original change. This is a common technique to “bring back” a change that was previously undone.

Collaboration and auditing

  • Why revert vs reset: Revert is history-preserving, making it ideal for shared branches where you must not rewrite history. Reset would move branch pointers and can require force-pushing.

Git - git-revert Documentation

Tips, Tricks, Roadmaps, Resources, Networking, Motivation, Guidance, and Cool Stuff ♥

Updated on Dec 23, 2025