Get the current Git branch name or commit hash if detached

Viewed 214

Is there a single command that will print the current branch (e.g. master) if there is one, or the commit hash if it is detached? The purpose is to give me something to write down so I can later execute git switch <branch_or_commit> to get back to where I started.

This is to be used programmatically, so no scraping of git status, Bash pipes or whatever. The answer needs to use the "plumbing" commands, which have guarantees about the format and stability of their output.

Also I should note that there are many many questions asking for each of these thinks individually, but not together. PLEASE THINK BEFORE CASUALLY MARKING THIS AS A DUPLICATE.

Here are the things I have tried. The closest is actually cat .git/HEAD.

Command Output on a branch Output when detached
git rev-parse HEAD cedbe9... cedbe9...
git rev-parse --abbrev-ref HEAD master HEAD
git symbolic-ref --short HEAD master fatal: ref HEAD is not a symbolic ref
cat .git/HEAD ref: refs/heads/master cedbe9...
git branch --show-current master (no output)
your answer here master cedbe9...
2 Answers

Impossible with exactly one command but possible with two:

git symbolic-ref -q --short HEAD || git rev-parse HEAD

Get the current branch; but if detached get the hash.

The purpose is to give me something to write down so I can later execute git switch <branch_or_commit> to get back to where I started.

You'll need to know whether the thing-you-got-back is a branch name or a commit hash ID because git switch demands the --detach flag when using a hash ID, but using --detach with a branch name will produce the wrong result.

Thus, you need to know whether you're getting a symbolic name:

if switchname=$(git symbolic-ref -q --short HEAD); then
    detach=
else
    switchname=$(git rev-parse HEAD) || exit  # quit if unborn branch
    detach="--detach"
fi

and later:

git switch $detach $switchname

for instance.

There's a flaw in the above: if you are on an unborn branch, git symbolic-ref -q --short HEAD will produce the branch name, but git switch won't be able to switch to it. It's probably wise to run both git symbolic-ref and git rev-parse HEAD so as to detect the unborn branch case.

Related