"git cherry" 将已经挑选好的提交显示为 "ready to be applied"

"git cherry" shows an already cherry-picked commit as "ready to be applied"

我一直在处理分支 align 并希望从中挑选一些提交到 master。 我使用 git cherry 来查找候选提交:

C:\Users\me\Documents\repo>git cherry -v master align | head -1
+ c2bbb3d99440be7524673702c92ad65e6522d2b1 Made RW_assert() work on 64-bit.

我的理解是“+”表示 master 上没有等效的提交。 但我记得已经挑选了 master 的提交。 事实上,这是分支 align:

上对文件 rw-fwd.h 的最新更改
C:\Users\me\Documents\repo>git log align -1 rw-fwd.h
commit c2bbb3d99440be7524673702c92ad65e6522d2b1
Author: Me
Date:   Thu Jun 8 10:41:01 2017 +1000

    Made RW_assert() work on 64-bit.

并且仍然是分支 master:

上对 rw-fwd.h 的最新更改
C:\Users\me\Documents\repo>git log master -1 rw-fwd.h
commit 5bc790b9b0adfcdc6c0a07b679155e33974e343a
Author: Me
Date:   Thu Jun 8 10:41:01 2017 +1000

    Made RW_assert() work on 64-bit.

git cherry 的文档指出:"The equivalence test is based on the diff, after removing whitespace and line numbers. git-cherry therefore detects when commits have been "通过 git-cherry-pick[1]、git-am[1] 或 [复制” =67=]-变基[1]。” 在视觉上,使用 git show,提交看起来是一样的,但我们绝对确定:

C:\Users\me\Documents\repo>git show c2bbb3d | git patch-id
f6ad0912fd71f694b6b00c6ea93c87af7cf4ab98 c2bbb3d99440be7524673702c92ad65e6522d2b1

C:\Users\me\Documents\repo>git show 5bc790b | git patch-id
f6ad0912fd71f694b6b00c6ea93c87af7cf4ab98 5bc790b9b0adfcdc6c0a07b679155e33974e343a

补丁 ID 相同。为什么 git cherry 没有检测到此提交已经被精心挑选?

编辑: 下面是经过清理的 git 日志 --oneline --decorate --graph. 我添加此内容是为了回应@torek 的回答,不是因为我怀疑答案是否正确,而是因为我希望根据该回答帮助解释真实的提交日志。

master 位于 a52f43e(第一行),align 位于 9ffa94e(第三行)。 align 是图表中最右边的线,一直向下,未合并。

* a52f43e ######## ############ #####
* 507e731 ##### ##### ### ## ###
| *   9ffa94e (origin/align) Merge branch 'master' of https://ghe/repo/repo into align
| |\
| |/
|/|
* |   657d6c8 Merge pull request #8 from repo/test_system
|\ \
| * \   679739b Merged origin master into local branch.
| |\ \
| |/ /
|/| |
* | |   c7a5944 Merge branch 'master' of https://ghe/repo/repo
|\ \ \
| * \ \   e12016c Merge pull request #7 from repo/lean-mean
| |\ \ \
| | * | | 144fefd ##### ####### ##### ## #######
| | * | | 87e0e23 ####### ############## ## ####### ####### ...
| * | | | 8613f4e ######## ####### ######### ## ###### #####...
| |/ / /
* | | | 8f70a8d ######### #### ##### ### ###### ### ########...
* | | |   aedb306 Merge branch 'master' of https://ghe/repo/repo
|\ \ \ \
* \ \ \ \   0a4fd59 Merge branch 'master' of https://ghe/repo/repo
|\ \ \ \ \
* \ \ \ \ \   e1cfbfd Merge branch 'PBA_Experiment' of https://ghe/repo/repo
|\ \ \ \ \ \
| * | | | | | 7f1bc5b (######/##############) ##########
| | | | | * | 323d965 ######## ######### ####### ########.##...
| | | | | * | 5839749 ##### #######-#### ###### ## ### ## ##...
| | | | | | * d96ba71 ##-####### ############, ## ##### ####...
| | | | | | * 680354b #### ##### ######### #####, ##-###### ...
| | | | | | * a066e66 #####.  ### ### ###### ########## ####...
| | | | | | * afb7945 (###: ####-##-##-#######, ###: ####-##...
| | | | | | *   a14e769 Merge remote-tracking branch 'origin/master' into align
| | | | | | |\
| | | | | |_|/
| | | | |/| |
| | | | * | |   4354de6 Merge pull request #5 from repo/tech-bug-fixes
| | | | |\ \ \
| | | | | * | | c084aa8 (######/####-###-#####) ##### ######...
| | | | | * | | aea8a4f ######### ###-######## # ###### ### ...
| | | | | * | | 7857c95 ### #### #############, ### ### ####...
| | | |_|/ / /
| | |/| | | |
| | | | * | | 0b65102 .
| | | | * | |   2448af9 Merge branch 'master' of https://ghe/repo/repo
| | | | |\ \ \
| | | | * | | | 04c03da ##### ##### ###### ## ###### #######...
| | | | | | | * e05b167 ###### ### ## ######### ##########, ...
| | | | | | | * c3422d5 ##### ###############() ###### ## ##...
| | | | | | | * 92f4eff ##### ### ## ######/######### ####-#...
| | | | | | | * 35fb291 ### ################## (##### ######...
| | | | | | | * 6d12b2c ##### # ####### ## ######### #-###-#...
| | | | | | | *   aa84d37 Merge branch 'master' into align
| | | | | | | |\
| | | | | | |_|/
| | | | | |/| |
| | | | | * | | a96cb9d ##### #### ##### ######## ### ##### ...
| | | | |/ / /
| | | | * | | 911e5d2 ######## ### ##### #########.
| | | |/ / /
| | | * | |   d32ef9a Merge pull request #4 from repo/tech
| | | |\ \ \
| | |/ / / /
| | | * | | 092858f (######/####) ######## #### ## ######.
| | | * | | 1d862dd ##### ############ ## #### ### ### #### ...
| | | * | |   7eae069 Merge branch 'master' into tech
| | | |\ \ \
| | | |/ / /
| | |/| | |
| | | * | | f639a00 ##### ##### ## ### ########
| | | * | | ac794d9 ##### ################ ###### #### #####...
| | | * | | b0296ac ####### ########## ## ####### #### ## ##...
| | | * | | 91f2adf ###########
| | | * | | 47ae5eb ######
| | | * | | a975c46 ####### ##### ## #########
| | | * | |   041a552 Merge branch 'tech' of https://ghe/repo/repo into tech
| | | |\ \ \
| | | | * | | 908b8f7 ######
| | | | * | |   85ff704 Merge branch 'tech' of https://ghe/repo/repo into tech
| | | | |\ \ \
| | | | * | | | 6351c83 ######
| | | * | | | | 1486296 ###### #### ########.
| | | | |/ / /
| | | |/| | |
| | | * | | | 89cefd9 ######### ############# #### ### #####...
| | | |/ / /
| | | * | | 401b346 ### ########## ## ######### ######### ##...
| | | * | |   0e36458 Merge branch 'tech' of https://ghe/repo/repo into tech
| | | |\ \ \
| | | | * | | 7029347 ######
| | | | * | |   d819996 Merge branch 'tech' of https://ghe/repo/repo into tech
| | | | |\ \ \
| | | | * | | | 1d11d8a ######
| | | | * | | |   0f52244 Merge branch 'tech' of https://ghe/repo/repo into tech
| | | | |\ \ \ \
| | | | * | | | | 63f49c3 ######
| | | * | | | | | 15e0017 ######
| | | | |_|/ / /
| | | |/| | | |
| | | * | | | | a7c00b8 ######### ## ### #### ### #### ####
| | | | |/ / /
| | | |/| | |
| | | * | | | 5074fe5 ####### ## #### ########## ###### ## #...
| | | |/ / /
| | | * | | 989e68c ####### ## ### #### ### #### #### ####, ...
| | | * | |   9b3545c Merge branch 'tech' of https://ghe/repo/repo into tech
| | | |\ \ \
| | | | * | | 2a9f6b2 ##### #### ## ######## ######### #####...
| | | * | | | 519ac87 ######
| | | |/ / /
| | | * | | e850bac ######
| | | * | | 7e920c4 ######### ## ### #### ### ####### ### ##...
| | | * | | ac4608d ######## ## #### #### ########### ## ###...
| | | * | | f7f4e0c ###### ##-######### ## ###### ## ## ####...
| | | * | | 7ed258f ##### ######## ## ###### ##### ##### ###...
| | | | | * 67c8f71 ##### ### ## ######### ######## ########...
| | | | | * 2280a88 ##### ######### ### #### ### ##########
| | | | | * 3bd5b85 ##### # ### ## ##-######; ## ##### #####...
| | | | | *   7919cc3 Merge branch 'master' into align
| | | | | |\
| | | |_|_|/
| | |/| | |
| | * | | | 7278053 ##### #### ####### ##########.
| |/ / / /
|/| | | |
| | | | * 31d1e44 ##### # ### ### ### ######### ## ###### ##...
| | | | * 87f8195 ######## ### ### ###### ##### ####### ####...
| | | | * 379bd4a ### '#' ### ## #### # #### ### ####### ###...
| | | | * fe30105 ##### ######### ###### ##### ## ###### ###...
| | | | *   3b50f20 Merge branch 'master' of https://ghe/repo/repo into align
| | | | |\
| |_|_|_|/
|/| | | |
* | | | |   48ca2d6 Merge branch 'master' of https://ghe/repo/repo
|\ \ \ \ \
| |/ / / /
| * | | |   edbf46e Merged from align
| |\ \ \ \
| * | | | | af282b8 ##### ###### ### ######### ### ## .#####...
| * | | | | 2237855 ####### ### ######### ### #### ##### ## ...
| * | | | | f0711d9 ##### ###################() ### ########...
| * | | | | 5bc790b Made RW_assert() work on 64-bit.
* | | | | | c53aad5 ##### ######## ### ######## ####### ### ...
* | | | | | 1b4f135 ##### ####### #### #### ### ######-#####...
| | | | | * 49730f3 #####, ### ######, ## ###### ######## ##...
| | | | | * 8efc11e ##### ###### ### ######### ### ## .#####...
| | | | | * e0f583a ####### ### ######### ### #### ##### ## ...
| | | | | * 3b1a263 ##### ###################() ### ########...
| | | | | * c2bbb3d Made RW_assert() work on 64-bit.
| | | |_|/
| | |/| |
| | * | | 67154d6 ##### ##### ####### ### ####. ######### ##...

查看上面日志的底部,c2bbb3d 是对 align 的初始提交,5bc790b 是对 master 的提交的 cherry-pick。我希望 67154d6 是共同祖先,那是 git cherry 停止输出的地方。

我仍然无法回答的问题是,我如何才能获得对 align 所做的提交列表,这些提交尚未在 master 上?似乎任何可以从 align 访问但不能从 master 访问的提交都是候选者,只要它还没有被挑选到 master。任何馈入 master 的分支都必须进行精选检查——包括图表中的每个分支,最右边的分支 align.

除外

注意:我们使用 git 才几个月,所以我很确定我们正在做的很多事情都不是最佳实践。我们从反复试验中学到了很多东西。

让我把新添加的额外问题放在最上面,因为它实际上更重要,也更容易回答:

The question I still can't answer is, how could I get a list of commits made to align, which are not already on master?

你可以通过 git rev-list(用于计算机)或 git log(用于人类)的输出得到它:

align ^master

作为两个约束。 (小提示:git rev-listgit log 本质上是相同的命令,区别在于 git rev-list 旨在进一步处理,因此它默认只生成完整的哈希 ID , 而 git log 是针对人类阅读的,所以它默认显示提交。关于 方式 git log 显示了一些小而重要的细节提交,但对于 --oneline 输出,它们在这里无关紧要。)

这些约束告诉 Git 修订列表遍历器:查找 "on" 的提交——意思是 "reachable in a walk through history starting from"——名称指定的提交 align,但从该列表中排除所有 "on" master. 鉴于上图,此提交列表相当长。

这种特殊形式,yes ^no,可以拼写为 no..yes,给出更熟悉的缩写形式:

git log --decorate --oneline --graph master..align

(注意这个表格有两个点)。我已经包含了 DOG、装饰单线图选项,因为对于这个特殊目的,友好的狗通常很有帮助。1

如果你颠倒名字——git log align..master——你会得到,在这种情况下,两个提交在 master 上而不在 align.

这也是-点或对称差形式所处理的:当我们写master...alignalign...master,如下面的原始答案所示,我们告诉 Git 产生 both 这些行走。一个找到在 master 上但不在 align 上的提交(只有两个),另一个找到在 align 上但不在 master 上的提交(很多) .

当我们将这种三点对称差分形式与git rev-list(或git log)一起使用时,我们可以告诉Git标记输出以显示提交来自哪一方。该标记甚至可以使用 git patch-id 来查找两侧相同的提交。但它不会查看双方未选择的任何提交,特别是,当您将其拆分为 --left-only--right-only 时,您可能会丢弃大量数据。 (那些数据点通常是无用的,丢弃它们是好的,但它们并非 总是 无用。)


1对于 git log,我认为几乎一直打开 --decorate 实际上是个好主意。事实上,Linus Torvalds himself got it added to Git back in v2.1.0, but nobody remembered to document it until Git v2.9.0.

真是个好主意

请注意,您在上面添加的图表有些复杂(周围有许多松鼠状的小线 运行),因此有不止一个提交,其中各种线分叉和连接。当您使用 master...alignalign...master 时,修订步行代码会删除 any 可以从 both 起点到达的提交.想象一下打印出日志并使用两个荧光笔。使用一种颜色,您可以从 master 处开始标记,然后为您可以从那里到达的所有线条和星星涂上颜色。使用另一种颜色,您从 align 开始标记,然后为从那里可以到达的所有线条和星星涂上颜色。无论两个突出显示 重叠 ,那些提交都在 both 上;在他们不这样做的地方,这些提交只在一个分支上。

原始答案,关于 git cherry

The patch-ids are identical. Why has git cherry not detected that this commit was already cherry-picked?

git cherry 命令只查看提交图的有限子集。纵观全局,时间太长,收获太少。

我不确定你是如何陷入这种特殊情况的(有不止一种方法可以到达这里),但这里有两种不同的 [Edit: 和 简单的]情况,因为它们可能显示为git log --oneline --decorate --graph align master:

* c2bbb3d (align) Made RW_assert() work on 64-bit.
* xxxxxxx some other commit here
| * 5bc790b (master) Made RW_assert() work on 64-bit.
|/
* yyyyyyy whatever commit here
* zzzzzzz yet another commit
   ... snip ...

或:

* c2bbb3d (align) Made RW_assert() work on 64-bit.
* xxxxxxx some other commit here
| * zzzzzzz (master) yet another commit
|/
* yyyyyyy whatever commit here
* 5bc790b Made RW_assert() work on 64-bit.
   ... snip ...

运行 git cherry master align 将显示提交是多余的,即,不需要 cherry-picking,第一个图 。这样做的原因是 git cherry 仅查看 从两条图形线分叉 .

点开始的图形部分 "extends up"

由于两条图形线在 yyyyyyy whatever commit here 重新连接,该命令从不查看任何提交 "at or below" 那个点。鉴于您声称 c2bbb3d 是 "new",您的图形必须类似于第二个图形,而不是第一个(并且 说它确实如此)。

更准确的定义

更准确地说,git cherry master align 使用 git rev-list --left-right master...align 来识别 align 分支上的提交, 或者 master 分支,但不在 两个 分支上。对于像上面那样的简单图形,这会切断合并基础及其所有父提交。如果图具有更复杂的拓扑结构,则可能有多个合并基础;都被排除在外;恰好那些可以从两个特定提交之一到达的提交被包括在内,并且每个这样的提交在内部被标记为是否从左侧参数到达(master in master...align)或右侧参数(master...align 中的align)。

git cherry 命令——甚至是 git rev-list 命令本身,使用正确的参数——然后为两侧的每个提交计算 git patch-id。这让它可以检测哪些提交是相同的,哪些是不同的。但它从不为对称差异三点语法排除的 any 提交计算补丁 ID。在大型存储库中,这排除了大部分提交,通常这对那些提交无关紧要,因为这些提交已经在两个分支上了。