gitcherry-pick对什么用例有用



最初,我认为gitcherry-pick会对其父级进行diff,生成一个补丁文件,然后将该补丁应用到HEAD上,我认为这更有趣、更独特,而且我还没有在git命令中看到这样做。如果您有一些简单的修复方法,比如希望两个分支生成相同的日志输出,但只在一个分支上修复了它,并且希望cherry-pick这一行的更改并将其应用于另一个分支,以便现在可以比较结果,那么这样的命令可能会很有用。但如果它只是把整个物体带到你的头上,那么我看不出有什么意义。

所以我的问题是,我会使用cherry-pick作为什么用例?因为它似乎只用于提交历史管理(即,不将精心挑选的提交的所有父提交合并到当前HEAD中)。

能够"复制";从一个分支提交到另一个分支,而不必进行合并,也不必手动重做所有编辑。

例如,在您的用例中,假设它不是一行日志输出,而是您在开发分支上进行的一个重要错误修复。现在,对于补丁发布,您希望将此修复程序向后移植到您的发布分支,但显然不希望将开发分支合并到发布分支,因为自发布以来,已经在那里提交了很多内容。你是做什么的?你git cherry-pick

您对git cherry-pick的想法所做的描述与实际所做的足以作为初始描述。(因此,您提出的用例是主要用例。)我们所需要做的就是:

  1. 注意,Git的内部实现使用了Git的合并引擎,因此您有时会看到一个"合并冲突";。在这种情况下,cherry-pack操作在中间停止,要求您解决冲突并使用--continue完成冲突
  2. 请注意,您可能一次选择多个提交:在这种情况下,Git会执行每个选定的提交,一次一个,如注1所示,然后继续下一个提交
  3. 注意,在没有-n的情况下,每个樱桃采摘步骤(a)都要求工作树和索引为"0";"干净";(或多或少与当前提交相匹配),并且被复制的每个提交也将其提交消息复制到新的提交中,从而再次处于这种干净状态;但是对于-n;完全清洁";并且该操作本身不会进行新的提交1
  4. 请注意,这一切都至少有可能使用定序器(执行多个提交),git revert和现代git rebase也是如此,并且定序器一次只能执行一件事,因此,如果您正在进行恢复或重定基,某些用例会受到限制

关于注释,术语object在Git中指的是Git的内部对象存储。有四种对象类型:Blob、树、提交和带注释的标记。blob对象存储任何唯一的文件内容(但不是文件名,也不是其+x与-xchmod状态),这就是Git消除重复文件的方法,这些文件的内容在任何给定的提交集之间共享,甚至在其中共享。树对象存储文件名和模式信息,提交对象存储提交元数据(包括保存快照的树对象的哈希ID),

tag对象Cherry picking将提交视为一个整体,并将父P与子C进行比较,以查看给定的提交对中发生了什么变化。为了将这些更改应用于当前(HEAD)提交,它还比较了PHEAD,这就是它最终使用合并引擎的原因和方式。(对于-n风格的cherry picks,它使用当前索引,而不是HEAD提交。由于非-ncherry ticks要求HEAD和索引匹配,因此它实际上可以始终使用索引。)


1没有适当的、严格的clean定义,并且实际实现往往是特别的:任何需要";清洁状态";进行自己的检查,从而确定对于该特定命令来说,它意味着什么;清洁";。然而,在git-sh-setup中有一个require_clean_work_tree函数,这为正确定义提供了一个很好的起点。注意子模块在这里往往被忽略,这可能并不总是合适的。

cherry-pick是我从未用于永久开发历史的东西。事实上,在过去的几年里,我已经使用过一两次了,但那是因为我们在一个分支上包含了一个提交,然后忘记将其合并到另一个分支;不幸的是,当时我们有三个开发分支,需要保持同步(谢天谢地,现在我们只有一个)。

除非我在某个地方犯了错误,需要以某种方式赶上一个分支,否则我从未将其用于永久的开发历史。

但是,当我对自己的树枝进行临时更改时,樱桃采摘是非常有用的。例如,可以引入一些配置代码,以便在测试某些东西时打开或关闭某些选项。但要么我太懒了(很可能是选项),要么上游集成商不想引入这种复杂性。那我该怎么办?我直接更改代码,然后将更改存储在一个分支中,这实际上只是我可以在需要时挑选的一个提交。然后我不时地将该分支重新设置在上游之上,以解决冲突。最近的一个例子是一些警告日志消息,我想把它们变成一个错误(异常),因为我怀疑我的更改可能会触发这些情况。因此,我只是更改了代码,将提交标记为TEMP,然后继续我的工作。如果这个更改后来被证明是有用的,我可以将该提交转换为一个分支,我可以存储该分支以供以后临时挑选。

要做到这一点,你必须确保临时更改不会与你正在做的工作("实际")更改重叠。否则你就会陷入冲突。

另一种需要考虑的可能性是生活在上游之上(重新建立基础)的长寿命分支,可能是因为上游不会接受它们(所以它们只在您的存储库中)。也许你关心这个分支的历史,所以事情被分成几十个提交。但有时你可能不在乎历史,然后你可以把提交压缩成一个提交,这个提交是基于上游的,或者是经过精心挑选的。