你不应该在编写脚本时使用 git branch。 Git 提供了一个“plumbing” interface,它明确设计用于脚本(普通 Git 命令的许多当前和历史实现(添加、签出、合并等)使用相同的接口)。
你想要的管道命令是 git for-each-ref:
git for-each-ref --shell \
--format='git log --oneline %(refname) ^origin/master' \
refs/heads/
注意:您不需要远程引用上的remotes/ 前缀,除非您有其他引用导致origin/master 匹配引用名称搜索路径中的多个位置(请参阅the Specifying Revisions section of git-rev-parse(1) 中的“符号引用名称。...”) .如果您想明确避免歧义,请使用完整的参考名称:refs/remotes/origin/master。
你会得到这样的输出:
git log --oneline 'refs/heads/master' ^origin/master
git log --oneline 'refs/heads/other' ^origin/master
git log --oneline 'refs/heads/pu' ^origin/master
您可以将此输出通过管道传输到 sh。
如果你不喜欢生成 shell 代码的想法,你可以放弃一点鲁棒性* 并这样做:
for branch in $(git for-each-ref --format='%(refname)' refs/heads/); do
git log --oneline "$branch" ^origin/master
done
*
引用名称应该不受 shell 的分词影响(参见 git-check-ref-format(1))。就我个人而言,我会坚持使用以前的版本(生成的 shell 代码);我更有信心不会发生任何不适当的事情。
由于您指定了 bash 并且它支持数组,因此您可以保持安全并仍然避免生成循环的内容:
branches=()
eval "$(git for-each-ref --shell --format='branches+=(%(refname))' refs/heads/)"
for branch in "${branches[@]}"; do
# …
done
如果您不使用支持数组的 shell(set -- 用于初始化,set -- "$@" %(refname) 用于添加元素),您可以使用 $@ 执行类似的操作。