Using Git describe without tags
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.
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