Git Ate Your Homework

Jan 10, 2019 09:40 · 493 words · 3 minute read Git Tools

Git ate your homework

So you’re ready to merge your code back to the master branch, it’s 3:50 PM, and you’re just about to leave your home office and get into some comfortable sweatpants.

You perform a rebase squash. (roll a d20)

(you rolled a 1; critical miss)

Your squash was more like a splat, and now everything is a mess and this is going to take forever to fix and oh my god why would you do that now the sweatpants are just a pipe dream and you’ll never be able to binge-watch that show with a bottle of wine, nooooooooooooooooooo!

What happens next will surprise you

If you type git reflog, you’ll see this:

be78b52 (HEAD -> after_file_a, master) HEAD@{0}: rebase -i (finish): returning to refs/heads/after_file_a
be78b52 (HEAD -> after_file_a, master) HEAD@{1}: rebase -i (start): checkout master
bf9a8e7 HEAD@{2}: commit: Added dict file, tweaked file_a
3e43d92 HEAD@{3}: checkout: moving from master to after_file_a
be78b52 (HEAD -> after_file_a, master) HEAD@{4}: commit: Added file_b, tweaked file_a
3e43d92 HEAD@{5}: checkout: moving from after_file_a to master
3e43d92 HEAD@{6}: checkout: moving from master to after_file_a
3e43d92 HEAD@{7}: commit (initial): Added file_a

Of note are the first few lines, including rebase, and the refs on the left. Lucky for you, you didn’t push your changes yet to Github. What you can do is just reset the place to which your branch points (in your case, after_file_a), like so:

git reset --hard HEAD@{2}

Now, your git branch is back to before you ruined your own day, and it’s only 3:52 PM! Still time for sweatpants!

Fun facts

  • Branch names are essentially pointers to references (the git hashes).
  • You can checkout a reference directly (a git hash). This is called “detached head” state.
git checkout bf9a8e7
Note: checking out 'bf9a8e7'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.
  • HEAD points to your current branch. “detached HEAD” means your HEAD (the pointer to the pointer (the branch) to the ref (the hash), is pointing directly to a ref. This is fine, but at some point, consider merging them back.
  • git reflog by default shows all activity in the repository affecting HEAD. This means any commit, revert, rebase, merge, what have you, will leave a trace in the reflog, which is super awesome when you screw up like you did earlier. > The “show” subcommand (which is also the default, in the absence of any subcommands) shows the log of the reference provided in the command-line (or HEAD, > by default). The reflog covers all recent actions, and in addition the HEAD reflog records branch switching. git reflog show is an alias for git log -g > –abbrev-commit –pretty=oneline; see git-log(1) for more information.

  • Last but not least:

Git does not eat your homework. Ever. Use the Force reflog, Luke. (also you’re named Luke)