当开发分支与主分支不同时,如何管理热修复?

81

我正在使用"Git Flow"分支模型,其中包括主分支(master)和开发分支(develop)。我正在进行一个重大的新版本发布,所以我的develop分支与master分支有很大的不同。这导致每当我需要在master上进行热修复并将其合并回develop时都会出现问题。几乎总是会产生冲突,这变成了一个真正的麻烦。

如何更好地管理这个问题?对我来说,手动在develop上进行小的热修复变化,并在准备就绪后将所有内容合并到master中而不是将master合并回develop会更容易。这种做法可行吗?


2
你是否考虑过cherry-picking,而不是将master合并到develop分支中? - Fred Foo
默认情况下,使用非 FF 合并时,如果将 develop 拉入 master,则 develop 的尖端不会具有 master 的更改,但是 master 将具有 develop 的更改。这符合您的要求吗? - Andy
@Andy - 我基本上只想用develop替换master。我不希望它抱怨master的更改未合并到develop等问题。 - TaylorOtwell
1
@TaylorOtwell,如果是这样的话,为什么不直接重命名它呢? - Andy
7
好的,我会尽力进行翻译。 +1 for being TaylorOtwell 的意思是“因为是TaylorOtwell,所以点赞/支持”。 - Chris Bier
5个回答

70

将一个分支上的部分提交复制到另一个分支最简单的方法是使用cherry-picking

假设你在master分支中修复了某个提交并且该提交哈希为HASH,现在你想将这个热修复应用到devel分支中,只需执行git checkout devel,然后执行git cherry-pick HASH即可。

如果你想将master分支中的所有更改都应用到devel分支中,则可以使用以下命令实现:

git checkout devel
git rebase master
如果你需要相反的情况(在开发过程中,在“devel”分支中进行热修复并希望在将“devel”完全合并到“master”之前将该修复引入到“master”中),则工作流程非常相似。假设热修复具有哈希值HOTFIX_HASH,请执行以下操作:
git checkout master
git cherry-pick HOTFIX_HASH

现在,这个提交已经存在于 masterdevel 分支中。为了解决这个问题,请输入:

git checkout devel
git rebase master

此提交将从 devel 中消失,因为它已经存在于 master 中。


16
请注意,git cherry-pick 会创建一个不同的提交记录。因此,将 devel 分支合并到 master 分支时会发生冲突。这种解决方案只适用于“变基工作流”。 - Brian Cannard
7
如@IvanBorisenko所示,如果你与其他人共同开发,为避免重写历史记录,建议使用git merge master而非rebase。在第二种情况下,将需要解决合并冲突。 - gsf
我需要在使用checkoutcherry-pick命令之前推送到主分支吗? - Gergely Lukacsy

21

在这种情况下,我的一般工作流程是创建一个修复问题的 bug-fix 分支,该分支基于 master。 一旦准备好,将其合并回到 master,然后将 master 合并到 develop

这假设您的 bug 修复几乎是在两个分支中需要更改的代码之间一对一的关系。 如果是这种情况,您可以尝试将 git merge -s ours master(请参阅man-page)合并到 develop 中,以使 develop 分支具有优先权。

我在正在开发的开源项目中管理错误修复版本时使用类似的过程。 master 总是领先于需要应用错误修复的位置,因此我从需要修复的标记创建分支,应用修复并发布,然后重新打标记并将新标记合并到 master。 这会导致版本号冲突,但可以通过上面的命令避免。

希望对您有所帮助。


2
为什么不使用 git merge -s ours hotfix-2.2 呢?其中的 2.2 是我编造的。 - basarat
merge mastermerge hotfix-* 之间,哪一个是更好的方式? - LCB

8
我通常遵循这个指南,它在大多数情况下都非常适用,并避免了与冲突和更改相关的主要问题。
如果您能够在feature分支上工作,并仅在创建release分支之前将其合并到development中(意味着您实际上正在准备发布)...此方法应该可以避免您遇到的大部分合并冲突。
由于破坏性更改会发生在feature-breaking分支上,因此您可能只会在此feature-breaking分支合并到development时遇到冲突。您也可以随时将development合并到release分支以使其保持更新。
您还可以轻松地将所有最小或完全没有冲突的hotfix-branch合并到development中。
我在链接之前分享的指南非常强调从developmentmaster或反向合并。始终通过一个release分支处理您的发布。

这个指南也很好:https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow - CrazyTim

0

所有的答案都有点靠不住。

我的个人解决方案是中期发布。

每3-7天进行一次微型发布

比如你可以将其命名为1.01、1.02等。下一个客户版本将是2.0。

这些中期发布必须仅包含稳定的功能(因此尚未合并到主分支)

这样可以让您随着时间的推移保持主分支和开发的一致性,并轻松进行热修复,避免很多麻烦。


0
这完全取决于您如何使用GIT来管理您的代码、发布计划和版本。最佳实践是拥有master分支来保存您的生产级别代码,拥有develop分支来进行开发,从develop分支分支出release分支来处理即将发布的版本,从master分支分支出hotfix分支来处理生产代码的紧急修复。因此,releasehotfix分支最终将合并回masterdevelop,以确保两个分支都具有更改,并且当develop分支出新的release时,这个新的发布没有问题可以合并到master上。标记始终在master上进行。
采用这种方法,releasehotfix 分支将被合并两次,并且当合并到 develop 分支时有时会出现冲突,如果在 develop 上进行许多开发活动,则不可避免。缩短您的 releasehotfix 分支生命周期可能是缓解此问题的一种方法。如果发生冲突,请使用任何技术来解决它,并确保不更改已完成和测试过的 releasehotfix 代码。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接