What is Git Reset?
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
(or 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
errors.
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 .git/HEAD
and .git/refs/heads/<current branch>
to contain the 40-character hash for the parent of HEAD
instead of the
hash for 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.