OUR BLOG

Thoughts on development, design and the world we live in.



Undelete a branch in git

By Kane Baccigalupi in git. Posted on July 5th

The other day I had a bit more insomnia than usual. As such it seemed like a good idea to clean up my local repository’s branches using the immediate and seemingly permanent -D option:

git branch -D my_important_branch

With just one tiny statement on the command line, I managed to delete the very stuff I was working on. Apparently, git plans for this kind of stupidity, and it is quite easy to go back in time to a place free of grievous errors. Here is the fix:

git checkout -b my_important_branch HEAD@{1}

Some of this will look like very ordinary git stuff. Up until the “HEAD@{1}”, the above git command is just checking out a new branch. The HEAD@{1} specifies that the source for the new branch is … not the current branch. So what is this HEAD@{1}? It turns out that git keeps track of changes to the head of each branch using a tool ‘reflog’, with is short for reference log. You can look at what reflog is storing at any time:

git reflog

Here is an example of what I have on my current reflog at my wheel.js project:

121f1ea HEAD@{0}: commit: refactor EventManager drag events to be less aggressive about removing listeners from target
cbb109f HEAD@{1}: rebase -i (finish): returning to refs/heads/master
cbb109f HEAD@{2}: rebase -i (squash): Bug: swipes generated during drag
bacc417 HEAD@{3}: rebase -i (squash): updating HEAD
9e327e8 HEAD@{4}: rebase -i (squash): # This is a combination of 3 commits.
bacc417 HEAD@{5}: rebase -i (squash): updating HEAD
7b90379 HEAD@{6}: rebase -i (squash): # This is a combination of 2 commits.
bacc417 HEAD@{7}: rebase -i (squash): updating HEAD
fa11efd HEAD@{8}: checkout: moving from master to fa11efd
9a7d080 HEAD@{9}: commit: event managers no longer trigger swipe during drag

Reflog says that I did a normal commit. Before that I squashed some commits using an interactive rebase. Before that I switched branches.

So in the magic undelete code “HEAD@{1}” refers to reflog for the branch before it was deleted.

Of course, it is always wiser to use the -d option when deleting. That way git provides a nice warning if a branch is being deleted before it has been merged into master. Even better is advice is to get plenty of sleep. It will much improve the git workflow.

By Kane Baccigalupi | Posted in git | Comments (0)

Post a Comment

Your email is never shared. Required fields are marked *

*
*