将热修复合并到开发和主分支导致分歧(Git)

4

我正在遵循成功的Git分支模型(也称为git-flow)。

我按照“完成热修复分支”部分的指导进行了热修复。

我基于master创建了一个hotfix分支:

> git checkout -b hotfix upstream/master

做了一些工作并手动合并到 master 分支:

> git checkout master 
> git merge --no-ff hotfix

然后手动将其合并回dev:
> git checkout dev
> git merge --no-ff hotfix

我做了更多的工作 - 在dev上提交了一些内容。一切似乎都很好。但是当我试图将dev合并到master时,却无法完成。
> git checkout master
> git merge --ff-only dev
fatal: Not possible to fast-forward, aborting.

看起来来自热修复的合并提交是不同之处。

我以为按照这个过程会保留一个共同的历史记录。我做错了什么?


你为什么想要将dev合并到master并使用快进方式? - Alexey Ten
@alexeyten,我觉得应该避免合并提交……这是 文章 中的一段话:当develop分支达到一个稳定点并准备好发布时,所有更改都应以某种方式合并回master分支。 - Jason McCreary
1个回答

5
您没有提供有关历史拓扑的具体信息,因此从一般情况开始创建hotfix,可执行以下命令:
$ git checkout -b hotfix upstream/master
$ git lola
* 81a514a (dev) 特别棒的功能
* cb4d5e6 很棒的功能
* d4a7906 酷炫的功能
| * 39e449a (HEAD, upstream/master, hotfix) v0.2
|/
* 264ddbc (master) v0.1
注: git lola 是一个非标准但非常有用的别名。
hotfix合并到master,可执行以下命令:
*   567f066 (HEAD, master) 合并分支 'hotfix'
|\
| * 1b1b6e3 (hotfix) 修复了一个恶心的错误
| * 39e449a (upstream/master) v0.2
|/
| * 81a514a (dev) 特别棒的功能
| * cb4d5e6 很棒的功能
| * d4a7906 酷炫的功能
|/
* 264ddbc v0.1
hotfix单独合并到dev时会出现问题,可执行以下命令:
*   36aa1c8 (HEAD, dev) 将分支 'hotfix' 合并到 dev
|\
* | 81a514a 特别棒的功能
* | cb4d5e6 很棒的功能
* | d4a7906 酷炫的功能
| | *   567f066 (master) 合并分支 'hotfix'
| | |\
| |/ /
|/| /
| |/
| * 1b1b6e3 (hotfix) 修复了一个恶心的错误
| * 39e449a (upstream/master) v0.2
|/
* 264ddbc v0.1
此时,master不是dev的直接祖先,而是其兄弟。
dev添加更多提交会使master成为其曾祖父。
请回忆一下,dev 分支通过特性分支,并通过 --no-ff 合并到 master 分支。可能 release-1.0 从你的热修复开始,并得到了另一个 Bug 修复。

假设这个版本能够完成,可以使用以下命令将其合并回 master

$ git merge --no-ff -m "v1.0" release-1.0
$ git lola
*   5a384c8 (HEAD, master) v1.0
|\
| * f0398ba (release-1.0) Bugfix for v1.0
| * d89aa74 (dev) Jason does it again
| * a4dd5bf Jason saves the day
| *   36aa1c8 Merge branch 'hotfix' into dev
| |\
| * | 81a514a Stupendous feature
| * | cb4d5e6 Great feature
| * | d4a7906 Cool feature
* | |   567f066 Merge branch 'hotfix'
|\ \ \
| |/ /
|/| /
| |/
| * 1b1b6e3 (hotfix) Fix nasty bug
| * 39e449a (upstream/master) v0.2
|/
* 264ddbc v0.1


当然,对于您的历史记录,具体修复方法取决于具体情况。

你需要什么具体的信息?我感谢你的解释,但它还没有回答我的问题。让我问一个新问题,我应该如何做到这一点? - Jason McCreary
@JasonMcCreary 你可能已经很接近了。请记住,合并回master--no-ff,但是你的问题尝试使用--ff-only来完成它。在完全通用的模型下,dev合并到release-*,然后再合并到master。请参见我的答案的最后两个部分。如果这仍然不能回答你的问题,请考虑将git lola的相关输出粘贴到你的答案中。 - Greg Bacon
也许我在从dev合并到master时做错了。我以为你想要在分支之间合并时避免合并提交。为了在出现热修复等情况时保持干净的历史记录。因此使用--ff-only。你是说在git-flow下我想要合并提交吗? - Jason McCreary
请注意在git flow图片中,master分支中0.1版本之后的每个提交都有多个父级,即每个提交都是一个合并提交。您是正确的,基于git merge --ff-onlygit rebase的工作流通常会产生更清晰、线性的历史记录——但代价是丢弃了有用的历史上下文,例如被审查的确切提交、单个问题的寿命等等。使用rebase和squash进行一些历史记录整理仍然很有用,只要它保留足够的信息来讲述整个故事。 - Greg Bacon
1
因此,当将dev合并到master时,您需要使用git merge --no-ff。这会使masterdev分叉。但我猜您不在意,因为dev永远不会直接从master拉取,只能通过hotfix类型的分支进行操作。然而,我仍然感到困惑,因为这样做是否会使创建hotfix分支变得困难,因为devmaster已经分叉?随着时间的推移,您需要很长一段时间才能找到共同祖先。 - Jason McCreary

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