Another git horror story

Some not so common git disasters and their fixes

I’ve had my fair share of encounters(read, disasters) while working with git. Well, that’s how you learn, right? I remember the days when before running any git command I used to copy the whole project as a backup and the process continued by creating a backup of backup and so on. Kind of redundant when using a version control, no?

Well, what about the old days, even last year, I wiped out the project completely on my machine, after copying a command from StackOverflow blindly.

So, two learnings for me from that episode,

  • Never run any git command blindly(well, this goes for any command, right?)
  • Always work with an IDE that maintains local history, for disaster management.

Yeah, so how did I manage to bring back the wiped-up code?

I was working with PyCharm, and it maintains a Local History of the project in it. It can be accessed via

  • Right-click on the project > Local History
Local History in Intellij

And looks something like this:

Local history — Intellij

So, from this local history, I was able to restore the complete project including the setup, uncommitted files, everything! Many thanks to the Local History of PyCharm.

One other mess I created once, was while working on a core/common repository that was being widely used. We all know merging a change in a common repository is a task in itself, as it involves a rigorous development-testing-review cycle.

So, after going through the cycle, and getting the final approval for merging, my changes were ready to merge, and guess what I did?

I accidentally reverted(using reset HEAD) the latest commit from my local repository(don’t ask me why), and decided to throw the whole approved review down the drain.

Now, you must be thinking why didn’t I just take a pull from the origin branch and bring changes to my local. And to answer your question, the git setup I was working with didn’t have the option to pull the changes from the origin.

The only option? Get the reverted commit back with the same commit SHA, because if I commit the files again, a new commit ID/SHA will be created, which means, getting the approval again on a core repository!

So, how did I get the commit back?

git reflog came to the rescue. Taken from the git documentation:

Reference logs, or “reflogs”, record when the tips of branches and other references were updated in the local repository. Reflogs are useful in various Git commands, to specify the old value of a reference. For example, HEAD@{2} means "where HEAD used to be two moves ago", master@{one.week.ago} means "where master used to point to one week ago in this local repository", and so on. See gitrevisions[7] for more details.

Meaning for every git operation you do locally, reflog keeps a track of it and the same can be accessed via git reflog command.

Sample git reflow output

As shown above, the log maintained also keeps track of HEAD positions like HEAD@{0} as a result of different git commands that were run and viola! This was exactly what I needed.

So I ran git reflog, and found where my git HEAD was before the reset HEAD command went back to the HEAD position using

git reset ‘HEAD@{12}’

And that’s how I got my commit with the same commit id back! Sorcery, right?

git is such an underrated tool, when used right, it can be very powerful but it has its own learning process and some disasters that come with the process. Having a command and information like reflog, might help to avoid some disasters(it won’t help you if you do a force push on master, that’s on you!) and also in some cases Local history of IDE can come in handly and might save you from creating a backup of your backup before running the scary git commands :P

Until next time,
JD

Big Data Engineer at Linked[in]