Git 列出合并分支的命令

Git Command to List Merged Branches

有没有办法列出已经合并到当前工作树中的b运行分支?以下为关闭:

git branch -r --merged

然而,这也包括空的 b运行ches。例如,在当前 b运行ch 的最新提交之前的某个时刻,我 运行 以下内容:

git checkout -b empty_branch
git push -u origin empty_branch

现在,第一个命令在结果列表中包含 empty_branch。我发现了一个询问 how to find empty branches in git 的相关问题,但接受的答案不适用于没有提交的 b运行ches。有什么方法可以检测 git 中的无提交 b运行ches,或者从 git branch --merged?[=15= 的结果中过滤掉这样的 b运行ches ]

您正在推翻至少一个关于 Git 的错误假设。这不是一个 不合理的 假设,因为 Git 很奇怪,但它让你的整个问题有点偏离。

在 Git 中,分支 names 并不像大多数人认为的那样真正有意义,至少一开始是这样。分支名称只包含一些现有提交的哈希 ID。人们 称为 "a branch" 的底层实体,它由部分或全部提交组成,这些提交可从 提示 到达由分支名称定义的提交。有关(更多)更多信息,请参阅 What exactly do we mean by "branch"? and Think Like (a) Git,但让我们尝试快速总结一下:

  • Git真正的意义在于提交。每个提交都由其自己唯一的哈希 ID 标识。没有其他提交可以拥有这个哈希 ID。提交的内容包括一个快照——从索引中创建,而不是从 work-tree,但我会尽量不在这里涉及所有这些毛茸茸的细节——并包括作者的姓名和电子邮件地址commit,committer相同(一般是同一个人),两个date-and-time-stamps:一个是author,一个是committer。它们还包括提交者在 he/she/they/pronoun-of-choice 提交时提供的日志消息。也许最重要的是,提交的内容包括应被视为该提交的直接前身的任何提交的原始哈希 ID。

  • 换句话说,每个提交都有一组parent哈希ID,最常见的只是一个哈希ID。这些 parent ID 使提交形成 backwards-looking 链:从 last 提交,我们可以返回到上一个提交。从那里,我们可以再返回一步,依此类推。因此,如果像 master 这样的分支名称包含 last 提交的哈希 ID,我们应该将其视为分支的一部分,其余提交是该提交的 parent (s),parent(s) 的 parent(s),等等。如果 master 提示提交的哈希 ID 是 H 并且它的 parent 是 G 并且 G 的 parent 是 F 等等,我们有:

    ... <-F <-G <-H   <-- master
    

    这就是分支:它是名称,或者以 H 结尾的一系列提交,或者两者兼而有之:我们往往不得不猜测某人说 "the master branch" 时的意思.

git branch --merged 所做的是:

  • 找到当前分支的哈希ID(HEAD)。
  • 对于所有分支名称 B 跳过当前分支(从 HEAD 读取) 糟糕:Git 不会 跳过当前分支,这有点烦人:
    • B标识的提交是否为由HEAD标识的提交的祖先?1如果是,打印姓名 B。无论如何,继续下一个名字。

所以如果图表的一部分看起来像:

             I--J   <-- feature2
            /
...--F--G--H   <-- master (HEAD)
      \
       K--L   <-- feature1

与当前提交 H 相比,git branch --merged 将测试的两个提交是 JL。如果 JH 的祖先——但它不是——这将打印 feature2。如果 LH 的祖先——但它不是——这将打印 feature1。当然,HH 的祖先,所以这个 确实 打印 master(带有前缀 * 以表明它是当前分支)。

如果有一个 第四个 名称指向 FGH 或任何提交 "behind" F, git branch --merged 也会打印 那个 名字。

认为你想要的是打印所有指向任何真正祖先提交的名称,而不是任何直接指向提交的名称H.最简单的方法可能是让 git branch --merged 打印所有内容,然后从列表中删除哈希 ID 与 HEAD.

匹配的任何名称

要删除此类名称,请在每个名称上使用 git rev-parse。使用 git rev-parse HEAD 查找当前分支的哈希 ID,即上图中 H 的实际哈希 ID。然后,对 git branch --merged 中的每个名称再次使用 git rev-parse,如果结果与第一个 git rev-parse 相同,则丢弃该名称。否则,保留该名称。

(你将不得不为此编写一些代码。如果 git for-each-ref 可以执行 --not 并组合一些布尔表达式,它可能可以完成,但它没有'不要做 --not 和组合。)


1Git 使用的 is-ancestor 测试允许相等,即它是 ≤ 而不是 <(或者更准确地说,precedes-or-equals , ≼, 对比≺). git merge --is-ancestor.

也是如此