I am looking for a Git command that will print the symbolic name for HEAD. I
was using this command
$ git name-rev --name-only HEAD
master
$ git checkout HEAD~2
$ git name-rev --name-only HEAD
master~2
However I noticed that it does not work on a new repository
$ git init
$ git name-rev --name-only HEAD
Could not get sha1 for HEAD. Skipping.
I found this workaround
$ git init
$ git symbolic-ref --short HEAD
master
But this does not work on older commits
$ git checkout HEAD~2
$ git symbolic-ref --short HEAD
fatal: ref HEAD is not a symbolic ref
So now I have this, which covers both new repos and older commits
$ git symbolic-ref -q --short HEAD || git name-rev --name-only HEAD
master
I was just wondering, is this the best way to do this? It feels like this should be possible with one command.
You write:
The following may suffice to demonstrate that what you're asking for does not make sense in all situations, simply because
HEADmay not be unambiguously associated with one reference. Read on.What
git name-revdoesIn the
git-name-revman-page, you find the following description:More specifically,
git name-revchecks whether<commit-ish>is reachable from any of the local references (by processing them in lexicographical order, e.g.developbeforemaster).Let's examine what
does in different cases (the
--name-onlyflag is incidental here, as its effects are purely cosmetic).Case in which
HEADis not detachedIf
HEADis not detached, i.o.w. ifHEADis pointing to a valid ref (let's call itmyref), then there is no ambiguity: runningsimply outputs
because the
myrefreference is unambiguously associated withHEAD. So far, so good.Case in which
HEADis detachedIn that case, things are not as simple. In fact, there may be one or more references from which
<commit-ish>is reachable, or there may be none at all.Case in which there are one or more such local references
At the first such local reference found,
git name-revprints a "relative" symbolic reference, i.e. a revision of the formwhere
<ref>stands for the local reference in question, and<n>stands for the generation. For example, ifHEADpoints directly to a commit that is a grandparent ofmaster(masterbeing the only local reference), thenreturns
Note, however, that in case
<commit-ish>is reachable from multiple references, the one returned bygit name-revis somewhat arbitrary, as it's only dictated by the lexicographical order (in which the command checks local references).Case in which there is no such local reference
It's easy to imagine situations in which
<commit-ish>is reachable from none of the local references. Actually, here is one you can reproduce at home (boilerplate stdout is omitted):Because the commit DAG looks as follows,
commit
Bis not reachable from the only reference (master); therefore,git name-revgives up and simply returnsundefined.Conclusion
Because
HEADis not guaranteed to be unambiguously associated to one reference, what you're asking for doesn't make sense:p