How do I find if a git SHA points to a branch HEAD?

For my case, I wanted to know if HEAD pointed to a branch post-checkout and then exit 0 if pointing to a branch, or exit non-zero if not pointing to a branch, which is most likely detached HEAD state assuming the checkout succeeded. git symbolic-ref --short HEAD does this and also returns the name of the branch when pointing to one. Obviously, there's better solutions for what the OP needs, but I wanted to throw this in just in case anyone wanted to make use of the information.


With the upcoming git 2.7 (Q4 2015) you will get a more complete version of git for-each-ref, which now support the --points-at

git for-each-ref --points-at <branch_name>

With the doc:

--points-at <object>:

Only list refs which points at the given object.

That will allow to check if a commit is part of that list or not.


See commit 4a71109, commit ee2bd06, commit f266c91, commit 9d306b5, commit 7c32834, commit 35257aa, commit 5afcb90, ..., commit b2172fd (07 Jul 2015), and commit af83baf (09 Jul 2015) by Karthik Nayak (KarthikNayak).
(Merged by Junio C Hamano -- gitster -- in commit 9958dd8, 05 Oct 2015)

Some features from "git tag -l" and "git branch -l" have been made available to "git for-each-ref" so that eventually the unified implementation can be shared across all three, in a follow-up series or two.

* kn/for-each-tag-branch:
  for-each-ref: add '--contains' option
  ref-filter: implement '--contains' option
  parse-options.h: add macros for '--contains' option
  parse-option: rename parse_opt_with_commit()
  for-each-ref: add '--merged' and '--no-merged' options
  ref-filter: implement '--merged' and '--no-merged' options
  ref-filter: add parse_opt_merge_filter()
  for-each-ref: add '--points-at' option
  ref-filter: implement '--points-at' option  

You could try something like this:

git for-each-ref --format="%(refname:short) %(objectname)" 'refs/heads/' |
    grep SHA1 | cut -d " " -f 1

That should give you a list of branches that are currently at the revision SHA1.


If you are going to use python, this is what I would do:

import subprocess

def get_name(target):
    p = subprocess.Popen(['git', 'for-each-ref', 'refs/heads/'], stdout=subprocess.PIPE)
    for line in p.stdout:
        sha1, kind, name = line.split()
        if sha1 != target:
            continue
        return name
    return None

Another option is to use the power of eval to construct a dictionary:

d = '{' + subprocess.check_output(['git', 'for-each-ref', '--python', '--format=%(objectname): %(refname),', 'refs/heads/']) + '}'
name = eval(d)[sha1]

Tags:

Git