试图弄清楚为什么git rev-list的行为不符合我的预期

时间:2013-11-29 21:43:25

标签: git

我有一对分支,掌握和开发,具有共享历史。我运行它来查看只有在开发中而不是在master中存在的提交:

git rev-list --no-merges develop ^master

它给了我一个哈希列表:

2855e2bc0be2b31a1ecc6b1982cb250bce93d160
03c0fa2aa7e7969cd0f0597af3a922a671cbfb67
aa2a8ab2703c648d010377f55ff7e4748e1d9d9a
ee1192481391d4cebaa5787669db985eab445b82
1b02e1f58a464e8f90d13dc61c932cb8cacaec38
ab6b1022f2275e2513c4abf0be9eb8098776771d
0ea538c6791f6581285924c5d95eea929409a834

耶。我将第二个应用于樱桃挑选,如下:

git cherry-pick 03c0fa2aa7e7969cd0f0597af3a922a671cbfb67

我再次运行我的git rev-list。并得到相同的哈希列表。到目前为止,可以预料。然后我用一个新选项运行git rev-list:

git rev-list --no-merges --cherry-pick develop ^master

我仍然得到同样的名单。关于rev-list的页面说的是关于cherry-pick:

Omit any commit that introduces the same change as another commit on the "other side" when the set of commits are limited with symmetric difference.

在该描述和名称本身之间,我的印象是它会忽略列表中任何挑选的提交,但它不是那样做的。我在这里不理解什么?

1 个答案:

答案 0 :(得分:1)

你实际上并没有使用“对称差异”:

   Another special notation is "<commit1>...<commit2>" which is useful for
   merges. The resulting set of commits is the symmetric difference
   between the two operands. The following two commands are equivalent:

               $ git rev-list A B --not $(git merge-base --all A B)
               $ git rev-list A...B

(注意:当它表示“等效”时,它有点过于笼统;只有三点语法设置内部标志,导致--cherry-mark--cherry-pick起作用。)

无论如何,试试:

git rev-list --no-merges --cherry-pick develop...master # or --cherry-mark

您可能还需要--left-only--right-only(您可以交换master并开发以更改左侧vs右侧,但由于它是对称的,无论如何都是纯粹的名义:-))。


如果有人可以在不需要文字对称差异规范的情况下获得git,这可能会很好,因为有时补丁会在合并边界上进行(重新)挑选。例如:

-C-o-o-o-o-o-o    <-- branchA
    \     \
-o-o-m-R-o-M-P-o  <-- branchB

此处branchB已将branchA合并两次,mM。分支C上的提交A已在B提交R时恢复(还原) - 可能brB尚未准备好 - 然后“在第二次合并MB做好准备之后重新选择了。使用实际的樱桃选择进行的“恢复”提交是提交P(选择)。你不能得到git来计算CP的“相同性”,因为branchA...branchBC修剪为“低于”两个合并基础(两个{ {1}}和m)。但只要你不是在寻找 - 而M暗示你不是 - 你应该没事。