3

I need a command which returns the full reference name of my currently checked out revision. Or as close to this as possible. Big plus if git-only (for cross-platform purposes).

By "full reference name" I mean e.g. refs/tags/my-tag, refs/heads/my-branch.

Examples:

git checkout master
magic command
# => /refs/heads/master

git checkout v1.0.0
magic command
# => /refs/tags/v1.0.0

git checkout 86742545e8152a8fbf31eafa55eb573042f61f5d
magic command
# => 

Few points of reference:

  • I actually don't think this is possible with 100% accuracy because (as I understand git) there's no difference between checking out a tag and a specific hash. I.e. .git/HEAD shows the hash in both cases.
  • git show-ref shows all references and the corresponding commit hashes
  • git symbolic-ref HEAD works for branches and with the -q option it doesn't fail if you're not on a branch
  • git describe --tags --exact-match kind of works for tags, but you'd need to prefix it with refs/tags and get rid of stderr

Related:

All I could find seemed too complicated for what I'm looking for.

thisismydesign
  • 21,553
  • 9
  • 123
  • 126
  • try `git branch --list`. it will give you the name of the currently checked out branch. – Serge Nov 26 '19 at 16:23
  • "I need a command which returns the full reference name of my currently checked out revision." The modern term for this is "xy problem": you're in some situation, you've imagined a method for dealing with that situation based on your understanding of it, and are asking for implementation help with a troublesome step in that method—without explaining either method or motive—when the real problem is you're trying an approach that's so far suboptimal there's simply no support for it. Could you explain what prompts this attempt please? – jthill Nov 26 '19 at 18:17
  • @jthill thanks for the help & description, but my problem is wanting to do exactly what's described in the question. It's prompted by me wondering how to do it. – thisismydesign Nov 26 '19 at 23:22
  • Well, I've had idle curiosity grab hold of me before too, but I try not to call that a "need" without making the humorous intent a little less implicit. – jthill Nov 26 '19 at 23:43
  • Fair enough, I suppose I'd like to know if there's a command which... – thisismydesign Nov 27 '19 at 00:14

1 Answers1

2

You probably want git describe, perhaps with some flags and perhaps with some post-processing. See details below.


I'm not entirely sure what actual problem you are trying to solve:

  • The hash ID is the permanent name for this commit. So just git rev-parse HEAD and you have it.

  • The current branch name is what git symbolic-ref HEAD gets. It produces an error if there is no current branch name, which is the case whenever you use git checkout to switch to a detached HEAD. That includes:

    • checking out a non-branch name (e.g., a tag name or remote-tracking name),
    • using --detach with a branch name, and
    • using a raw hash ID (of course).

Note that a branch name stores one commit hash ID, except for the somewhat special case of being on an "unborn branch", in which case, the branch name doesn't exist, even though it is the current branch name. This somewhat obnoxious state is necessary because a branch name must contain the hash ID of an existing commit, and in a new, totally-empty repository, there is no existing commit, yet you're started out on branch master.

If the problem you are trying to solve is: "Tell me what command the user typed in to get into the HEAD state I'm in now, whether that is detached or attached", Git does not save that for you. The closest you get are entries in the HEAD reflog. This reflog is not required to exist. One other place to look is in history saved by the shell (command line interpreter): if that history exists, it probably contains the exact command the user entered, even if that command is an alias.

If the problem you are trying to solve is: "Provide a name useful to / readable by humans, that will (always | currently) identify this exact commit", there is no right answer, but the closest you can come is to make your own new tag for the current commit hash ID. The second-closest you can come, which is pretty useful, is to use the output of git describe (which has lots of flags to tweak its output). Note that using a branch name will only identify the same commit until the branch name moves on to identify some other commit, which happens regularly.

torek
  • 448,244
  • 59
  • 642
  • 775
  • Thanks. I'm just wondering if this is possible. I'd use it for something like "tell me where the user expects to be now? - on a tag / branch / commit", so your first case. But the right answer is that it's not simply possible. `reflog` is great but makes things very complicated. – thisismydesign Nov 26 '19 at 23:33
  • 1
    Well, that's what `git status` tries to do too. It would be nice if there were a plumbing equivalent of "obtain the thing that `git status` will say about the branch" (the first line info, `on branch foo` or `HEAD detached at/from ...`), but there isn't - but you can do `git status | head -1`, crude as that is. – torek Nov 27 '19 at 00:08