git is just the best version control tool, ever, period. Most of times, it's straightforward. Sometimes you have to really understand what happens.
A few day ago I synchronized with another repository on a USB key. Then I resumed my work. While requesting
git status
I saw many times there was no current branch. I decided to fix that by forcing the current branch, issuing a
git checkout master
. Then all the work I did since the synchronization appeared to be lost
on both git repository and my local filesystem!
As those commits happened, I was pretty sure they were somewhere inside my git repository. Reading git
doc carefully, I learned that I was working with a "detached head" (poor myself).
It is sometimes useful to be able to checkout a commit that is not at the tip of one of your branches.
[...]
The state you are in while your HEAD is detached is not recorded by any branch (which is natural --- you are not on any branch). What this means is that you can discard your temporary commits and merges by switching back to an existing branch.
Clearly, I messed the merge in some way. The way to recover was mentioned: the "reflog" kept track of every changes (including those not attached to a branch) until a
git prune
or a
git gc
.
Here is what I did.
First, read the reflog and find last "lost" commit with my bare eyes:
$ git log -g --after=2008-08-14
Appeared to be:
991ee3ebc11e1dc3434fab4c22e261b7e0711346
.
This time I created a branch:
$ git branch rescue_2008-08-23
$ git checkout rescue_2008-08-23
Now get back every "lost" stuff with
one single command (commits are chained):
git checkout 991ee3ebc11e1dc3434fab4c22e261b7e0711346
This looked good. I committed inside the "
rescue_2008-08-23
" and switched back to the "master" branch:
$ git commit -a
$ git checkout master
Merge happened seamlessly as a "fast forward", wow!
$ git merge rescue_2008-08-23
Updating 13d16f3..31626f8
xxx: needs update
[...]
Fast forward
[every "lost" change listed here, there were many!]
This mess happened because I had some problems during the merge I didn't try to understand. Next time if I get such problems I'll do all the mess in a new branch of the target repository, and then perform a second merge.