目的 :我需要提供的补丁到上游项目的以前版本,我希望能够将这些补丁应用到更高版本。
问题 :从维护分支衍合到更高版本创建与未在维护分支被修改的文件冲突。
怀疑 :我申请合并或者什么,我试图完成基础重建不正确。
示例:这是我所要完成的任务,但明白,发布标签v1.0和v2.0之间的提交史可数百提交的之间的逻辑实例。
我叉上游回购与多个标记与一个主版本(v1.0和V2.0)提交历史A至D. B是最后提交标签V1.0。 C是最后提交标签V2.0。 d是持续发展。
$ git clone git@server:repo
A<--B(v1.0)<--C(v2.0)<--D Master
我岔开早期版本标签(V1.0),使像这样一些自定义的修改:
$ git checkout v1.0 -b v1.1
E<--G<--H v1.1
/
A<--B<--C<--D Master
\
F v2.1
我现在想要做的是分支以后的版本标签(V2.0)和应用补丁提交我在V1.1分支(G“和H”)到2.0分支的。 我需要保持个人承诺,我在V1.0在V2.0日志做。
E<--G<--H v1.1
/
A<--B<--C<--D Master
\
F<--G'<--H' v2.1
问 :什么是应用这些变化,避免矛盾,正确的工作流? 我曾尝试合并的多种组合和变基(包括--onto),但都失败。 git的重订希望默认值为3路合并和冲突与不相关的文件。
$ git rebase v2.1 v1.1
Falling back to patching base and 3-way merge
...
Failed to merge in the changes.
$ git checkout v2.1
$ git rebase v1.1
Falling back to patching base and 3-way merge
...
Failed to merge in the changes.
我建议您编辑的问题,包括与您试图变基--onto确切的指令(S)。 这应该是你完成你正在尝试什么样的方式,但你可能会以这样的方式运行命令触发更多的基础重建比实际需要。
如果衍合命令重写之间的一切v1.0
和v.2.0
,那么这可能会导致很多不必要的疼痛,如果这么做历史包括通过非快速向前合并解决的冲突。
在清晰的兴趣,我搬到有关合并的冲突和重订基期这个答案底部的解释。 然而该节仅仅是猜测,这将有助于看到的一个例子rebase --onto
你尝试。 不具有可现在,我将提供什么,我认为你应该做的。 随着中说,让我们开始您的解决方案。
解决方案
变基--onto
我喜欢读--onto落后的参数来了解更好。 向后读, --onto <1> <2> <3>
读为-以任何提交是上<3>
中,不是在<2>
并且将其应用到<1>
该提交不是“移动”,在被“克隆”,让你的老提交仍然在那里他们- --onto只是创建它们的副本,并在他们之后应用重订<1>
它的重要的是知道执行后, rebase --onto
,您可以在无头的状态结束。 如上所述,在应用新的提交,但他们没有立即改变你的分支的状态。 这增加了在这个过程中额外的步骤,但也给你明知底垫不能打破你的分支附加的安全性 - 你将有机会申请东星更改您的分支之前查看更改的历史。
与此图开始。
E<--G<--H v1.1
/
A<--B<--C<--D Master
\
F v2.1
若要仅获取G
和H
跟随F
, 而不包括E
,这似乎根据你的描述是这样,那么你应该尝试使用以下命令。
git rebase --onto F G^ v1.1
上面我写的少,我可以假设一下如果你的现实情况。
这将需要对提交的任何存在v1.1
不上承诺立即着手存在G
,后其应用于F
。 由于只有犯下实际上被改写为G
和H
,那么有没有理由你应该得到的任何冲突无关的什么这两个提交更改。
无头状态
正如我上面所描述的,你可以在无头的状态结束。 这意味着,你是不是在您的分支了。 你在这一点上图实际上看起来是这样的...
E<--G<--H v1.1
/
A<--B<--C<--D Master
\
F v2.1
\
G'<--H' (currently checkout out headless state)
正如你所看到的,分支V2.1仍处于F
,但你已经创建了一个新的历史A<--B<--C<--F<--G'<--H'
这是你想要的,但它在你不v2.1
分支。 所以,现在你回顾历史并验证你想它是什么。 即使你想对它进行测试。 一旦通过验证,你只需要签V2.1并运行以下命令
git checkout v2.1
git merge H'
这是假设你有没有在2.1版没有新提交H'
。 为了确保,你可能想使用--ff-only
旗合并,以便它会拒绝合并,而不是创建一个合并提交的。
就像我上面说的,这是一个额外的步骤,以做到心中有数,但这样的结果,你可以重置放心, git rebase --onto
不会让一个烂摊子您的实际分支。 如果您发现该底垫没有工作打算-你可以简单地结帐v2.1
,看到没有伤害作为已经完成。
结果
在您的快进合并compeltes,你将有一个历史,看起来像这样...
E<--G<--H v1.1
/
A<--B<--C<--D Master
\
F<--G'<--H' v2.1
樱桃采摘VS再次基于--onto
不会深究采摘樱桃的细节,但我要明确的是,以下..
git checkout v2.1
git cherry-pick G^..H
是完全等效的太...
git rebase --onto v2.1 G^ H
git checkout v2.1
git reset --hard <hash> <-- were hash is the commit the rebase kicks you into.
樱桃挑有更少的步骤,底垫可以不检查出的“基地”,这两种情况下,这里是做v2.1
。 另外,作为解释波夫底垫--onto不会直接影响你的分支使其更容易从,如果出现错误恢复。 这两个“克隆”的提交,他们将到基地,留下原件不变。
问题
以上是就如何实现你问做什么的一般说明。 下面是我的怀疑,为什么你有你所描述的问题。
非快速转发冲突解决及衍合
我的猜测是,v1.0和v2.0之间的,你有一些非快进合并是用在解决冲突。 当冲突被非快进合并过程中得到解决,对于冲突解决存储在合并提交 ,而不是在有问题的承诺本身。 这次合并提交后来在历史上出现在合并的点,而不是冲突的承诺本身。
当你变基,通过每个git的步骤单独提交,并再次确认它 - 作为一个结果,我们可以重温从非快进合并产生的所有矛盾,但分辨率这场冲突是不可用的,直到后来在历史上的合并发生时。 与非快进合并解决冲突是不利于你在未来的衍合分支的能力,除非你愿意一个重新解决所有这些冲突之一。
你可能错
如果我对你的问题的猜测是正确的,那么你可能已经做了以下...
git rebase --onto v1.1 F v1.1
这本或一些变化会导致采取所有在提交F
使不上v1.1
,并将其追加到年底v1.1
。 如上所述,这说明将导致各之间提交B
和F
被重新提交一个接一个。 如果在没有合并这是与非快进解决的冲突 - 那么你会重温每个这些冲突,就好像这些提交的底垫步骤。
合并,而不是衍合
你的问题标题所暗示的,你可能是开放的简单合并这些历史。 如果你不能与线性的历史而言,你可能只是想V1.1合并到F
。 这不应导致任何奇怪的冲突,但它会显著搅浑你的历史记录。
虽然它可能没有细粒度的控制变基,或易于合并的,经过了一系列的提交到git cherry-pick
似乎更适合承担老枝个体的变化和他们玩到当前分支。
所以,如果G和H是在过去两年提交v1.1
,你应该能够樱桃接他们到v2.0
通过:
git cherry-pick v1.1~1
(或手动提供提交散列)
如果你已经尝试过这一点,也有缺点,让我知道。 我还在努力完善这种工作流自己的:)
文章来源: git: what is the correct merging or rebasing workflow to modify a maintenance branch and apply those patches to another branch?