Git Concepts

What Even Is HEAD?

HEAD is a symbolic reference pointing to your current place in the git history. During normal state, this points to the latest commit on the branch you are on (the tip of the branch).

When in detached HEAD state, HEAD points to a specific commit SHA.

You can see what HEAD is currently pointing to by running

cat .git/HEAD

git enters detached head state when you:

git reflog Is A Magical Time Machine

Background context

After finishing up a feature, passing review, and getting ready to ship to prod, I squashed a set of 7-ish commits and rebased onto main to clean up the branch.

Since this changes the git history, I forced pushed my changes into the remote, which forcefully replaced remote with my work.

Turns out something went wrong in my rebase and a test file for the feature I just completed (a days worth of work) had been deleted during the process. I had no copy of the commit introducing the test file in my local and no copy in the remote.

Turns out git reflog was able to help me find the SHA of the commit where the test file was. I checked out that commit SHA and copied the test file into my squashed feature branch. I probably could have used git cherrypick but that is a lesson for another day.

What is git reflog

The reflog is a log of all the moves HEAD has made in your local repository. Every time you switch branches, start a rebase, merge branches, go into detached head state, etc. the reflog keeps an entry of this movement. Each entry includes the commit hash, and a message that contains a few other infos (like the branch name you switched to). This data is stored in your projects local .git directory.

The reason why it’s possible to restore a messed-up repository with reflog is because git keeps those commit hashes. As long as there is some reference to a commit somewhere in the repo, Git won’t forget about that commit.

As long as you are following good commit practises - commiting often, committing atomically - it’s near impossible to have something be lost forever.

Just don’t delete your .git directory, the reflof of all your local movements will NOT be in the remote repo.

Additional Resources

git, concepts