Is there a way to find out what branch a commit comes from given its SHA-1 hash value?
Bonus points if you can tell me how to accomplish this using Ruby Grit.
I think someone should face the same problem that can't find out the branch, although it actually exists in one branch.
You'd better pull all first:
git pull --all
Then do the branch search:
git name-rev <SHA>
or:
git branch --contains <SHA>
Aside from searching through all of the tree until you find a matching hash, no.
git branch --contains <ref>
is the most obvious "porcelain" command to do this. If you want to do something similar with only "plumbing" commands:
COMMIT=$(git rev-parse <ref>) # expands hash if needed
for BRANCH in $(git for-each-ref --format "%(refname)" refs/heads); do
if $(git rev-list $BRANCH | fgrep -q $COMMIT); then
echo $BRANCH
fi
done
(crosspost from this SO answer)
Use the below if you care about shell exit statuses:
branch-current
- the current branch's namebranch-names
- clean branch names (one per line)branch-name
- Ensure that only one branch is returned from branch-names
Both branch-name
and branch-names
accept a commit as the argument, and default to HEAD
if none is given.
branch-current = "symbolic-ref --short HEAD" # https://stackoverflow.com/a/19585361/5353461
branch-names = !"[ -z \"$1\" ] && git branch-current 2>/dev/null || git branch --format='%(refname:short)' --contains \"${1:-HEAD}\" #" # https://stackoverflow.com/a/19585361/5353461
branch-name = !"br=$(git branch-names \"$1\") && case \"$br\" in *$'\\n'*) printf \"Multiple branches:\\n%s\" \"$br\">&2; exit 1;; esac; echo \"$br\" #"
% git branch-name eae13ea
master
% echo $?
0
0
.% git branch-name 4bc6188
Multiple branches:
attempt-extract
master%
% echo $?
1
1
.Because of the exit status, these can be safely built upon. For example, to get the remote used for fetching:
remote-fetch = !"branch=$(git branch-name \"$1\") && git config branch.\"$branch\".remote || echo origin #"
This simple command works like a charm:
git name-rev <SHA>
For example (where test-branch is the branch name):
git name-rev 651ad3a
251ad3a remotes/origin/test-branch
Even this is working for complex scenarios, like:
origin/branchA/
/branchB
/commit<SHA1>
/commit<SHA2>
Here git name-rev commit<SHA2>
returns branchB.
To find the local branch:
grep -lR YOUR_COMMIT .git/refs/heads | sed 's/.git\/refs\/heads\///g'
To find the remote branch:
grep -lR $commit .git/refs/remotes | sed 's/.git\/refs\/remotes\///g'