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 [email protected]{1}
Some of this will look like very ordinary git stuff. Up until the “[email protected]{1}”, the above git command is just checking out a new branch. The [email protected]{1} specifies that the source for the new branch is … not the current branch. So what is this [email protected]{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 [email protected]{0}: commit: refactor EventManager drag events to be less aggressive about removing listeners from target
cbb109f [email protected]{1}: rebase -i (finish): returning to refs/heads/master
cbb109f [email protected]{2}: rebase -i (squash): Bug: swipes generated during drag
bacc417 [email protected]{3}: rebase -i (squash): updating HEAD
9e327e8 [email protected]{4}: rebase -i (squash): # This is a combination of 3 commits.
bacc417 [email protected]{5}: rebase -i (squash): updating HEAD
7b90379 [email protected]{6}: rebase -i (squash): # This is a combination of 2 commits.
bacc417 [email protected]{7}: rebase -i (squash): updating HEAD
fa11efd [email protected]{8}: checkout: moving from master to fa11efd
9a7d080 [email protected]{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 “[email protected]{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.