gpt4 book ai didi

git - git merge-git : what is the correct merging or rebasing workflow to modify a maintenance branch and apply those patches to another branch?

转载 作者:行者123 更新时间:2023-12-02 23:34:49 26 4
gpt4 key购买 nike

目标:我需要对上游项目的先前发行版进行自定义补丁,并且我希望能够将这些补丁应用于更高版本。

问题:从维护分支重新定位到更高版本会与未在维护分支中修改的文件产生冲突。

怀疑:我要为完成的工作错误地应用 merge 或重新定基。

示例:这是我要完成的事情的逻辑示例,但是请理解,带标记的发行版v1.0和v2.0之间的提交历史记录可以介于两者之间的数百次提交中。

我用一个具有主要提交历史记录A到D的带有多个标记发行版(v1.0和v2.0)的上游 repo fork 。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')中所做的补丁提交应用于v2.0分支。我需要在v2.0日志中保留我在v1.0中所做的单个提交。
     E<--G<--H v1.1
/
A<--B<--C<--D Master
\
F<--G'<--H' v2.1

问题:什么是应用这些更改并避免冲突的正确工作流程?我尝试了 merge 和 rebase 的许多组合(包括--onto),但都失败了。 git rebase希望默认为三向 merge ,并且与不相关的文件冲突。
$ 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用作基础的确切命令。那应该是您完成尝试的方式,但是您可能已经以某种超出实际需要的触发基础的方式运行了该命令。

如果您的rebase命令重写了v1.0v.2.0之间的所有内容,那么如果该历史记录包含通过非快进 merge 解决的冲突,则可能会导致很多不必要的痛苦。

为了清楚起见,我将关于 merge 冲突和重新定级的解释移到了此答案的底部。但是,该部分仅仅是猜测,请参阅您尝试的rebase --onto的示例,这将对您有所帮助。现在没有可用的功能,我将提供您认为应该做的事情。话虽如此,让我们开始您的解决方案。

解决方案

重新设置--on到

我喜欢阅读--onto的论点,以便更好地理解。向后读,--onto <1> <2> <3>读为-接受<3>上的所有提交,而不接受<2>上的任何提交,并将它们应用于<1>。提交不会被“移动”,而是被“克隆”,因此您的旧提交仍在原处(重新设置基础),仅创建它们的副本并在<1>之后应用它们。

重要的是要知道,在执行rebase --onto之后,您可能最终会陷入 headless 状态。如上所述,将应用新的提交,但是它们不会立即更改分支的状态。这在该过程中增加了一个额外的步骤,但同时也使您更加安全,因为知道 rebase 不能破坏您的分支机构-您将有机会在将变更应用到分支机构之前查看已更改的历史记录。

从此图开始。

     E<--G<--H v1.1
/
A<--B<--C<--D Master
\
F v2.1

要仅使 GH遵循 F,而不包括 E,根据您的描述似乎是这种情况,那么您应该尝试以下命令。
git rebase --onto F G^ v1.1

如果您遇到的情况,我在写上面的假设时尽可能少地假设了现实。

这将接受 v1.1上存在的所有提交,而不是立即继续进行 G的提交上存在的所有提交,并将它们应用在 F之后。由于实际被重写的唯一提交是 GH,因此没有理由要使与这两个提交所更改的内容无关的任何冲突发生。

headless 状态

如上所述,您可能最终会陷入 headless 状态。这意味着您不再在分支机构中。此时您的图表实际上看起来像这样...
     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分支中。因此,现在查看您的历史记录并验证其是否想要您的记录。如果需要,甚至可以对其进行测试。验证后,您只需 checkout v2.1并运行以下命令...
git checkout v2.1
git merge H'

假设您在v2.1上没有 H'中没有的新提交。为确保这一点,您可能需要在 merge 中使用 --ff-only标志,以便它将拒绝 merge 而不是创建 merge 提交。

就像我在上面说的那样,这是一个需要注意的额外步骤,但是因此,您可以重置以确保 git rebase --onto不会在您的实际分支上造成困惑。如果您发现重新设置没有达到预期的效果-您可以简单地 check out v2.1并看到这样做没有任何危害。

结果

快速 merge merge 后,您将拥有一个类似以下的历史记录...
     E<--G<--H v1.1
/
A<--B<--C<--D Master
\
F<--G'<--H' v2.1

Cherry-picking vs Rebase-到

不会详细介绍 cherry-pick ,但是我想在下面澄清一下。
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.

Cherry Pick的步骤更少,可以在不 check out “base”的情况下完成 rebase ,这两种情况都是 v2.1。同样如前所述,bove rebase --onto不会直接影响分支,因此在出现问题时更容易从分支中恢复。两者都“克隆”了他们带来的提交,而原始文件则保持不变。

问题

上面是关于如何实现您要完成的任务的一般说明。以下是我对您为什么遇到所描述问题的怀疑。

非快速转发冲突解决和重新定位

我的猜测是,在v1.0和v2.0之间,您有一些用于解决冲突的非快进 merge 。如果在非快速 merge 中解决了冲突,则该冲突的解决方案将存储在 merge 提交中,而不是存储在有问题的提交中。 merge 提交发生在历史记录的稍后位置,而不是发生在冲突的提交本身上。

当您重新设置基准时,git会逐个逐步处理每个提交并重新提交-结果,您将重新体验由非快进 merge 引起的所有冲突,但是直到 merge 发生的历史记录中的较晚版本,该冲突的解决方案才可用。使用非快进 merge 解决的冲突会损害您将来重新建立分支机构的能力,除非您愿意一一解决所有这些冲突。

您可能的错误

如果我对您的问题的猜测是正确的,那么您可能已经完成了以下工作...
git rebase --onto v1.1 F v1.1

这种更改或某些更改将导致 F中的所有不在 v1.1上的提交都被添加到 v1.1的末尾。如上所述,这将导致 BF之间的每个提交都被一次重新提交。如果其中存在通过非快进 merge 解决的冲突,那么您将在重新提交的基础上重现这些冲突中的每一个,尽管这些提交已提交。

merge 而不是重新设置

您的问题标题表明您可能愿意简单地 merge 这些历史记录。如果您不关心线性历史记录,则可能只想将v1.1 merge 到 F中。这不应该导致任何奇怪的冲突,但是会极大地混淆您的历史。

关于git - git merge-git : what is the correct merging or rebasing workflow to modify a maintenance branch and apply those patches to another branch?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15973964/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com