Programming and IT
How to undo a commit
The question "how do I undo a commit" actually hides four different ones: fix the last commit, take it back and redo it, erase several, or cancel an old commit in the middle of history. The answer depends above all on one thing — whether anyone besides you has seen that commit.
In this article
First question: has the commit been pushed?#
The answer determines everything else, so start here:
## main...origin/main [ahead 1]
ahead 1 means you have one commit more than the server, and nobody has seen it.
You can rewrite history freely. If there is no such note, the commit has already
gone out — you must not rewrite it, because your teammates will keep the old
version and the next merge will show the changes twice.
Hence a simple rule: fix private commits by rewriting, shared ones with a reverting commit. The methods below are laid out along that line.
Method 1: fix the last commit#
You forgot a file or made a typo in the message — do not remove the commit, extend it:
An editor opens with the previous message — change it or leave it. To change only
the set of files without touching the text, add --no-edit.
It is important to understand what happens: the old commit is not modified; a new one with a different hash is created in its place. For a pushed commit this is the same history rewriting as a rebase, with all the restrictions described in the article on git rebase.
Method 2: take the commit back and keep the work#
The commit was made too early or with the wrong set of files:
## main...origin/main
The commit is gone, the changes are intact and staged — you can regroup them: commit
part now and part later. Without the flag (git reset HEAD~1) the changes stay in
the files but are unstaged.
The --hard flag is not needed in this scenario and is dangerous: it does not just
remove the commit, it erases everything that is not in other commits, including
edits you had not added yet. All three modes are explained in the article on
git reset.
Method 3: delete the last commit entirely#
If you really do not need the commit's contents:
Before running this, always look at git status -s: everything in that output will
disappear. The deleted commit itself lives in the repository for several more weeks
and can be brought back (see the last section), but uncommitted edits cannot.
Several commits are removed the same way: HEAD~3 removes the last three.
Method 4: a reverting commit for a shared branch#
git revert rewrites nothing. It reads the commit you name, works out the opposite
changes and makes a new commit from them on top:
Both commits stay in history: you can see what was done and that it was changed
back. Such a commit goes out with an ordinary git push and gets in nobody's way —
which is why it is the only safe method for code that has been pushed.
Useful variations:
If the changes you are reverting have since been built on by later edits, Git stops
on a conflict. You resolve it in the usual way, described in
how to resolve a merge conflict; then
git revert --continue finishes the job and git revert --abort gives it up.
What not to do#
Force-push after rewriting a shared branch. git push --force replaces the
server branch with yours and silently destroys commits that appeared there after
your last fetch. If the rewrite has been agreed with the team, push like this:
The command refuses to work if the tip on the server is not the one you saw. This is not complete protection (another terminal of yours might have fetched in the meantime), but it catches the most common case — a teammate who pushed work five minutes ago. More in the article on git push.
Undoing a commit by editing files by hand. Putting the files back by hand and
committing works, but it is murky: history gets a commit with no explanation.
git revert does the same thing more precisely and labels it for you.
If you undid too much#
Commits can be recovered until the garbage collector takes them:
The rescue branch now points at the "deleted" commit, and its contents are
available. From there you can bring it back or take individual files.
This trick does not work for uncommitted changes: the reflog only remembers commits. That is exactly why, before any risky operation, the cheapest insurance is a draft commit or stashing your edits.
Step-by-step plan
- Check whether the commit was pushedgit status -sb: ahead means the commit is yours alone and can be rewritten.
- A small fix to the last commitgit add what is missing and git commit --amend, with --no-edit if needed.
- Take the commit back, keep the workgit reset --soft HEAD~1 and regroup the changes.
- Undo something already pushedgit revert <hash>; on a conflict, resolve it and run git revert --continue.
- Check the resultgit log --oneline and git status: the expected tip and the expected contents.
- If you undid too muchgit reflog, find the commit, pin it with a branch via git switch -c.
Start learning this in your own space
The plan goes into your repository: tick off stages, keep notes — the change history shows how far you have come.
Check yourself
1.A commit has been pushed to a shared branch. Which command undoes it without rewriting history?
2.You forgot to add one file to the last, unpushed commit. What is the shortest route?
3.What happens to the commit when you run git commit --amend?
4.You reset the branch with git reset --hard HEAD~1 and it turns out you need that commit. What helps?
Sources
-
git revert referenceReverting commits, reverting merges, working with rangesfree
-
git commit referenceThe --amend mode and what it does to historyfree
-
Pro Git: Undoing ThingsThe section on undoing changesfree
Was this helpful?