Cancel a Git CommitJanne 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.
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
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.
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.
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!