Today we had a problem: we lost several git commits when a rebase went wrong. We’re still not sure how this happened, but we were able to recover the commits. Here’s a quick summary of how we managed that, which I hope will help others get out of similar situations.
We tried to abort a rebase that had a lot of conflicts, and it took us from a situation like this:
to one like this:
Disaster! Our “last big commit on my story” has vanished! We were pretty sure it was still in the repository somewhere, it just wan't reachable from any named branch. We hunted around in git log, git fsck and other commands with no luck. It turns out that the answer lies in git reflog show
$ git reflog show
3330b4e HEAD@{0}: checkout: moving from ms2 to my-story
3330b4e HEAD@{1}: checkout: moving from 3330b4e0b9af502908ce2c59958ec1e7f83a1a4b to ms2
3330b4e HEAD@{2}: checkout: moving from my-story to 3330b4e
5b50352 HEAD@{3}: rebase: updating HEAD
8f4a119 HEAD@{4}: rebase: more work on my story
c715f09 HEAD@{5}: rebase: some work on my story
6e1441d HEAD@{6}: checkout: moving from my-story to 6e1441d03b200d62f9ffc28d902c60a289d2ea3b^0
5b50352 HEAD@{7}: checkout: moving from mainline to my-story
6e1441d HEAD@{8}: commit: more work by the rest of the team
e72f33f HEAD@{9}: checkout: moving from my-story to mainline
5b50352 HEAD@{10}: commit: last big commit on my story
3330b4e HEAD@{11}: commit: more work on my story
a7d49b0 HEAD@{12}: commit: some work on my story
f3d00fb HEAD@{13}: checkout: moving from master to my-story
f3d00fb HEAD@{14}: checkout: moving from mainline to master
e72f33f HEAD@{15}: commit: some work done by other developers
f3d00fb HEAD@{16}: checkout: moving from master to mainline
f3d00fb HEAD@{17}: commit: commit b
2fcece2 HEAD@{18}: commit (initial): commit a
There it is! We now have the SHA for the “last big commit on my story”. We can check that this really is the right one:
$ git show 5b50352 commit 5b503520f132e1a64c510816fcd61cc97626791e Author: Alex ScordellisDate: Tue Jul 21 20:26:21 2009 +0100 last big commit on my story diff --git a/anotherfile.c b/anotherfile.c ...diff contents elided...
Now all we had to do was reattach a branch name to that SHA, and we were back where we started:
ascordel@ALEXSCORDEL /c/alex/code/git-recovery $ git checkout 5b50352 Note: moving to '5b50352' which isn't a local branch If you want to create a new branch from this checkout, you may do so (now or later) by using -b with the checkout command again. Example: git checkout -bHEAD is now at 5b50352... last big commit on my story ascordel@ALEXSCORDEL /c/alex/code/git-recovery (5b50352...) $ git checkout -b recovered-my-story Switched to a new branch 'recovered-my-story'
Now we’re back where we were at the beginning. We can start again and try to get the rebase through this time. We still don’t know where it went wrong in the first place, but we were pretty relieved to get our work back after a short period of panic!

Nice one. I had this problem just today :-)
ReplyDeleteI saw an article not so long ago, the gist of which was, rebase is probably not the right tool to use..
ReplyDeleteI'm pretty sure the one I read gave much more complete arguments, but here is an article on Git best practice and another on rebase considered harmful
Maybe worth a read :-)
@Andy - that sounds like good advice in general. I always feel with git that there are so many different ways to get things done, so thanks for the links to recommended practice.
ReplyDeleteIn our situation we're actually using git svn. I think this requires a rebase in order to push a linear working history back into the central svn repo.
Thank you. Great help.
ReplyDelete@will - glad to be of help :-)
ReplyDeleteThanks for the post. I had a moment of panic myself today thinking I had lost hours of work but was able to recover everything. (Huge sigh of relief)
ReplyDeleteI'm not quite sure what I did but looking at my shell history I have a guess. I was working in a branch and I think I meant to type
git reset HEAD~1
when I commited something my accident. Instead I typed out
git rebase HEAD~2
I don't know where the 2 came from or why I rebased but it's in my shell history so I must of done it.... :-) In any case I thought I was on my branch when really I was working off of an unnamed branch as passing a branch to (HEAD~2) to rebase created a new branch I think.
Later I went to merge my branch to master and got far less than I thought I should have when the fast forward was complete. After some panic I found this post and wanted to thank you for it.
Thanks!
Joel
Thanks! This help me a lot.
ReplyDeleteSaved my life. Thanks!
ReplyDeleteThanks, you saved me a lot of worry too.
ReplyDeletePhew, I thought I lost my commit!
ReplyDeleteThanks!
Saved my day!
ReplyDeletethanks buddy you made my day...
ReplyDelete+1
ReplyDeleteYou just saved my 7 man days. Thank you so muchhhh.
ReplyDeleteThank you!! OMG so relieved!
ReplyDeleteSaved my 2 days of work from being lost... Thanks!
ReplyDeleteThank you mate :D.
ReplyDeleteI also have experienced the "short period of panic" till I find your solution... Thanks a lot!
ReplyDeleteJust ran into exact same problem. your blog helped. Thank you!
ReplyDeleteYou saved me....
ReplyDeleteThank you very much!