提交时`.git/CHERRY_PICK_HEAD`有什么区别?

kjo*_*kjo 5 git cherry-pick git-cherry-pick

注意:这是对我之前的帖子(现已删除)的改写。重新措辞旨在为帖子提供不同的重点。


运行后git cherry-pickgit报告有冲突。我解决了冲突,然后跑了git cherry-pick --continue。此时,$GIT_EDITOR弹出一个COMMIT_EDITMSG缓冲区,其中预先填充了精选提交的原始消息以及一些附加信息,其中包括警告:

# It looks like you may be committing a cherry-pick.
# If this is not correct, please remove the file
#   .git/CHERRY_PICK_HEAD
# and try again.
Run Code Online (Sandbox Code Playgroud)

我检查了如果我“删除”(实际上只是暂时重命名).git/CHERRY_PICK_HEAD文件会发生什么。这产生的直接外部影响是|CHERRY-PICKING从我的git-aware 提示中删除指示。

除了我的提示中的这一变化,以及COMMIT_EDITMSG缓冲区中预先填充的信息可能存在一些差异之外,在有或没有.git/CHERRY_PICK_HEAD文件的情况下执行提交会有什么区别?


更准确地说,我试图在这里比较两种情况。

在第一个场景中,我运行

% git cherry-pick --continue
Run Code Online (Sandbox Code Playgroud)

...并且(无视前面引用的警告)我像往常一样继续提交。

在第二种情况下,我运行

% rm .git/CHERRY_PICK_HEAD
% git commit
Run Code Online (Sandbox Code Playgroud)

...并像往常一样继续提交。

(假设我在两种情况下都使用相同的提交消息。)

这两种情况的最终结果会有什么不同?

tor*_*rek 6

答案取决于你在做什么。Using--continue完成了序列——但如果序列只是一个樱桃挑选,那么无论如何都没有真正的序列。

无论哪种方式,但是,消除.git/CHERRY_PICK_HEAD绝对有额外的一个显著的效果:在完成一个冲突樱桃采摘重新使用原来提交的作者名的电子邮件和日期信息。您始终是任何新提交的提交者,但所有提交都不仅仅是一个人和时间戳:每个新提交都有两个条目,一个用于“提交者”(您,刚刚进行提交),一个用于“作者” "(无论是谁写的原始提交,以及他们何时这样做)。Cherry-pick 保留了原始提交中的作者信息。

音序器

两个git cherry-pickgit revert哪位实际上内部相同的命令; revert 只是“向后工作”——使用 Git 所说的sequencer。也就是说,您可以一次选择多个提交:

git cherry-pick notthis..that thistoo
Run Code Online (Sandbox Code Playgroud)

挑选所有提交“之后” notthis,通过并包括that,以及一个特定的提交thistoo。例如,出于测试目的,您可能决定挑选feature/X从 增长的每个提交develop,加上一个错误修复提交fix-1234

git checkout master
git checkout -b testbranch
git cherry-pick develop..feature/X fix-1234
Run Code Online (Sandbox Code Playgroud)

无论如何,这里的重点是这可能会挑选十几个或更多的提交,并且在此过程中的某个地方可能会出现合并冲突,这需要git cherry-pick停下来寻求帮助。

旁白:这里的模型 - Unix/Linux 命令行 - 是您将命令输入到名为shell的命令解释器中。shell 将人机界面的控制权传递给新命令,新命令会保留它,直到命令完成并退出。一旦命令退出,命令本身就没有任何痕迹:任何永久的东西都必须保存在文件中。

所以:如果樱桃采摘必须停止,它怎么知道从哪里恢复?答案是将信息保存在文件中。如果您正在挑选单个提交,Git 只会保存该CHERRY_PICK_HEAD文件,该文件记录了正在挑选的提交的 ID。但是,如果您要挑选多个提交,Git 会将冲突提交保存为单个提交,并将剩余信息保存在排序目录中(其位置已随时间移动了一些)。

运行git cherry-pick --continue指示(新的,单独的实例)cherry pick 命令从前一个停止的地方开始。Git 将首先git commit为您运行 a ,然后定位排序信息并完成尽可能多的序列,在下一次冲突时再次停止,或者完成所有的挑选。

git commit相反,运行时,Git 会注意到该CHERRY_PICK_HEAD文件并使用该文件,如您所见。当提交完成时,该命令退出并且对定序器不执行任何操作。如果音序器数据留下,你现在可以git cherry-pick --continue:Git会注意到,提交已经完成,只是继续/完成序操作。

请注意,您可以使用git cherry-pick --abort. 这将终止操作并将事情恢复到您开始之前的状态。从 Git 2.19 开始,您可以改为使用git cherry-pick --quit停止(a la --abort),但不能将事情恢复到开始之前的状态。也就是说,它会停止任何未来的挑选操作,而不会撤消您迄今为止所做的操作。(此操作在 2.19 之前缺失。)

git status命令现在会注意到是否有正在进行的序列,并报告您正在执行任何操作。(与 Git 1.7 时代相比,这是一个很大的改进,当时它没有。)