Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Git describe without tags

Tags:

git

I have a repository that gives me only a hash when I run git describe. I did not know until today that it does this because of the --always option (which is what I was using) since that repository has no tags. I have another repository with lots of tags.

How can I use git describe to exclude tags and just give me a hash? I want to have all of the other functionality of git describe in case I need to use the other features, such as dirty marking; I just want to exclude tags. Is this possible, or are tags the central feature of describe?

The help page does seem to indicate that, but I just want to be sure. I use this in an Ant build.xml file, so I'm trying to keep this simple.

like image 823
sorinev Avatar asked Jul 05 '17 16:07

sorinev


2 Answers

Yes, but it's not necessarily a good idea. There is a --all option, which will search branch names—or in fact, all references—as well, but if you use that, you might also need --long.

Description

The central feature of git describe output is that it starts with a name that is (or should be) human-readable:

v1.2.3

To this, Git will, if necessary, add a suffix indicating that the current (or requested) commit is not quite the one named by this string. The suffix tells both you and Git how much to deviate from the tag. If there is no suffix, the tag itself names the commit. Since tags never1 move, if we have that name, we are guaranteed2 to find the correct commit using that name.

With a repository with no tags and no --always:

$ git describe
fatal: No names found, cannot describe anything.

If we add --all, however, we might get this:

$ git describe --all
heads/master

This is a human-readable name, but there is a problem with it: it does not uniquely identify one particular commit, because branch names do move. Once I make a new commit in this repository, refs/heads/master now names a different commit.

Since the usual intent of one of these outputs from git describe is to provide a human-readable but exact-commit-specifying ID, a branch name, which is never that exact, is not necessarily a good thing.

You can add --long:

$ git describe --all --long
heads/master-0-g2cbd83f

This now uses the -g... suffix to specify a prefix of the actual hash ID. Now Git can verify that master itself has not moved, or if it has, you can use the 2cbd83f string to find the commit.


1Well, hardly ever. See the git-tag documentation on when and why and why not to move a tag.

2Guaranteed to the extent that tags have not moved, anyway.

like image 173
torek Avatar answered Oct 05 '22 09:10

torek


An easy way to do this is to combine --always with the -exclude option, using a glob pattern of *, to exclude all tags from consideration. Since it won't find any non-excluded tags, describe will fall back to just the abbreviated sha1 plus optionally "-dirty" and so on.

$ git describe --always --dirty --abbrev=5 
2018.02-rc1-58-gca0e6
$ git describe --always --dirty --abbrev=5 --exclude '*'
ca0e6
like image 34
TrentP Avatar answered Oct 05 '22 08:10

TrentP