git HEAD detached *from* vs detached *at*

2.1k Views Asked by At

I am NOT new to git. I know what a detached HEAD is and that I can just checkout a new branch to move forward. But today I saw a detached from message instead of a detached at message. While trying to abort a merge in a repo with 2 submodules, one of my submodules got stuck in this state:

so_is_my_nacho_cheese$ git status

HEAD detached from 9733eeb0
nothing to commit, working tree clean

Question 1:

The from part is throwing me off. I am used to seeing at. What does this commit refer to? Is this the last place the HEAD was before being moved to a branchless commit? In my case, that commit is in the submodule reflog, but it's 7 layers down at HEAD@{7}. That doesn't seem like the last place the HEAD was. But because this was result of an aborted merge in the parent module, maybe the tracing of the HEAD's movement is inscrutable for that reason. What does this detached from commit usually refer to?

Question 2:

To add to my confusion, according to git log, my HEAD is pointing at a branch in the submodule:

so_is_my_nacho_cheese$ git log --graph --oneline -n 5

* ba737d3b (HEAD, xdhmoore_pascal) Just to record pascal run
* 5b69ce96 Fix fine_tune_checkpoint_loading
* 21dc78b2 Just docker changes applied to base
* 9733eeb0 (xdhmoore_base) Updating center_net_mobilenet_v2_fpn_feature_extractor to support classification finetuning.
* 63ec7359 Adding float feature to dataset_util

Why does git status tell me my HEAD is detached (from 9733eeb0, though not at what commit) while git log says it's pointed at ba737d3b?

2

There are 2 best solutions below

2
On BEST ANSWER

When the detached HEAD points at the commit from which it was first checked out, git status says detached at <the_base_commit>. If then you make new commits or use git reset to move HEAD to another commit, for example to its parent, git status says detached from <the_base_commit>. And if then you reset HEAD back to the base commit, git status says detached at <the_base_commit> again.

The base commit is recorded in HEAD's reflog, in .git/logs/HEAD. If you remove .git/logs/HEAD, git status says Not currently on any branch because it cannot find the base commit now.

1
On

A key item I was missing in my understanding is that you can still have a detached HEAD while pointing to a commit with a branch on it. If you are not detached, the log will show HEAD -> with an arrow:

detached:

so_is_my_nacho_cheese$ git log -n 1 --oneline --graph

* ba737d3b (HEAD, xdhmoore_pascal) Just to record pascal run

not detached:

so_is_my_nacho_cheese$ git log -n 1 --oneline --graph

* ba737d3b (HEAD -> xdhmoore_pascal) Just to record pascal run