选择与Git进行提交意味着什么?


Answers:


2854

在Git中进行Cherry采摘意味着从一个分支中选择一个提交,然后将其应用于另一个分支。

这与其他方式形成对比,例如mergerebase通常会将许多提交应用于另一个分支。

  1. 确保您位于要应用提交的分支上。

    git checkout master
    
  2. 执行以下命令:

    git cherry-pick <commit-hash>
    

注意:

  1. 如果您是从公共分支机构摘樱桃,则应考虑使用

    git cherry-pick -x <commit-hash>
    

    这将生成标准化的提交消息。这样,您(和您的同事)仍然可以跟踪提交的来源,并可以避免将来发生合并冲突。

  2. 如果您在提交内容上附加了笔记,则不要遵循这些提示。要将它们也带过来,您必须使用:

    git notes copy <from> <to>
    

附加链接:


246
如果您是从公共分支机构挑选的,则应考虑使用git cherry-pick -x <commit-hash>。这将生成标准化的提交消息。这样,您(和您的同事)仍然可以跟踪提交的来源,并可以避免将来发生合并冲突。
2014年

2
采摘樱桃真的有必要吗?混合重置或软重置不会执行类似的工作吗?
2014年

10
请注意,如果您将注释附加到提交中,则它们不会遵循“挑选”。您还必须使用git notes copy <from> <to>它们。
Zitrax

5
git push是对master进行更改的最后一步
感觉不错,正在编程

58
FYI:一个COMMIT语义包含那一刻的工作树中的所有文件(并提交哈希以前的提交),这样你就不会采用整体提交到另一个承诺,但更改提交做了上一次提交"cherry-pick commit applies the changes introduced by the named commit on the current branch"的大多数ppl倾向于将提交视为更改(例如svn是iirc),但事实并非如此,每个提交都指向完整的工作树。尽管在这种情况下这没有什么区别,但可以帮助您理解git为何如此工作。
Emile Vrijdags '17

314

引用来自: 使用Git进行版本控制 (非常不错的书,如果您对git感兴趣,我建议您购买它)

编辑:由于此答案仍然令人印象深刻,我想在此视频教程中添加一个非常好的内容:

Youtube:Git樱桃简介

使用git cherry-pick命令git cherry-pick commit将在当前分支上应用由命名提交引入的更改。它将引入一个新的,独特的提交。严格来说,使用git cherry-pick不会更改存储库中的现有历史记录;相反,它增加了历史记录。与其他通过diff引入更改的Git操作一样,您可能需要解决冲突才能完全应用给定commit的更改。git cherry-pick命令通常用于将特定提交从存储库中的一个分支引入到另一个分支。通常的用途是将提交从维护分支转发或反向移植到开发分支。

$ git checkout rel_2.3
$ git cherry-pick dev~2 # commit F, above

之前: 之前

后: 后


12
当在某些分支(b1)上进行了精心挑选的提交,然后又交付给master时。并且如果分支b1(最初从中选择提交)也试图传递给master。冲突如何?请问保重或如何工作?
parasrish

3
@parasrish是的,它们已经与您以前的合并一起使用了。因此,您确实更改了(b1)分支的a,b,c,d。您只选择了“ c”。然后,将来从(b1)合并到母版后,由于“ c”更改是相同的,因此它将仅合并a,b,d并保留“ c”更改。但是,如果您回滚合并,那么您将返回其中带有“ c”的更改。您将需要分别将它们回滚。
Teoman shipahi

12
应该强调的是:在给出的示例中,将差(F-E)应用于Z。这是一个狭窄的情况。Cherry-pick可以用于应用多个提交的差异,例如,两个非相邻提交之间的所有差异。例如,从上方开始依次是(F-E),(E-D),(D-C)和(C-B)。这等效于应用差异(F-B)。
Thomas Bitonti

2
另外,如果所选的提交(在示例中为F)具有多个直接前身怎么办?
Thomas Bitonti

2
@ j2emanue换句话说,cherry-pick将仅更改最后提交的内容。如果您提交了3次不同的时间,并且选择了最后一个,则第一次和第二次提交都不会更改。合并命令将进行所有更改并将其应用于目标(主)分支。
蒂曼·希帕希(Teoman shipahi)'18年

157

Git中的Cherry picking旨在将某个分支中的某些提交应用于另一分支。如果您愿意,可以做到。犯了一个错误,并将更改更改为错误的分支,但是不想合并整个分支。您可以例如。还原提交,然后在另一个分支上进行选择。

要使用它,您只需要git cherry-pick hash,其中hash是其他分支的提交哈希。

有关完整过程,请参阅:http : //technosophos.com/2009/12/04/git-cherry-picking-move-small-code-patches-across-branches.html


96

需要摘樱桃的情况的简短示例

考虑以下情形。您有两个分支。

a)版本1-该分支将交付给您的客户,但仍有一些错误需要修复。

B) -经典主分支,在那里你可以为release2例如添加功能。

现在:您可以在release1中修复某些问题。当然,您也需要在master中进行此修复。这是樱桃采摘的典型用例。因此,在这种情况下选择樱桃意味着您从release1分支中进行提交,并将其包括在master分支中。


3
您可能只需要另一种方式。您已修复了master的一个错误,应将其精选为release1。此外,它们可能是存储库,而不是分支机构
canbax

1
为什么不使用合并呢?
FreeLightman

我会:创建分支发布,在分支中修复它,在发布中合并分支,在主版本中合并发布。
Jasper-M

57

cherry-pick是一个Git功能。如果有人想将一个分支中的特定提交落实到目标分支,则使用cherry-pick。
git cherry-pick步骤如下。

  1. 签出(切换到)目标分支。
  2. git cherry-pick <commit id>
    

    这里的提交ID是另一个分支的活动ID。

    git cherry-pick 9772dd546a3609b06f84b680340fb84c5463264f
    
  3. 推送到目标分支

访问https://git-scm.com/docs/git-cherry-pick


43

我准备了分步演示的插图,摘樱桃的工作以及这些插图动画(接近尾声)。

  1. 在选择樱桃之前
    (我们将对分支中的提交进行樱桃选择): Lfeature在此处输入图片说明

  1. 启动命令git cherry-pick feature~2
    feature~2是之前的第二次提交
    feature,即commit L): 在此处输入图片说明

  1. 执行命令(git cherry-pick feature~2)后: 在此处输入图片说明

相同的动画: 在此处输入图片说明


注意:

所述提交L'从视用户的角度(提交=快照)的提交精确副本L

从技术上讲(内部),它是一个新的不同的提交(因为例如L包含一个指向K(作为其父对象L'的指针),而包含一个指向的指针E)。


这是否意味着分支主机上的L'将为N-> M-> L?否则它将在主分支上带来提交L
Priyank Thakkar

1
@PriyankThakkar,是的,完全是L,别无其他(如您从图片/动画中看到的)。
MarianD

22

您可以考虑,如果选择的樱桃类似于重新设定,或者像重新设定一样进行管理。我的意思是,它需要一个现有的提交并以您当前所在分支的头作为起点来重新生成它。

A rebase接受具有父X的提交,并像实际具有父Y一样重新生成该提交,这正是a的cherry-pick作用。

Cherry Pick更多有关如何选择提交的信息。使用pull(rebase),git在拉到分支的顶部隐式地重新生成本地提交,但是随着cherry-pick您显式选择一些提交,并在当前分支的顶部隐式地重新生成它们。

因此,您的操作方式有所不同,但是在幕后,它们是非常相似的操作-提交的重新生成。


1
我发现这对事情很有帮助。这暗示了为什么cherry-pick当目标分支后来合并回源分支时会表现出这种行为。谢谢你,先生。
阿兰·哈达德

3
完成功能后,我想使用Cherry Pick代替git merge。每个人完成一项功能后,总会进行git merge feature_branch。为什么不使用cherry-pick命令?你有什么想法吗?如果我能摘樱桃,为什么还要
打壁球

11

有点像“复制”(从某处)和“粘贴”(到某处),但是用于特定的提交。

例如,如果您想进行热修复,则可以使用该cherry-pick功能。

将您cherry-pick放在开发分支,然后merge提交到发布分支。同样,cherry-pick从发行分支到母版。沃伊拉


11

当您与一个项目团队的开发人员一起工作时,管理多个git分支之间的更改可能会成为一项复杂的任务。有时,您不想将整个分支合并到另一个分支,而只需要选择一个或两个特定的提交。此过程称为“樱桃采摘”。

在关于采摘樱桃的文章上找到了很棒的文章,请查看其详细信息:https : //www.previousnext.com.au/blog/intro-cherry-picking-git


7

如果要合并而没有提交ID,则可以使用此命令

git cherry-pick master~2 master~0

上面的命令将从1到3合并master的最后三个提交

如果要对单个提交执行此操作,只需删除最后一个选项

git cherry-pick master~2

这样,您将合并master末尾的第3次提交。


这很混乱。我认为您在这里不是master分支,对吗?当您提到两个提交时,您指的是<from>和<to>提交,以定义要选择的范围。正确?如果描述了方案,将大有帮助。虽然很好。谢谢。
萨拉·帕蒂(Saurabh Patil),

6

它将对当前分支应用特定的提交。

这表示 :

  • 此提交添加的所有文件将被添加
  • 此提交删除的所有文件都将被删除
  • 此提交修改的所有文件将被合并。这意味着提交中的整个文件,而不仅仅是此提交中的更改

例如:考虑提交A

added newFileA
modified main:
+ import './newFileA'

提交B

added newFileB
modified main:
+ import './newFileB'

如果您在另一个分支上选择B提交,您将得到:

/newFileB
/main :
   import './newFileA'
   import './newFileB'

因为犯乙包含newFileB,但没有newFileA,造成了错误,所以请谨慎使用。


0

摘自官方文档:

给定一个或多个现有提交,应用每个引入的更改,并记录每个提交的新提交。这要求您的工作树是干净的(HEAD提交没有任何修改)。

如果不清楚如何应用更改,则会发生以下情况:

  1. 当前分支和HEAD指针停留在成功完成的最后一次提交上。

  2. CHERRY_PICK_HEAD ref设置为指向引入了难以应用的更改的提交。

  3. 在索引文件和工作树中,都会干净地应用更改的路径。

  4. 对于冲突的路径,索引文件最多记录三个版本,如git-merge的“ TRUE MERGE”部分所述。工作树文件将包含对冲突的描述,并用通常的冲突标记<<<<<<<和>>>>>>>括起来。

没有其他修改。

阅读更多...

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.