代码之家  ›  专栏  ›  技术社区  ›  Felix Dombek

git cherry pick和git格式的patch | git am有什么区别?

  •  1
  • Felix Dombek  · 技术社区  · 6 年前

    我有时需要在我的分支中选择一个带有特定补丁的标签,并且通常是通过

    git cherry-pick tags/myfix
    

    这是可行的,但是樱桃采摘需要越来越长的时间来进行“不精确的重命名检测”。

    我的预感是,这可以更快地与

    git format-patch -k -1 --stdout tags/myfix | git am -3 -k
    

    事实上,这个结果立即应用了修复程序,使我的分支处于与樱桃采摘完全相同的状态。

    现在我的问题是,采摘樱桃到底有什么不同?我以为采摘樱桃基本上就是这样实施的,但我一定是弄错了。

    2 回复  |  直到 6 年前
        1
  •  9
  •   Mark Adelsberger    6 年前

    cherry-pick 实现为合并,合并基是要引入的cmomit的父级。在没有合并冲突的情况下,这应该与生成和应用修补程序的效果完全相同(但是请参见 torek's answer 提醒一下,在哪里 am 从理论上讲,可能会做错事)。

    可以尝试更优雅地处理发生变化的情况 冲突。(事实上 -3 告诉它,如果需要,它应该做同样的事情,如果它在补丁中有足够的上下文可以这样做。最后我会回到那一点……)

    择优挑选 /合并方法将查看这些差异是什么,并从中生成合并冲突—这样您就有机会解决冲突并继续。

    作为冲突检测的一部分, 择优挑选 不重命名检测。例如,假设你有

    o -- x -- x -- A <--(master)
          \
           B -- C -- D <--(feature)
    

    犯罪 C master . 假设在 o 你创造了 file.txt ,和 A 你有修改 文件.txt . 但要承诺 B 移动 文件.txt my-old-file.txt ,并提交 C级 修改 我的老朋友-文件.txt .

    更改为 我的老朋友-文件.txt 在里面 C级 可能与更改为 文件.txt 在里面 A 文件.txt 我的老朋友-文件.txt 是“同一件事”。

    B类 C级 A

    尝试 -3 选项)是否会退回到执行合并,并进行冲突检测。它可以跳过所有这些——以及任何潜在的重命名检测——只要它的第一次尝试完全适用。


    更新

    -X no-renames 选项将关闭重命名检测。您可以将此选项传递给

    根据托雷克的评论,似乎重命名检测应该是一个没有问题

        2
  •  8
  •   torek    6 年前

    Mark Adelsberger's answer 是正确的(而且投票结果是正确的,也许你应该接受它)。但这里有一个历史上的奇怪之处。

    事实上,cherry pick曾经实施过 作为 git format-patch | git am -3 git rebase 1 这里的问题是,这无法检测重命名的文件,有时在(罕见的)难以描述的情况下,但我将尝试在适当的三方合并可以正确应用更改的地方应用更改。例如,考虑以下情况:

    @@ -123,5 ... @@
         }
       }
    -  thing();
       {
         {
    

    换句话说,被删除行周围的上下文只是大括号(或者更糟的是,空白)一些无用的匹配。在 同一个文件的版本,由于其他事件,什么 第123行到第127行现在在同一个文件中较早或较晚。比如说,它们现在是第153-158行。同时123-127号线

        }
      }
      thing();
      {
        {
    

    但是 这些 线路正确:呼叫 thing() 应该删除的(因为它是错误的)已经下移了,但是有一个调用 事情() 那应该

    你的 版本,也许 也许 吧 你的 第155行。

    在这两种格式差异中,重命名检测比apply和true三方合并更为重要,但在某些情况下,两者都很重要。跑步 git cherry-pick 做更彻底、更慢、更经常正确的事情。


    git再基 曾经使用过格式补丁,即使这样,只要你 不要 使用 -m -s ,或使用指定扩展选项 -X . 这三种方法中的任何一种都会强制非交互的rebase使用cherry pick方法。

    注意,Git文档调用 -十 参数“策略选项”或“策略选项参数”,这是一个非常笨拙的短语。我喜欢这里的“扩展”这个词,因为它解释了 ,即扩展。扩展选项只是传递的选项 你选择的策略 -s码 :Git不知道每个选项有哪些附加选项 -十 ,Git给出所选的策略,然后策略本身要么接受 -十 选择做某事,或抱怨未知。

    推荐文章