Cherry-pick并将一系列提交压缩到子目录或子树中

don*_*ote 53 git git-cherry-pick git-squash

我怎么能告诉樱桃选择一个被压缩的提交范围?

或者换句话说,将两个提交之间的差异应用于存储库的当前状态?

以下就不能正常工作(摘樱桃没有--squash选项):

git cherry-pick --squash e064480..eab48b59c
Run Code Online (Sandbox Code Playgroud)

注意:我的用例是在一个子树场景中 - 在任何人开始争论我不应该压制之前.

以下工作,但后来我有一系列单独的提交.之后,我可以使用交互式rebase手动压缩它们.

git cherry-pick -X subtree=vendor/package e064480..eab48b59c
Run Code Online (Sandbox Code Playgroud)

有没有什么方法可以挤压作为樱桃挑选的一部分?

Dav*_*sch 81

传递-ngit cherry-pick.这将应用所有提交,但不提交它们.然后只需git commit在单个提交中提交所有更改.

  • @DavidDeutsch 错了。如果您使用“--no-commit”选择提交,遇到冲突,解决它并暂存文件,“gitcherry-pick--Continue”**将不起作用**:“错误:您的本地更改将被覆盖通过cherry-pick。``提示:提交您的更改或隐藏它们以继续。``致命:cherry-pick 失败`。如果您提交更改以继续,那么您最终将得到您不想要的提交(加上索引中没有冲突的分阶段更改)。如果您隐藏它们,那么您会忽略冲突的更改(稍后可以从隐藏中应用它们,但解决冲突会越来越困难) (7认同)
  • @SazzadHissainKhan,虽然我很确定它会以相同的方式工作(即你解决每个冲突,然后使用`git cherry-pick --continue`),在这种情况下省略`-n`可能是最安全的,以便在操作完成后,您可以查看每个单独的提交并确认一切正常.然后,您可以通过交互式rebase压缩它们. (5认同)
  • 如果在挑选的提交范围内有多个冲突怎么办? (3认同)

lkr*_*aav 9

对于某些用例来说,有用的替代方案git cherry-pick -n可能是git merge --squash- 例如,当您想要在集成分支之上测试功能分支的更改而不进行变基时。

来源:git merge --squash 和 gitcherry-pick 之间有什么区别?


小智 8

从 master \xe2\x86\x92 开始,从另一个分支中挑选两个提交

\n
git checkout master\ngit cherry-pick :1  \ngit cherry-pick :2\ngit reset --soft HEAD~2 (number of cherry pick commits, i.e 2 ) \ngit add . \ngit commit\n
Run Code Online (Sandbox Code Playgroud)\n


Von*_*onC 5

2022 年的讨论来看,还有其他方法:

  • git diff A...B | git apply --3wa
    但,

    • 它不显示提交消息,
    • 您将无法使用显示整个源文件的图形合并工具。
      当使用“ git cherry-pick”并且存在冲突时,您可以看到整个文件上下文的变化。
  • Johannes Sixt 建议进行交互式变基

    例如,要将历史范围移植A..B到 HEAD 之上,我会开始(注意^0之后B,因为我不相信自己,所以我会保持真正的分支B不变,因为我在运行 rebase 时可能会犯错误):

    $ git checkout --detach HEAD ;# this is only to use @{-1} later
    $ git rebase -i --onto HEAD A B^0
    
    Run Code Online (Sandbox Code Playgroud)

    然后,如果我的目标是将所有内容压缩为单个提交,则将除第一个之外的所有“pick”替换为“squash”。
    这将给我一次编辑单个提交消息的机会,但编辑器缓冲区以所有原始消息中的日志消息开始,因此我可以在编写新内容时从中挑选出好的部分。我将在分离的 HEAD 上得到结果。
    如果我喜欢这个结果,我可以用它更新我原来所在的分支。

    $ git checkout -B @{-1}
    
    Run Code Online (Sandbox Code Playgroud)

    或者,如果我不这样做,也许是因为我犯了错误,那么我可以放弃它并返回到原来的分支。

    $ git checkout @{-1}
    
    Run Code Online (Sandbox Code Playgroud)

然而,诺姆·约拉夫-拉斐尔 (Noam Yorav-Raphael) 反对:

我使用“ rebase -i”的主要问题是,它需要我在出现合并冲突的每次提交上一一修复它们,而不是一次修复所有冲突,将从 到 的更改视为A一个 B
它还需要对A和之间的每次提交进行手动编辑B

诺姆建议:

我认为使用现有命令执行我想要的操作的最佳方法是:

$ git checkout --detach HEAD ;# this is only to use @{-1} later
$ git rebase -i --onto HEAD A B^0
Run Code Online (Sandbox Code Playgroud)

这允许您一次性修复合并冲突,显示导致冲突的整个文件,并允许您编辑提交消息,从所有压缩提交的描述开始。

我认为这也很好地解释了“ cherry-pick --squash”将做什么:它确实是“”的类似物merge --squash,但用于樱桃挑选。