Oh no. I just committed a file containing my username, password, social
security number, and mother’s maiden name. How do I make sure this never
sees the light of day? Stack overflow would probably tell you “just do a
git reset --hard”. But what does
git reset do?
The documentation page for reset actually lists the ability to erase commits as the last of three usages for reset. These three options are:
The first is the way to undo
git add. If you added some file, text.txt,
that you really didn’t want to add, then typing in
git reset HEAD text.txt
git reset -- text.txt) will remove text.txt from the index (where
it got put when you typed
git add text.txt, or did something more complicated
with the same effect). The
-q is for quiet, which would make Git only output
The next option is if you want to have a little more control over what happens, so you could unstage just the password you saved, but not the social security number that you want the world to know.
Finally, option 3 is for undoing entire commits, well, sort of.
First off, let’s get the usage - if you committed changes, and you just
want to go back 1 commit, you do a
git reset HEAD~1. What this really
does is change the file
to contain the 40-character hash for the parent of
HEAD instead of the
HEAD. You can actually set this to any commit that you know the
hash for, so like
git reset acce7b will reset to the commit that starts
with that hash. There are several modes that you can specify here,
soft, mixed, hard, merge and keep:
Soft: only change the repository, don’t change anything in the index or working directory.
Mixed: (the default) change the repository and reset the files in the index to those stored in the commit (yes actually entirely stored in the commit, see the commit post).
Hard: reset everything! This throws away all changes in the index and working directory and replaces them with the files in the commit.
Merge: resets the index and files in the working directory to what’s stored in the commit, but it keeps files that have unstaged changes in the working directory. An error is thrown and the reset stops if a file is different between the current commit and the one to reset to and has unstaged changes. Usually used to undo a ‘merge operation’.
Keep: does a hard reset, but aborts if there are local changes in a file that changed between the target commit and the current commit and keeps uncommitted changes in the working directory and index.
Some useful things to know:
Git reset ORIG_HEAD after a pull or merge to undo it (add
--merge to avoid losing local changes)
If you don’t specify anything, this will just un-stage changes in the index
What if I want to undo a commit way way back, but not everything in between?
The answer is
git revert– for another day.