Cancel a Git Commit

Janne Kemppainen |

Did you commit and push something that you didn’t intend to? Don’t worry, it’s quite simple to fix!

Sometimes you just can’t avoid accidentally committing files. Perhaps there were some automatically generated files that were included with git add ., you forgot to use git status to verify what was staged, and then happily committed to the repo, maybe even pushed to the remote.

$ git add .
$ git commit -m "add new file"
[master 589d92a] add new file
 4 files changed, 4 insertions(+)
 create mode 100644 .newfile.txt.un~
 create mode 100644 .unwantedfile.txt.un~
 create mode 100644 newfile.txt
 create mode 100644 unwantedfile.txt

We only intended to include newfile.txt but our commit contains temporary files from Vim and another file that we don’t wish to include in this commit. How can we cancel what we just did?

Reset to previous commit

You can reset the latest commit with this command:

$ git reset HEAD~1

This effectively takes you back in history by one step but keeps the changes on your local file system. The HEAD~1 part means “go back one commit from the current one”. You can check the git-reset documentation for more details.

Use git status to see what has changed:

$ git status
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        .newfile.txt.un~
        .unwantedfile.txt.un~
        newfile.txt
        unwantedfile.txt

Next, add the files that you actually wanted and commit again

$ git add newfile.txt
$ git commit -m "add new file"

If you had already pushed the erroneous changes to the remote repository then you’re going to have to update the branch with a force push:

$ git push -f

Be careful when force pushing to a remote, especially when others might be working on the same branch. Be extra cautious when force pushing to a default branch such as main. Typically you’d even want to forbid such activities!

The default behavior of git reset matches the --mixed flag which resets the Git index but not the working tree. That’s why our files are still there, but unstaged.

Reset commit but keep changes staged

Optionally, you can specify the --soft flag to cancel the commit, but keep the changes in the staging area.

$ git reset --soft HEAD~1
$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        new file:   .newfile1.txt.un~
        new file:   .unwantedfile.txt.un~
        new file:   newfile1.txt
        new file:   unwantedfile.txt

Use git reset to remove a file from the staging area:

$ git reset unwantedfile.txt

If the filename could potentially be interpreted as a command line argument or a branch then you’d have to add -- before the file(s):

$ git reset -- unwantedfile.txt

This only signifies to Git that everything after the double dashes should be interpreted as file or directory names.

Commit the changes and (force) push as needed.

Reset and discard changes

The third option is to do a hard reset with the --hard flag. This will remove all changes in your repository after the specified commit, so be careful!

$ git reset --hard HEAD~1

Any untracked files will still be present, though.

Create a git cancel alias

If you don’t want to have to remember (or type) the correct reset command every time you need to cancel a commit then why not create an alias out of it!

$ git config --global alias.cancel 'reset HEAD~1'

Now you can cancel the previous commit with the git cancel command.

Final thoughts

Git can be a bit intimidating at times, and when you make mistakes you can find yourself Googling for answers. Don’t worry as this is completely normal, even I have to do it surprisingly often.

I really recommend that you take a look at the official Git documentation to learn things that I haven’t covered here, but I also hope that this post gave you the answer that you were looking for!

Discuss on Twitter

Subscribe to my newsletter

What’s new with PäksTech? Subscribe to receive occasional emails where I will sum up stuff that has happened at the blog and what may be coming next.

powered by TinyLetter | Privacy Policy