git 脚本:如何列出包含提交的所有 git 分支

git scripting: How to list all git branches containing a commit

我可以列出来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,这是一个瓷器命令,不应该在脚本中使用

后一个问题建议使用管道命令git for-each-ref,但不支持--contains

列出包含特定提交的所有分支的正确管道接口是什么。

一种可能的解决方案是使用管道命令 git-for-each-refgit merge-base(后者由 Joachim 自己建议):

#!/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=

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 $?

脚本可在 GitHub 的 Jubobs/git-aliases 获得。

(编辑:感谢 coredump for showing me 。)

18 个月后更新(2017 年 4 月):随着 Git 2.13(2017 年第 2 季度),git for-each-ref --no-contains <SHA1> 终于得到支持!

参见 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)
(由 Junio C Hamano -- gitster -- in commit d1d3d46 合并,2017 年 4 月 11 日)


原回答

从 git 2.7(2015 年第 4 季度)开始,您将获得更完整的 git for-each-ref 版本,现在支持 --contains

git for-each-ref --contains <SHA1>

与文档:

--contains [<object>]:

Only list tags which contain the specified commit (HEAD if not specified).


参见 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)
(由 Junio C Hamano -- gitster -- in commit 9958dd8 合并,2015 年 10 月 5 日)

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