Undo Mistakes in Git: restore, amend and revert

Git and GitHub Essentials: Version Control for Beginners · Git Basics · 5 min read · Updated

Choosing an undo

  1. Different mistakes need different tools. For an edit you have not staged, git restore brings back the committed version.
  2. If you staged something by mistake, git restore --staged takes it out of the staging area and keeps your edit.
  3. If the last commit has a typo or misses a file, git commit --amend replaces it, as long as it is not pushed.
  4. For a commit that is already shared, git revert adds a new commit that undoes it, and it keeps the history honest.

Everyone makes mistakes: a wrong edit, a file added by accident, a typo in a commit message. The comfort of Git is that you can undo most mistakes, as long as you know which tool fits which situation. This lesson covers the common cases, from the safest to the most careful. You will practise each in a small project, and the session below is a real one.

$ git status -s
 M menu.txt
$ git restore menu.txt
$ cat menu.txt
tea
coffee
$ git add menu.txt
$ git restore --staged menu.txt
$ git status -s
 M menu.txt
$ git add menu.txt && git commit -m "Add soup"
[main 682019c] Add soup
 1 file changed, 1 insertion(+)
$ git add menu.txt && git commit -m "Add jus"
[main 0b5d67b] Add jus
 1 file changed, 1 insertion(+)
$ git commit --amend -m "Add juice"
[main 19ae32e] Add juice
 1 file changed, 1 insertion(+)
$ git log --oneline
19ae32e Add juice
682019c Add soup
f8c6f07 Add menu
$ git revert --no-edit HEAD
[main 4029f99] Revert "Add juice"
 1 file changed, 1 deletion(-)
$ cat menu.txt
tea
coffee
soup
$ git log --oneline
4029f99 Revert "Add juice"
19ae32e Add juice
682019c Add soup
f8c6f07 Add menu

1. Discard changes you have not staged: git restore

We added soup to menu.txt but changed our mind. git restore menu.txt replaced the file with the version from the last commit, and cat menu.txt shows only tea and coffee again. Warning: this throws away your edit for good, because Git never saved it. Use it only when you are sure.

2. Unstage a file: git restore --staged

We staged the file with git add and then realised it should not be in this commit. git restore --staged menu.txt moves it out of the staging area, but keeps your edit in the working folder. The status goes back from staged to M (modified). Nothing is lost.

3. Fix the last commit: git commit --amend

We committed with the message Add jus and noticed the typo. git commit --amend -m "Add juice" replaced the last commit with a corrected one. You can also use --amend to add a forgotten file: stage it, then run git commit --amend. Notice that the commit code changed from 0b5d67b to 19ae32e. Amend creates a new commit that replaces the old one.

4. Undo a commit safely: git revert

Suppose the juice commit was a mistake, and it is already shared. git revert HEAD makes a new commit that does the opposite of the last one. Look at the log: the old commit is still there, followed by Revert "Add juice", and the menu no longer has juice. The history stays honest, and nobody's copy breaks. Revert is the safe choice for anything that is already published. HEAD means the latest commit. You can also revert an older commit by giving its code, such as git revert 682019c.

The dangerous commands

  • `git reset --hard` moves your branch and throws away all uncommitted changes. It can destroy work. Never use it unless you understand exactly what it will remove.
  • `git push --force` overwrites the history on the remote. It can delete other people's work. Avoid it on shared branches. If you must use it on your own branch, prefer --force-with-lease, which stops if somebody else pushed meanwhile.
  • `git clean -fd` deletes untracked files. They are not in Git, so they cannot be recovered.
  • Before you try something risky, make a safety copy of your work, or create a new branch (lesson 4) so you can return to it.

A safety net: the reflog

Even after a bad reset, Git keeps a private log of where your branch was, called the reflog. git reflog lists recent positions, each with a code that you can go back to. It is a lifesaver for commits, but it cannot bring back uncommitted changes, and it is only kept for a limited time. Do not rely on it, but know that it exists.

Choosing the right tool

  • Edited a file and want the old version back: git restore file.
  • Staged something by mistake: git restore --staged file.
  • Wrong message or forgot a file in the last commit, not pushed yet: git commit --amend.
  • A bad commit that others may have: git revert <commit>.
  • Not sure: run git status and read what Git suggests.

A note on the lines you see in the output: Git also prints a Date: line for --amend and revert. We left it out to keep the session short.

Your task

  1. Create a project with a file and one commit. Edit the file, then use git restore to throw the edit away.
  2. Edit again, stage with git add, and then unstage with git restore --staged.
  3. Make a commit with a typo in the message, and fix it with git commit --amend -m.
  4. Make a commit, then undo it with git revert HEAD. Look at git log --oneline.

How to check it worked

  • After restore, the file has its old content.
  • After git revert, your log shows both the original commit and the revert commit.
  • You can say why revert is safer than reset for shared work.

Frequently asked questions

What is the difference between git revert and git reset?

Revert adds a new commit that undoes an earlier one, which is safe for shared history. Reset moves the branch back and can discard work, so it is risky on shared branches.

Can I recover a commit after a bad reset?

Often yes, with git reflog, which lists recent positions of your branch. It cannot recover changes that were never committed.