Print a symbolic name for HEAD

I am looking for a Git command that will print a symbolic name for HEAD . i used 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 in the 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 for older commits

 $ git checkout HEAD~2 $ git symbolic-ref --short HEAD fatal: ref HEAD is not a symbolic ref 

So now I have this that spans both new repositories and older commits

 $ git symbolic-ref -q --short HEAD || git name-rev --name-only HEAD master 

I'm just wondering, is this the best way to do this? It seems like this should be possible with a single command.

+5
source share
2 answers

You write:

I am looking for a Git command that will print a symbolic name for HEAD .

There is not enough sense in all situations to demonstrate what you are asking, simply because HEAD cannot be unambiguously associated with a single link. Read on.

What git name-rev does

In the git-name-rev man page you will find the following description:

Given the commit, find out where it refers to local refs. [...]

In particular, git name-rev checks whether <commit-ish> is accessible from any of the local links (by processing them in lexicographical order, for example, develop to master ).

Let's look at what

 $ git name-rev --name-only <commit-ish> 

in different cases (the --name-only flag is random here, since its effects are purely cosmetic).

Case in which HEAD does not detach

If HEAD not disconnected, iow if HEAD points to a valid ref (let's call it myref ), then there is no ambiguity: running

 $ git name-rev --name-only HEAD 

just prints

 myref 

since the link myref uniquely linked to HEAD . So far so good.

The case in which the HEAD separated

In this case, everything is not so simple. In fact, there may be one or more links, of which <commit-ish> achievable, or not at all.

A case in which there is one or more such local links

When the first such local link is detected, git name-rev prints a "relative" symbolic link, i.e. form revision

 <ref>~<n> 

where <ref> stands for local link, and <n> stands for generation. For example, if HEAD points directly to a commit, which is the grandmother of grandfather master ( master , which is the only local link), then

 $ git name-rev HEAD 

returns

 master~2 

Note, however, that if <commit-ish> is accessible from multiple links, the one returned by git name-rev is somewhat arbitrary, as it is dictated only by the lexicographic order (in which the command checks local links).

A case in which there is no such local link

It is easy to imagine situations in which <commit-ish> achievable from any of the local links. In fact, here is one of them that you can play at home (the template stdout is omitted):

 # set things up $ mkdir test $ cd test $ git init # create a commit $ touch README.md $ git add README.md $ git commit -m "add README" # detach the HEAD (make it point directly to the tip of master, instead of to master itself) $ git checkout $(git rev-parse master) # create a second commit (while in detached-HEAD state) $ printf "foo\n" > README.md $ git commit -am "write 'foo' in README" # attempt to find a symbolic name for HEAD $ git name-rev --name-only HEAD undefined 

Since the DAG commit command is as follows,

 A [master] \ B [HEAD] 

commit B not available from a single link ( master ); therefore git name-rev issues and just returns undefined .

Conclusion

Since HEAD not guaranteed to be uniquely linked to a single link, what you are asking for does not make sense :p

+8
source

Just want to add my solution for your case:

 git symbolic-ref -q --short HEAD || git describe --all --always HEAD 

This covers branches, tags, individual chapters (commits), and new repositories. But tags will be returned, for example, as tags/0.1.0 .

+4
source

Source: https://habr.com/ru/post/1209749/


All Articles