I can list all branches containing a certain commit using git branch --list --contains
just fine. But as explained in the related question on how to list all branches , this is a porcelain command that should not be used in scripts.
The latter question suggests to use the plumbing command git for-each-ref
, but that does not support --contains
.
What is the correct plumbing interface to list all branches that contain a certain commit.
Update 18 months later (April 2017) : with Git 2.13 (Q2 2017), git for-each-ref --no-contains <SHA1>
is finally supported!
See commit 7505769 , commit 783b829 , commit ac3f5a3 , commit 1e0c3b6 , commit 6a33814 , commit c485b24 , commit eab98ee , commit bf74804 (24 Mar 2017), commit 7ac04f1 , commit 682b29f , commit 4612edc , commit b643827 (23 Mar 2017), and commit 17d6c74 , commit 8881d35 , commit b084060 , commit 0488792 (21 Mar 2017) by Ævar Arnfjörð Bjarmason ( avar
) .
(Merged by Junio C Hamano -- gitster
-- in commit d1d3d46 , 11 Apr 2017)
Original answer
Starting git 2.7 (Q4 2015) you will get a more complete version of git for-each-ref
, which now support the --contains
git for-each-ref --contains <SHA1>
With the doc:
--contains [<object>]:
Only list tags which contain the specified commit (HEAD if not specified).
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
One possible solution using the plumbing commands git-for-each-ref
and git merge-base
(the latter suggested by Joachim himself):
#!/bin/sh
# git-branchesthatcontain.sh
#
# List the local branches that contain a specific revision
#
# Usage: git branchthatcontain <rev>
#
# To make a Git alias called 'branchesthatcontain' out of this script,
# put the latter on your search path, and run
#
# git config --global alias.branchesthatcontain \
# '!sh git-branchesthatcontain.sh'
if [ $# -ne 1 ]; then
printf "%s\n\n" "usage: git branchesthatcontain <rev>"
exit 1
fi
rev=$1
git for-each-ref --format='%(refname:short)' refs/heads | \
while read ref; do
if git merge-base --is-ancestor "$rev" "$ref"; then
printf "%s\n" "$ref"
fi;
done
exit $?
The script is available at Jubobs/git-aliases on GitHub.
(Edit: thanks to coredump for showing me how to get rid of that nasty eval
.)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.