如何获取未合并到主分支的分支列表,并按最近提交的顺序排序?

11
对于我们的Buildbot,我希望显示最近更新的活跃(未发布)分支。假设我有一个master分支,以及以下分支,从最旧到最新的提交:
  • branch1(未合并到master
  • branch2(已合并)
  • branch3(未合并)
我能够单独获取每个列表...例如获取所有未合并到master的分支:
$ git branch -r --no-merged origin/master
origin/branch1
origin/branch3

或者获取最近提交的前十五个分支(通过https://coderwall.com/p/ndinba):

$ git for-each-ref --sort=-committerdate --format='%(committerdate:short) %(refname:short)' --count=15 refs/remotes/origin/
2013-03-22 origin/branch3
2013-03-22 origin/branch2
2013-03-22 origin/master
2013-03-22 origin/branch1

所以我基本上想要第二个列表,减去branch2(带或不带master)。希望这样说明白了?

随着git 2.7(2015年第四季度),git for-each-ref --no-merged master refs/heads/将成为可能!请参见我下面的答案 - VonC
3个回答

14

你可以像这样将它们结合起来:

git for-each-ref --sort=-committerdate --format="%(committerdate:short) %(refname:short)" --count=15 $(git branch -r --no-merged origin/master | sed -e 's#^ *#refs/remotes/#')

那将会限制只有 branch --no-merged 报告的分支被处理在 for-each-ref 中...

编辑:在实际测试后,修正了 git branch 输出的格式...


不确定那个消息来自哪里 - 命令行中不包含 >... 无论如何,在实际尝试后,我稍微更新了命令。 - twalberg
嗯...在我的git 1.7.11.4和1.8.2上运行良好。你是否设置了一些可能会干扰的git别名?如果没有,请先测试git branch ... | sed ...部分,并确保它只返回refs/remotes/origin/somebranch行... - twalberg
3
啊哈!找到问题了:git branch ...返回了一行带有 origin/HEAD -> origin/branchName 的内容。这个命令可以解决问题:git for-each-ref --sort=-committerdate --format="%(committerdate:short) %(refname:short)" --count=15 $(git branch -r --no-merged origin/deployed | grep -v HEAD | sed -e 's#^ *#refs/remotes/#') - Aidan Feldman
在这里添加了 dotfiles 的解决方案:https://github.com/afeld/dotfiles/commit/2547f591b8fac3d1cca3dd9dbf97be0d84a649a9 - Aidan Feldman
叹气 我希望 StackOverflow 在答案中的内联代码上有一个复制按钮。在触摸板上复制那个水平滚动条框中的长行有点困难。 - SteveExdia

1

从 git 2.7 版本开始(2015年第四季度),git for-each-ref 命令将支持 --no-merged 选项。

git for-each-ref --no-merged master refs/heads/

使用文档:
--no-merged [<object>]:

仅列出参考文献,其提示不可从指定提交(如果未指定,则为HEAD)到达。



请参阅 提交 4a71109, 提交 ee2bd06, 提交 f266c91, 提交 9d306b5, 提交 7c32834, 提交 35257aa, 提交 5afcb90, ..., 提交 b2172fd (2015年7月7日),以及由Karthik Nayak (KarthikNayak)于2015年7月9日提交的提交 af83baf
(由Junio C Hamano -- gitster --提交 9958dd8中合并,2015年10月5日)

一些"git tag -l"和"git branch -l"的功能已经被添加到"git for-each-ref"中,以便最终可以在后续的一系列或两个过程中在所有三个功能中共享统一的实现。
* 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  

在Git 2.29(2020年第四季度),列出引用的 "git for-each-ref"(man) 和相关工具过去只允许使用一个--merged--no-merged来筛选它们;现在它们学会了同时使用这两种类型的筛选。

请参见 commit b59cdffcommit a1b19aa(2020年9月18日),以及由Aaron Lipman (alipman88)提交的commit 21bf933commit 415af72commit b775d81
(由Junio C Hamano -- gitster --commit 26a3728中合并,2020年9月22日)

ref-filter:允许使用 mergedno-merged 过滤器

签署者:Aaron Lipman

Enable ref-filter to process multiple merged and no-merged filters, and extend functionality to git branch(man) , git tag git(man) and for-each-ref.
This provides an easy way to check for branches that are "graduation candidates:

$ git branch --no-merged master --merged next

If passed more than one merged (or more than one no-merged) filter, refs must be reachable from any one of the merged commits, and reachable from none of the no-merged commits.

filters现在在其手册页面中包括:

当组合多个--merged--no-merged过滤器时,只显示可从至少一个--merged提交和没有任何--no-merged提交到达的引用。

注意:同样的Git 2.29(2020年第四季度)添加了一个热修复。

查看 提交 5336d50(2020年9月26日),由René Scharfe(rscharfe进行。
(已合并Junio C Hamano -- gitster --提交03b0198中,2020年10月4日)

ref-filter:修复reach_filter()中的内存泄漏

签名作者:René Scharfe

21bf933928("ref-filter: 允许合并和未合并的过滤器",2020年9月15日,Git v2.29.0 -- merge批次#16中列出)在reach_filter()中添加了一个早期返回。
通过推迟数组的分配,避免泄漏未使用的数组的内存,直到我们知道我们需要它。


1

你能否仅使用grep命令过滤出branch2?

基本上,就像这样:

for branch in `git branch -r --no-merged origin/master`; do git for-each-ref --sort=-committerdate --format='%(committerdate:short) %(refname:short)' --count=15 refs/remotes/origin/ | grep $branch; done;

鉴于您的示例输出,该方法对我有效。


grep:正则表达式太大。哈哈 - Aidan Feldman
74,哈哈。需要清理掉其中的一些。 - Aidan Feldman
好的,没问题。为了你这个巨大的情况做了修改。 - spitzanator
可以工作!但可能返回少于15个结果,并且比@twalberg的解决方案慢一些。此外,与那个解决方案类似,必须从“git branch…”中删除origin/HEAD -> origin/branchName行。感谢所有的帮助! - Aidan Feldman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接