如何列出特定分支的所有基于任何提交创建的 Git 分支

3

有几个问题与我提出的问题很接近,但并不完全相同。

我想列出所有分支,这些分支是在一个 git 分支的历史记录中的任何时间创建的。

类似问题的答案包括使用 git branch --contains [branch-name],但这并没有实现我的目标。

考虑以下(简单)示例和树形结构:

$ git init
$ git checkout -b master
$ touch master.txt
$ git add .
$ git commit -m "Initial master commit"
$ git checkout -b develop
$ touch develop.txt
$ git add .
$ git commit -m "Initial develop commit"
$ git checkout -b feature/a
$ touch a.txt
$ git add .
$ git commit -m "feature/a commit"
$ git checkout develop
$ git checkout -b feature/b
$ touch b.txt
$ git add .
$ git commit -m "feature/b commit"

master
      \
       \         feature/a
        \       /
         develop
                \
                 feature/b

如果我想获取所有包含 develop 分支的分支,可以执行命令 git branch --contains develop,将得到以下结果:

$ git branch --contains develop

  develop
  feature/a
  feature/b

很酷。但是让我们使用一个更实际的例子(-表示提交),其中有多个功能分支在不同时间合并:
$ git checkout develop
$ git merge feature/a
$ git branch -d feature/a

master
      \
       \         feature/a
        \       /         \
         develop           -
                \
                 feature/b

在这种情况下,feature/a 已经完成,合并到 develop 分支后被删除。现在,develop 分支的最新提交已经领先于仍在开发中的 feature/b 分支。现在,如果我运行命令 git branch --contains develop,会得到以下结果:
$ git branch --contains develop

  develop

不好。我想要看到的是developfeature/b两个分支,因为feature/b是从一个旧版本的develop分支派生的。

我的项目比较复杂,有很多功能、修复、增强等分支,它们都是从develop的不同时间点创建的,而且并不是所有的分支都被合并了。现在,git branch --contains develop对于告诉我哪些分支需要处理来说几乎没有用处。

1个回答

4

在写问题时,我意识到答案是什么(感谢能够把想法记录下来)。

git branch --contains develop 命令只考虑了 develop 分支的最新提交,所以你需要获取 develop 分支的第一个提交 SHA。

不幸的是,这就是事情变得棘手的地方。来自《Pro Git § 3.1 Git Branching - What a Branch Is》

Git 中的分支只是指向 [一次] 提交的轻量级可移动指针。

由于分支只是一个轻量级指针,因此 git 没有明确的历史或创建日期概念。

我花了很长时间拼凑出了一个获取分支原始提交 SHA 的方法,但这里有一些前提条件/限制。

  • 您需要知道要获取原始提交 SHA 的分支(在我们的例子中是 develop
  • 您需要知道它要从哪个分支分离出来,而且该分支不能领先于它(在我们的例子中是 master)- 这绝对不是理想情况,但欢迎任何人提供更好的答案 :)
$ git branch --contains $(git rev-list master..develop | tail -1)

  develop
  feature/b

如果你感到好奇,$() 中的内容是我从git rev列表中获取最早提交SHA的方式(得益于 @alfunx 的评论,这比原来的方法更好)。


2
你可以用 git rev-list master..develop | tail -1 替换 $() 中的命令。 - alfunx
谢谢@alfunx!这样就简单多了 :)(回答已更新) - MandM

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