【问题标题】:Proper way to merge dev into main branch将 dev 合并到主分支的正确方法
【发布时间】:2022-01-15 04:01:16
【问题描述】:

我在一家公司工作,我们决定要更正确地使用 git。我负责将 dev 分支集成到主分支中,对于如何在不同的场景中正确合并感到困惑。

我们现在的工作方式:开发人员只需在 dev 分支上重新定位他们的功能分支。完成后,他们将向dev 分支提交合并请求。然后,我会检查代码(我们是一个小团队),并接受合并请求。之后,他们只需删除功能分支。当dev 分支经过正确测试后,我会在 GitLab 中创建一个到主分支的合并请求,将其分配给我自己并批准它。这会在 main 分支上创建一个提交:

将分支'dev'合并到'main'中

然而,现在dev 分支是main 后面的一个提交。我如何最好地解决这个问题?到目前为止,我只是将main 再次合并到dev 中,但这看起来既麻烦又奇怪,因为它们现在是我的dev 分支中的另一个提交;

将'main'分支合并到'dev'中

我也可以在 main 上 rebase dev,但我知道“你永远不应该 rebase public 分支”

This SO 问题告诉我正确的方法是首先将 main 合并到 dev 中,以确保 main 分支保持干净。这会是实现dev --> main 合并的最佳方式吗?

这是否受到 git fast-forwards 由 default 合并的概念的影响?我读到,当从当前分支尖端到目标分支存在线性路径时,就会发生快进合并。这意味着,当 dev 分支在合并时简单地领先于 x 提交到 main 时,同时没有向 main 提交(这在我们的工作中很常见,因为我们在技术上只提交从devmain),合并将自动成为快进合并?这种行为对于将dev 合并到main 是否有问题,我应该在合并时使用-no-ff 标志吗?

如果我理解正确,快进合并集成dev 提交到main 分支,而--no-ff 合并导致合并总是创建一个新的提交对象,即使可以使用快进执行合并(来源:This SO question)。这是否意味着 ff 合并不会创建提交,而 dev 只是领先于 x 提交给 main?在本地合并分支后,我将如何向上游推送合并?我应该在本地合并 dev 和 main 还是干脆继续使用 gitlab 网络界面?

不用说,我对这一切感到非常困惑。如果有人能把事情弄清楚就好了。

【问题讨论】:

  • "现在 dev 分支是 main 后面的一个提交。我该如何最好地解决这个问题" 修复什么?为什么这是个问题?这是真的,没关系。
  • @matt 让我感到困惑的是,我有这样的想法,即分支在合并后应该具有 ~exactly ~ 相同的历史记录,因为两个分支现在应该包含相同的内容。但是,由于合并了分支,它们确实具有相同的内容。使历史“不同”的事情是主分支或开发分支上的~实际~合并提交。这确实是正确的。
  • 一般来说,不,如果你将dev合并到main中,它们的内容就不一样了。事实上,如果两个分支总是有相同的内容,就不需要两个分支。

标签: git git-merge


【解决方案1】:

您对git merge --no-ff 所做的事情的理解几乎是正确的。可能需要调整的部分是您使用 integrates 这个词来表示快进,而重要的是要意识到是允许快进发生,还是使用 --no-ff 强制创建合并提交,生成的文件结构是相同的。在这两种情况下,所有提交都是“集成的”,您可以在具有相同提交 ID 的两个分支中看到它们。强制合并提交会影响分支历史的图表。请注意,在快进合并之后,分支是相同的,这意味着两个分支名称都指向相同的提交 ID。如果快进是可能的,但您使用--no-ff 创建合并提交,则其中一个分支指向合并提交,并且正如您所注意到的,它将是源分支之前的一个提交。这导致我们提出您的问题:

然而,现在dev 分支是main 后面的一个提交。我如何最好地解决这个问题?到目前为止,我只是将main 再次合并到dev 中,但这看起来既麻烦又奇怪,因为它们现在是我的dev 分支中的另一个提交:

这里有两个观察:

  1. 实际上,如果您将dev 合并到main,然后将main 合并回dev dev 上出现任何新提交之前,然后快进回到@ 987654335@ 是可能的,如果您不希望,您不必生成新的合并提交(带有消息“Merge branch main into dev”)。如果您允许快进合并,那么之后dev 将指向与main 相同的提交,这将是带有消息“Merge branch dev into main”的合并提交。如果您选择使用--no-ff 进行该合并,那么您当然会创建一个新的合并提交。
  2. 让我们假设合并提交在那里,要么是因为新提交在两次合并之间潜入dev,要么是因为您使用了--no-ff 并强制它。 那又怎样?如果你强制合并提交(例如默认的 Git Flow 推荐),那么是的,你会有合并提交,这意味着 devmain 永远不会相同,并且完全没问题

现在让我们来梳理一下你的其他一些问题:

这个 SO question 告诉我正确的方法是首先将 main 合并到 dev 中,以确保 main 分支保持干净。这会是实现 dev --> main 合并的最佳方式吗?

这取决于你。在 Git Flow 模型中,如果新提交出现在 main 中,您通常希望尽快将 main 合并回 dev,这样您就不会测试与您将部署的内容不同的东西。 (或者更糟的是,如果您从 dev 或临时的 release 分支部署,那么您不会从 main 删除生产中的修补程序更改,因为它们还没有在您的 release 分支中。)所以,在将dev 合并到main 之前,您不需要将main 合并到dev 中。相反,如果 修补程序出现在 main 上,您应该在不久之后将这些修补程序合并到 dev 中。然后dev 将始终准备好合并到main

这是否受到 git 快进默认合并的概念的影响? ...当 dev 分支只是在提交到 main 之前 x 时 ...合并将自动成为快进合并?

是的。在可能的情况下,快进合并是默认设置。

这种行为对于将 dev 合并到 main 是否有问题,合并时是否应该使用 -no-ff 标志?

没有问题。您是否应该强制合并提交取决于您。有一些优点和缺点。取自我的answer to another question

合并(使用--no-ff)强制合并提交,这很有帮助,因为每个 PR 都包含与该 PR 关联的提交列表,使您能够查看显示所有合并到的第一父历史记录分支,并轻松比较它们。强制合并提交的另一个好处是,只需恢复合并提交即可轻松恢复整个 PR,而不是单独恢复原始 PR 中的每个提交。

请注意,GitLab 将“拉取请求”称为“合并请求”,因此您可以在上一段中看到“PR”的地方替换“MR”。强制合并提交的唯一缺点是:如果您不关心刚才提到的任何这些优点,那么它会给结果图增加不必要的复杂性。

最后,你问:

在本地合并分支后如何将合并推送到上游?我应该在本地合并 dev 和 main 还是干脆继续使用 gitlab 网络界面?

如果您没有启用分支保护,这没有什么区别。如果您为 devmain 分支(在 GitLab 中)打开分支保护/策略,那么您将需要使用合并请求功能来执行这些合并。完成合并请求后,您可以选择是要快进还是强制合并提交。如果您在本地执行此操作,那么您只需将分支推送到远程服务器 (GitLab),前提是您有权执行此操作。无论哪种方式,最终结果都是一样的。

【讨论】:

  • 你先生,真棒。
【解决方案2】:

当您同时提出多个问题时,我想将我的回答集中在您问题的一部分上。您可能会问自己,该项目/团队甚至拥有一个开发分支是否是一个好主意。没有它,您可能会更有效率和/或拥有相同的代码质量和/或维护能力。参见例如this SO question 关于拥有开发分支的好处。

关于本地与 Gitlab/Github 合并: 我总是尝试与 Gitlab 合并,因为它允许讨论更改并将有关合并(请求)的链接更容易地发送给其他人。此外,它可以让您在合并实际发生之前更轻松地依赖 CI,因此只有在管道成功时才进行合并(参见例如 this Gitlab Documentation)。

【讨论】:

  • 谢谢。这如何解决 dev 是 main 后面的一个 commit 的问题?
【解决方案3】:

我认为您的问题的最佳解决方案(将提交中的更改从main 带到dev 分支)是樱桃采摘git cherry-pick。这使您可以从 main 获取一组提交,而无需合并或变基并避免您指出的所有问题。

看看这个guide,前段时间帮了我很多。

【讨论】:

猜你喜欢
  • 2011-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-26
  • 1970-01-01
  • 2015-06-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多