Practical guide · Git

Git Undo Commit Explained: Reset, Revert, and Restore Changes

Choose the right way to undo a local commit, reverse shared history safely, restore individual files, or recover a commit after a reset.

Git gives you several ways to undo work, but they do different things. You might have committed too early, forgotten a file, introduced a bug, or pushed a change that teammates already have. Before choosing a command, decide whether you want to move a branch, create a new commit that reverses another, or restore a file.

Inspect your work first

Check which branch you are on, whether you have uncommitted changes, and which commit you intend to undo:

git status
git log --oneline --decorate -5

In a history such as A -> B -> C -> D (HEAD), HEAD points to the current commit D and HEAD~1 refers to its first parent C. Save or commit unrelated work before running commands that change the index or working tree.

Undo the latest local commit and keep changes staged

Use a soft reset when you want to remove the latest commit from the current branch but keep its changes staged:

git reset --soft HEAD~1
git status

This is useful when you forgot a file, want to revise the commit message, or plan to combine the changes into a new commit. The branch moves back one commit; the changes from the removed commit remain in the index, ready to commit again.

Keep changes but unstage them

A mixed reset moves the branch back and leaves the changes in your working tree, but unstages them. Mixed is the default mode, so these commands have the same effect:

git reset --mixed HEAD~1
# or
git reset HEAD~1

You can then review the files and stage only the parts you want with git add.

Discard the latest commit's tracked changes

A hard reset moves the branch, index, and tracked working-tree files to the target commit:

git status
git reset --hard HEAD~1

Destructive: git reset --hard can discard staged changes and uncommitted edits to tracked files. Confirm the branch and status first, and back up work you may need. Untracked files are not removed by reset, but they are not protected by a commit either.

To move back more than one commit, replace HEAD~1 with the appropriate parent, such as HEAD~3. Soft and mixed resets preserve the changes from the commits you move past; a hard reset does not preserve those tracked changes in the working tree.

Undo a commit that has already been shared

If a commit has been pushed or other people may have based work on it, prefer git revert. Revert records a new commit that applies the inverse of the selected commit, preserving the existing history:

git revert <commit-hash>

For the latest commit, git revert HEAD is a common choice. Resolve any conflicts Git reports, review the result, and complete the revert. Reverting a merge commit requires choosing a mainline parent; check the command's help and your branch history before doing that.

Restore or unstage an individual file

Use git restore when you want to change a path without moving the branch:

# Unstage a file while keeping its working-tree edits
git restore --staged -- path/to/file

# Discard unstaged edits to a file, restoring it from the index
git restore --worktree -- path/to/file

# Restore a file from a commit into both the index and working tree
git restore --source=<commit-hash> --staged --worktree -- path/to/file

The second command discards that file's unstaged edits, so inspect or back them up first. The -- separates options from the path and is helpful when a filename could be mistaken for an option.

Recover a commit after a reset

If a commit seems to have disappeared after a reset, inspect the reflog, which records recent local movements of references such as HEAD:

git reflog

Find the commit hash from before the reset, then preserve it on a new branch before changing your current branch again:

git branch recovery-before-reset <commit-hash>
git show --stat recovery-before-reset

Review the recovered commit and its files before deciding what to do next. Reflog entries are local and can expire; they are not a substitute for a backup. A reflog can help recover commits, but it does not generally restore uncommitted edits that were never recorded in Git.

Common situations

Fix the latest commit message or add a forgotten file

For a local commit that has not been shared, a soft reset keeps its changes staged so you can create a corrected commit. For a message-only correction, git commit --amend is often more direct. Avoid amending a commit that teammates already use unless your team has agreed to rewrite that shared history.

Remove a bad commit from a shared branch

Use git revert <commit-hash> to create a compensating commit. Avoid resetting a shared branch and force-pushing over teammates' history; coordinate with the team if history has to be rewritten.

Undo only one file

Use git restore with the appropriate source and target. This keeps unrelated files and commits untouched.

Quick reference

Rule of thumb: reset local, unpublished history when you want to move the branch; revert shared commits when you want to preserve history; restore paths when you only need to change files. Check git status before destructive commands.