仅显示 git-branch 上的 ahead-commits 与另一个分支相比是 ahead+behind

display only the ahead-commits on git-branch that is ahead+behind compared to another branch

我最近继承了一个 git(hub) 存储库

我设法重新创建了整个 git 存储库的最新版本 并在一条直线上创建了一个包含所有相关提交的新分支 (而不是有一个提交和分支的结)。 让我们称这个分支为 Mr.Branch.

Mr.Branch 运行所有(单元)测试并在用于构建核心的 cmake 和用于构建使用核心的应用程序的嵌入式 IDE 中编译良好。 还在目标嵌入式设备上测试了正确的功能。

old/previous 个分支仍然存在。 在删除它们之前,我想确保这些分支中的所有必要内容实际上都是 Mr.Branch.

的一部分

可能更新了文档内容或添加了新的测试。现在,我有机会错过这些变化。 但是,与 Mr.Branch 相比,其他分支通常落后 200 次提交,提前 3 次提交。

是否有一个选项可以找出分支在 Mr.Branch 之前的提交并以某种方式忽略后面的提交?

如果可能的话,我不想使用变基,因为有很多冲突,我将不得不多次解决相同的冲突(因为分支相互合并)

TL;DR

使用两点表示法,A..BB..A。在您的情况下,这将是 git log Mr.Branch..somebranch.

这里有两种查看一些提交图片段和两个标签A和B的方法:

          o--...--o   <-- A
         /
...--o--*
         \
          o--...--o   <-- B

在这种情况下,... 部分可以包含任意数量的提交,但它们之间不会交叉连接,因此 * 是第一个共享提交。

或:

          o--...--*--...--o   <-- A
         /        :
...--o--o         :
         \        :
          o--...--*--...--o   <-- B

其中存在某种交叉连接,因此两个 * 都在两个分支上,之后有更多提交。

在这两种情况下,较旧的提交都在左边;较新的提交在右边。提交 link 向后—Git 从某个标签开始,然后向左提交—因此在 加星标的提交或提交之后提交仅 可从两个标签之一访问

如果您 运行 git log Agit log B,Git 将从标记的提交(分别为 A 或 B)开始并向左工作。一旦到达 both 分支上的提交,您也会看到来自其他分支的提交。在顶部的简单情况下,很明显为什么两个提交都在两个分支上:那是开发分叉的地方,所以当我们及时倒退时,这就是开发重新加入的地方。

在混乱的合并案例中,为什么这些提交在两个分支上可能不太明显。此问题最常见的变种出现在“criss-cross merge”:

       A1---M1--...--An   <-- A
      /  \ /
...--o    X
      \  / \
       B1---M2--...--Bn   <-- B

在这里,有人将提交 B1 合并到分支 A 以生成合并 M1,而某人(可能是其他人,因为这更有可能)将提交 A1 合并到分支 B 以生成合并 M2。提交 A1 通过从 Bn 开始的路径在分支 B 上,通过 Bn-1、Bn-2 等回到 M2,然后到达 M2 的 A1 父级。发生这种情况是因为当 Git 命中合并时,它会转到 both 父级,而 M2 的两个父级是 A1 和 B1。

同样,提交 B1 通过合并 M1 在分支 A 上。尽管如此,在 A 和 B 上都有 在另一个分支上 没有的提交。

当您要求 Git 以某种方式 比较 A 和 B 时,某些命令会告诉您有多少提交“在”(可从)名称上A 但不是“在”(可从)名称 B 上作为 A 的 ahead 计数。例如,使用简单的情况:

       A1--A2--A3--A4   <-- A
      /
...--*
      \
       B1--B2   <-- B

有四个“在 A 上”而不是“在 B 上”的提交:这些都是顶行的所有提交,A1 到 A4。

同时,有两个“在 B 上”的提交不在“在 A 上”:这些都是底线的提交。 (中间线上可能有很多提交。)如果命令给出“落后”计数,这就是它的来源。

两点符号

当您使用双点表示法时,例如 B..A,您告诉 Git:Find commits reachable from不能从左侧名称 B 到达的右侧名称 A。当然,B2 和 B1 可以从 B 到达,但这并不重要:关键是 * 和它之前的所有内容 从 B 可以到达。所以这个 排除 来自 * 的提交,同时保留来自 A 的顶行提交:A4、A3、A2 和 A1。

三点符号

请注意 Git 也有一个 三点符号 ,例如 A...B。这告诉 Git 查看“on”(可从)either 分支名称的提交,不包括“on”both[=122] 的提交=] 分支机构。因此,鉴于上面的最后一张图,这将包括六个提交:A1 到 A4 plus B1 和 B2。请记住,Git 通常是倒着工作的——从右到左,就像以前一样——所以你通常会以其他顺序看到它们(它们可能会混合在一起,因为 Git 也做一些 -提交日期排序)。

同时获取两个计数

从命令行检索一个计数或另一个:

git rev-list --count B..A

和:

git rev-list --count A..B

将分别告诉您 A“领先”B 多远(例如,通过计算 A4、A3、A2、A1 = 4)以及 B“领先”A 多远(通过计算 B2 , B1 = 2).您可以使用以下方法同时获得两个计数:

git rev-list --count --left-right A...B

它会给你“4 2”作为它的输出:A 上的 4 不在 B 上,B 上的 2 不在 A 上。这意味着 A 领先 4,落后 2, B——或者等价地,B 比 A 领先 2 位,落后 A 4 位。

以上适用于许多 Git 命令,但不适用于 git diff

可让您查看提交的 git log 命令使用这些两点和三点语法格式让您查看所需的提交。

我在上面展示的 git rev-list 命令——这是 Git 用于列出提交哈希 ID 的内部主力;许多其他 Git 命令实际上在内部 运行 git rev-list——以相同的方式使用它们。这意味着,例如,您可以给 git cherry-pick A..B 样式的提交范围列表,以将多个提交从一个分支复制到另一个分支。请注意以下事实:在 A..B 中,提交 B 被包括在内,但提交 A 被排除在外。

git diff 命令比较特殊。它对待 A..B 就好像你刚刚写了 A B,而且它对待 A...B 更特别。具体来说,使用 A...B,Git 试图找到我在上面标记为 * 的提交。如果只有一个这样的提交,git diff 将比较 that 提交与 B 提交。通常会有一个这样的提交,一旦你理解了所有这些,这将做你想做的。我终于在 Git 中修复了一个小错误,以修复 git diff 在没有 * 提交或有两个或更多提交时的行为;这应该在下一个 Git 版本中。