Git:仅合并在分支上所做的更改

Posted

技术标签:

【中文标题】Git:仅合并在分支上所做的更改【英文标题】:Git: merge only the changes made on the branch 【发布时间】:2011-09-29 12:11:41 【问题描述】:
  G---H             // Release Branch
 /
/
A---B---E---F---    // master
    \
     \
      C---D---     // bug fix branch

根据我们对项目的特殊需求,上述情况很常见。我们的 master/dev 分支有一些提交。然后我们得到一个错误报告并开始在错误分支上修复它(提交上面的 C 和 D)。与此同时,更多的提交发生在 dev 分支中。接下来我们被告知我们需要为客户创建一个版本,该版本不能包含上述提交 B、E 和 F 引入的更改,但它应该包含错误修复。

所以我们在更改 B 被应用之前就从 dev 分支出来了,但是将 bug 修复也纳入这个发布分支的最佳方法是什么?如果我执行分支的合并,它将包括在 B 中所做的我不想要的更改。我可以对提交 C 和 D 进行挑选,但我读到挑选樱桃并不总是一个好主意based on this answer 基本上是因为我的回购看起来像:

  G---H---C'---D'--- // Release Branch
 /
/
A---B---E---F---     // master
    \
     \
      C---D---       // bug fix branch

所以 C' 和 D' 显示为具有不同 sha-1 ID 的全新提交,如 C 和 D。这真的是一件坏事吗?这会导致什么问题?有没有更好的方法将 bug fix 分支的更改导入到 release 分支?

【问题讨论】:

【参考方案1】:

This 文章建议不要合并两个分支,而是将它们变基,而 git 只会变基非重复提交。

但是,您可以考虑只重新设置分支,而不是挑选樱桃:

rebase --onto release B bug

其中release 是发布分支,bug 是错误分支。

然后你会得到类似的东西

         C'---D' //Bug branch      
        /
       /
  G---H  // Release Branch
 /    
/ 
A---B---E---F---     // master

但这意味着当您希望将错误修复应用到 master 时,您需要将错误与 master 合并,这会导致发布中的所有更改也添加到 master。

由您决定什么最适合您。

请注意,您不应将已为 pushed 的分支重新设置为其他分支,因为这会给它们造成混乱。

【讨论】:

看起来,所有这些提交都被推送到远程仓库。在这种情况下,不建议 rebase。 在我看到此评论之前添加了该部分。【参考方案2】:

使用cherry-pick 并没有真正的危险,尤其是如果您不打算将release 分支合并到master 中。

一般来说,您可以通过将错误修复基于您想要将修复合并到的所有分支中的提交来防止此类问题。在 git 本身的开发中,这是通过将所有错误修复合并到 maint 分支(即当前仅接收修复的当前稳定系列)然后定期将其合并到 master 来实现的。这样一来,修复无处不在,合并也很正常。

【讨论】:

如果我将发布分支合并回 master 会有什么危险?在我制作的图表中,最终需要将更改 H 应用回 master 分支。 好吧,如果你不把bug fix分支也合并到master中也没问题。如果你这样做,你可能会得到比其他情况更多的冲突(如果两个分支都以相同的方式修改代码的这些部分,并在此基础上添加一些不同的更改)。 “危险”是夸大其词,真的......这意味着您必须手动修复一堆冲突,并且这两个提交将在您的历史记录中出现两次(具有不同的提交 ID)。【参考方案3】:

注意:如上所述,这里可以采摘樱桃。 它的主要缺点是:

在合并的情况下,你会因为重复提交而发生冲突 见“Git cherry pick and datamodel integrity” 忽略函数依赖。 请参阅“How to merge a specific commit in git”。

在你的情况下:

无需合并。 如果您确定 CD 不是基于 B 中引入的代码,...请在需要的地方挑选它们。

【讨论】:

【参考方案4】:

创建一个补丁文件,其中包含来自错误修复分支的唯一内容。然后将该补丁文件应用到发布分支。

例子:

> git checkout bugfix_branch
> git diff B HEAD > unique_changes.patch /* where "B" is the point where bugfix_branch split from dev */
> git checkout release_branch
> git apply unique_changes.patch

瞧!现在,您的发布分支中只有来自 bugfix 分支的唯一更改。请注意,format-patch 倾向于更优雅地处理文件已被移动或删除的情况,因此您可能需要尝试生成补丁的实际过程,但这种方法应该会让您接近。

【讨论】:

以上是关于Git:仅合并在分支上所做的更改的主要内容,如果未能解决你的问题,请参考以下文章

git merge master branch来发布分支问题

如何 git-cherry-pick 仅更改某些文件?

如何运行 git log 以仅查看特定分支的更改?

创建分支后从 master 获取更改

我如何知道对分支所做的最新更改是啥?

如何恢复从一个分支合并的所有提交