Git 日志列表提交不包括从第一个分支中精心挑选的内容

ahm*_*hmy 3 git github

例如我有这个提交历史记录

git 历史记录 在此输入图像描述

假设在某个时候release1发布到生产环境,几天后,release2分支发布了。

  • 分支relase1包含从 master 精心挑选的 2 个提交(4 和 5)
  • 分支release2包含 2 个提交(8 和 9),也是从 master 中精心挑选的。

择优挑选永远不会因为-x争论而结束。

我想要获得release2“当时尚未发布”的所有提交,这意味着由绿色圆圈标记的提交(6,7,8,9)。

做到这一点最简单的方法是什么?

github中的存储库示例

更新1(git樱桃)

$ git cherry -v release1 release2
- 91785f2be363244a1da4459746fce6a6ea28c2b5 4
- e88de1f8b62213089b300e3143c4caf509b5c13b 5
- 9d23e9c7e6f769c3bbb44ad42bc7b708b4b0a9e6 6
- 6fb71e4406e0b127e06f6e5b145de8a9d39db01e 7
- 6276becc413494b7724a4dd8b852234f4b71e913 8
- 6dd3b5b75222c02c921c9c20bcaee83e1c8be746 9
Run Code Online (Sandbox Code Playgroud)

有了cherry,似乎我仍然得到了 4 和 5,它们都是 form master

更新 2(--左-右--cherry-mark)

$ git log --left-right --cherry-mark --pretty=oneline --abbrev-commit  release2...release1
= 6dd3b5b 9
= 6276bec 8
> caa4e2f 5
= 0230a1f 4
= 6fb71e4 7
= 9d23e9c 6
= e88de1f 5
= 91785f2 4
Run Code Online (Sandbox Code Playgroud)

这给了我一切,除了 5 是樱桃标记的,我很难解释这一点

带有非空提交的更新 3

在最初的尝试中,我使用--allow-empty. 如下所示,它创建了空树的哈希值。

用真实内容重新创建存储库后,我得到了想要的结果,答案git cherry如下--left-right --cherry-mark

tor*_*rek 5

请注意,您的链接存储库包含 15 个完全空的提交。我所说的“空提交”不仅仅意味着git commit --allow-empty允许的那种无更改提交,而是完全空的:每个提交根本没有文件,只有一条提交消息。(更准确地说,每个提交都将空树4b825dc642cb6eb9a060e54bf8d69288fbee4904作为其树。)因此,存储库中的每个提交的补丁 ID 等于存储库中的每个其他提交。

\n\n

这(主要)解释了为什么你的 update-2 部分显示了它的输出: commit6dd3b5b与 commits 6276bec9d23e9c等等补丁等效。令人困惑的是为什么提交caa4e2f不与另一个提交配对,因为它也与每个其他提交是补丁等效的。无论如何,这几乎是一个误报的例子,但这里它实际上更像是一个真正的肯定:这些提交都是相同的,因此可以被丢弃而不会产生任何影响。

\n\n
\n\n

Git 的修订遍历命令(git loggit rev-list)可用于git patch-id标记补丁等效提交。这并非万无一失,但如果在没有手动干预的情况下精挑细选提交,则副本和原始版本的补丁 ID 将匹配。

\n\n

要了解如何使用它,请查看或文档git loggit rev-list(有关此部分的部分在两组文档中共享\xe2\x80\x94,因为是底层实现\xe2\x80\x94,所以我只链接到一个)跳至有关--left-right选项的部分。请注意,--left-right 只有与对称差异结合时才有意义,在这种情况下意味着使用语法release1...release2release2...release1。请注意,此处两个名称之间有三个而不是两个点。

\n\n

使用三个点 和--left-right,Git 将枚举可从 访问的提交 5 和 4 release1,以及可从 访问的两个不同的提交 5 和 4 release2。(当然,Git 会首先枚举可从 到达的提交 9、8、7 和 6 ,然后再枚举可从 到达但不可release2到达的提交 5 和 4。如您所见,调用这些提交可能是错误的四个不同的提交具有相同的两个名称。它们具有不同的哈希 ID 是有原因的:它们是不同的提交。如果您愿意,可以将它们称为“ and ”和“ and” ,或者可能添加“ and”来添加版本号,但给它们不同的名称!)release2release15A5B4A4B5.15.2

\n\n

到目前为止,这还没有多大帮助:Git 显示您从 提交了 5.1 和 4.1 release1,标记为<>取决于名称release1所在的三个点的哪一侧。而且,Git 显示您从 提交了 9、8、7、6、5.2 和 4.2,并release2用另一个标记进行了标记。但这是最重要的起点。现在,您可以从 切换--left-right--left-only--right-only,告诉 Git不要向我显示这两组中的一组,即使您仍在枚举所有提交。

\n\n

无论有或没有仅左或仅右选项,您都可以添加--cherry-mark, 来告诉 Git:在两组中的每次提交上运行。git patch-id当左侧集中的提交与右侧集中的提交具有相同的补丁 ID 时,请使用等号标记该提交=。否则,用加号标记提交+

\n\n

因此,在这种情况下,如果您运行:

\n\n
git rev-list --left-right --cherry-mark --abbrev-commit release2...release1\n
Run Code Online (Sandbox Code Playgroud)\n\n

你会看到(假设提交 9 的哈希 ID 以999999等开头):

\n\n
<9999999\n<8888888\n<7777777\n<6666666\n=5200000\n=4200000\n=5100000\n=4100000\n
Run Code Online (Sandbox Code Playgroud)\n\n

因此,您想要的提交正是那些标记为 的提交<。使用release1...release2,您想要的提交正是那些标记为 的提交>

\n\n

假设以上所有内容都有意义,现在请阅读本--cherry-pick

\n\n

请注意,如果您在挑选时必须解决冲突,则原始提交及其副本的补丁 ID将不匹配此过程不会省略此类提交。也有可能得到错误的匹配。这种情况往往发生在仅包含移动一些左大括号和右大括号的修复中:补丁 ID 不仅是通过去除行号,而且还去除空格来形成的。因此,减少对补丁 ID 的两个不同(通过缩进和行号)大括号更改提交会折叠应该不同的提交。因此,我在顶部的声明并不是万无一失的:您可能会得到误报(合并冲突已解决的精挑细选)误报(实际上不同的合并提交)。

\n