At some point, a new user of Git will accidentally commit some undesirable changes. This post will address a few scenarios where you might want to “undo” a commit.
First case, you’ve committed some terrible code, and you simply want to blow away the previous commit and start over. Remember, each commit is uniquely identified by a hash identifier, and you’ll need to locate the hash of the commit just previous to the unwanted commit you just created. To undo the most recent commit, you’ll type:
git reset --hard [hash_of_commit_previous_to_unwanted_commit]
WARNING: Much like ‘–hard’ implies, this will completely blow away the unwanted commit. You will not be able to retrieve the changes for that commit in a way that is…economical. What if you want to undo the commit, but you still want to further manipulate the changes that were contained in that commit? A common scenario might be that you want to improve the changes or that you simply want to recover a specific portion of the commit. Then, you simply modify the above command:
git reset --soft [hash_of_commit_previous_to_unwanted_commit]
git reset [hash_of_commit_previous_to_unwanted_commit]
There is a slight difference between resetting a to a previous commit using –soft versus no option at all. What happened in the first command (reset using –soft), is that we’ve undone the previous commit and pulled the changes back into “staged” mode, which is essentially what the status of the files were right before you originally committed the unwanted changes. The second command (reset, without specifying an option) returns the changes to “unstaged”, which means that if you want to make some additional modifications and then commit them, you’ll need to add or “stage” them to do a subsequent commit.
All of the above examples require you to seek out the specific hash of the commit to which you want to reset the current branch, and this can be tedious. You can accomplish the same general goal (using similar options for each type of reset) as the above commands, by simply typing:
git reset HEAD~1
Perhaps you’ve seen the term HEAD in command-line output with Git and have always wondered what it means? Basically HEAD is a symbolic reference to the most recent commit (or “tip”) of a branch. By specifying HEAD~1, you’re basically saying, I want to go back exactly one commit from HEAD. Learning to use the convention of HEAD~[some-number-of-commits-back] is a common shorthand for specifying the target of other Git commands as well (such as rebase and log), so be sure to get comfortable using. It will be very handy and convenient for you in the future when executing more advanced operations with Git.
There you go…now you can undo a commit! Git luck to you!