Log in

January 9th, 2009

Previous Entry Share Next Entry
10:29 pm - Revisionist History
Earlier I talked about how to fix mistakes you made in your work tree, and left the topic of fixing mistakes you made in your commit.  This entry is about that.

git reset HEAD^
discards the latest commit without touching files in your working tree.  It is to pretend as if you did all the work without saying "git add" anything at all since the commit immediately before the one you created by mistake.

In other words, a typical scenario to apply it would be:

git checkout branch ;# start working on this branch
edit edit edit
git add ...
git commit

And you noticed that the commit was wrong and you would want to redo it.  Then you would say:

git reset HEAD^

and you can pretend that you never did "git add ..." and "git commit" above, without losing any of your editing.

git reset --soft HEAD^ keeps both your changes to files in your work tree and the state you recorded with "git add" so far, and only discards the latest commit.  This is to pretend that you never did "git commit" above, but your "git add" so far are still remembered.

git reset --hard HEAD^ discards the changes to the files in your working tree while discarding the latest commit.  In other words, you are taken back to the state immediately after checking out the branch.

All are to recover from making a wrong commit.  You use the default or --soft variant when what you recorded in the commit was wrong, but what you have in your work tree is largely OK (e.g. perhaps you wanted to make two commits out of a mixed set of changes in your work tree, but you ran "git add" too eagerly and included changed files that you did not intend to record in the commit by mistake).  The default one is easier to work with if your previous "git add"s were too screwed up, and --soft one is easier to work with if your previous "git add"s were mostly OK.

You use --hard when everything you did was wrong (e.g. the experimental changes you madae in your work tree did not work well, you are better off making another attempt from scratch than trying to fix the failed code which is beyond repair).

git commit --amend makes --soft variant mostly redundant.  If what you committed was wrong, what you have in the work tree is mostly correct and also what you "git add"ed to the index is also mostly right, then without resetting to discard the commit, you can keep working and "git add" what you corrected as fix-ups, and then say "git commit --amend".  This discards the last commit and replaces it with a new commit with the fixed-up content with a single step.

In other words,

git commit --amend

is equivalent to

git reset --soft HEAD^ && git commit -c HEAD@{1}


(Leave a comment)

Revisionist History - gitster's journal

> Recent Entries
> Archive
> Friends
> Profile

Pages at the k.org
The latest blog by Gitster

> Go to Top