注意你的链接存储库 https://github.com/yulrizka/git-question包含 15 个完全空的提交。我所说的“空提交”并不仅仅指那种无更改的提交git commit --allow-empty
允许,而是完全地空:每个提交根本没有文件,只有一条提交消息。 (更准确地说,每个提交都有空树4b825dc642cb6eb9a060e54bf8d69288fbee4904 https://stackoverflow.com/q/9765453/1256452作为它的树。)所以every存储库中的提交补丁 ID 相当于所有其他提交到您的存储库中。
这(主要)解释了为什么你的 update-2 部分显示了它的输出:commit6dd3b5b
补丁等同于提交6276bec
, 9d23e9c
, 等等。谜题是为什么要承诺caa4e2f
不与另一个配对,因为它也与每个其他提交是补丁等效的。无论如何,这几乎是一个误报的例子,但这里它实际上更像是一个真正的肯定:这些提交are都是一样的,因此可以被丢弃而没有效果。
Git 的修订行走命令(git log
and git rev-list
) 可以使用git patch-id https://git-scm.com/docs/git-patch-id标记补丁等效承诺。这并非万无一失,但如果在没有手动干预的情况下精挑细选提交,则副本和原始版本的补丁 ID 将匹配。
要了解如何使用它,请查看the git log or git rev-list文档 https://git-scm.com/docs/git-log(关于此的部分在两组文档中共享 - 正如底层实现一样 - 所以我只链接到一个)。跳下至的部分--left-right option https://git-scm.com/docs/git-log#Documentation/git-log.txt---left-right。注意--left-right
仅当与对称差结合时才有意义,在本例中意味着使用语法release1...release2
or release2...release1
。请注意,有three,不是这里两个名字之间的两个点。
使用三个点和--left-right
,Git 将枚举可从以下位置访问的提交 5 和 4release1
,以及可从以下位置访问的两个不同提交 5 和 4release2
。 (当然,Git 首先会枚举可从以下位置访问的提交 9、8、7 和 6:release2
,在枚举可到达的 5 和 4 之前release2
但不是release1
。正如您所看到的,用相同的两个名称来调用这四个不同的提交可能是错误的。它们具有不同的哈希 ID 是有原因的:它们是不同的提交。给他们打电话5A
and 5B
and 4A
and 4B
如果你喜欢,或者也许5.1
and 5.2
添加版本号,但给它们不同的名称!)
到目前为止,这还没有多大帮助:Git 显示您提交了 5.1 和 4.1release1
,标记为<
or >
取决于名称在三个点的哪一侧release1
已开启。并且,Git 显示您提交了 9、8、7、6、5.2 和 4.2release2
,用另一个标记标记。但这是最重要的起点。您现在可以从--left-right
to --left-only https://git-scm.com/docs/git-log#Documentation/git-log.txt---left-only or --right-only
,告诉 Gitdon't show我是两组中的一组,即使您仍在枚举所有提交。
无论有或没有仅左或仅右选项,您都可以添加--cherry-mark https://git-scm.com/docs/git-log#Documentation/git-log.txt---cherry-mark,告诉 Git:Run git patch-id
在两组中的每次提交上。当左侧集中的提交与右侧集中的提交具有相同的补丁 ID 时,请使用等号标记该提交=
。否则,用加号标记提交+
.
因此,在这种情况下,如果您运行:
git rev-list --left-right --cherry-mark --abbrev-commit release2...release1
你会看到(假设提交 9 的哈希 ID 开头为999999
, etc):
<9999999
<8888888
<7777777
<6666666
=5200000
=4200000
=5100000
=4100000
所以你想要的提交正是那些标记为<
。使用release1...release2
,您想要的提交正是那些标记为>
.
假设以上所有内容都有意义,现在阅读--cherry-pick section https://git-scm.com/docs/git-log#Documentation/git-log.txt---cherry-pick.
请注意,如果您在挑选时必须解决冲突,则原始提交及其副本的补丁 IDwon't匹配。这样的提交won't被这个过程省略。也有可能得到错误的匹配。这种情况往往发生在仅包含移动一些左大括号和右大括号的修复中:补丁 ID 不仅是通过去除行号,而且还去除空格来形成的。因此,减少对补丁 ID 的两个不同(通过缩进和行号)大括号更改提交会折叠提交should有所不同。因此,我在顶部的声明并不是万无一失的:您可以获得两个误报(合并冲突已解决的樱桃选择)and误报(实际上不同的合并提交)。