Mercurial:分支特定的更改在虚拟 merge 后不断出现

标签 mercurial merge

我有一个带有两个永久分支的 mercurial 存储库,default 和 UAT。每隔一段时间,我们就会将应用程序的新版本部署(推广)到 UAT 环境,我们通过将稳定的默认提交 merge 到 UAT 分支来实现这一点。有时会在 UAT 分支中修复错误,这些错误修复会 merge 回默认值。

在 UAT 分支上,为了部署目的,我需要更改一些内容 - 连接字符串和各种环境设置。我试图做的是在 UAT 分支中进行这些更改,并在将默认值 merge 到 UAT 后立即提交它们(全部作为一次提交)。然后我将这个提交虚拟 merge 回默认值 - 想法是因为默认值现在在其祖先中具有此提交, future 从 UAT merge 到默认值的错误修复不会尝试重做这些特定于 UAT 的更改。

然而事情并没有我想象的那么顺利。从虚拟 merge 提交到默认值开始,我尝试了以下两种情况:

1) Make a few more commits to default and then "promote" to UAT (merge default onto UAT)
2) Make a bugfix on UAT and "backport" it to default (merge UAT onto default)

在运行 #1 和 #2 之间,我删除了所有内容,以便两个场景都从同一点开始。

我看到的是,根据 merge 的最后一个方向,我仍然需要在执行一个或另一个 merge 和还原后检查更改的文件 - 有时 merge 尝试将默认配置放入 UAT,有时将 UAT 配置放入 merge 。

如果我恢复配置更改并提交 merge ,那么将来在同一方向上的 merge 行为正常,但是当我朝另一个方向前进时, merge 再次将错误的配置放入文件中。

我错过了什么?

最佳答案

我相信这个问题类似于 this question 中的问题: merge 并不像你认为的那样工作。 merge 只是比较文件状态的问题,它是 不是 将更改从一个分支应用到另一个分支的问题。

您的起点是这样的历史:

UAT:      ... x --- y --- z
                           \
default:  ..... a --- b --- c

哪里xy包含 UAT 和 b 的配置设置是没有配置设置的虚拟 merge 。所以b中的文件看起来就像他们在 a 中所做的那样——他们是虚拟 merge 的。

如果您现在对 default 进行新的更改如果您想推广到 UAT,您将与:
UAT:      ... x --- y 
                     \
default:  ..... a --- b --- c

merge 在 y 之间和 c .这是一个退化 merge ,其中共同的祖先是 y本身。这意味着 b 之间的所有更改和 c将在三路 merge 中“获胜”。在三路 merge 中如何 merge 帅哥的表格是:
ancestor  local  other -> merge
old       old    old      old (nobody changed the hunk)
old       old    new      new (they changed the hunk)
old       new    old      new (you changed the hunk)
old       new    new      new (hunk was cherry picked onto both branches)
old       foo    bar      <!> (conflict, both changed hunk but differently)

请注意, merge 结果不依赖于 merge 的“方向”:该表关于 local 是对称的。和 other列。在这里,两个 ancestorlocaly , 和 otherc .所以表格变成了:
ancestor  local  other -> merge
old       old    new      new (they changed the hunk)

可以看到 merge 结果总是包含newc 中进行的更改.

merge 是否退化并不重要。假设您在 UAT 上有一个新提交,并且此提交不涉及配置字符串,那么您在 merge 时将获得相同的行为(在任一方向, merge 都是对称的)。

正常解决方案这个问题是外部化配置字符串。将它们放在版本控制之外的某个地方——环境变量、未版本控制的配置文件等。如果可以,请将配置文件放在版本控制下作为模板。然后为包含版本控制配置文件的 UAT 分支创建一个未版本控制的配置文件。您可以根据需要覆盖此未版本化配置文件中的设置。

关于Mercurial:分支特定的更改在虚拟 merge 后不断出现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9532823/

相关文章:

mercurial - 推送 SSH 时抑制 TortoiseHg 中的 "Push to remote repository?"提示

mercurial - 从过去的 mercurial 分支

python - 使用相同的键在 Python 中合并两个字典

merge - 当 KEY 已作为批处理存在时,Cassandra 更新或插入

python - 通过合并更好地替代 groupby

architecture - 用于功能、稳定版本等的 Mercurial 存储库结构

mercurial - 有没有人有一个脚本可以一次处理多个hg存储库?

templates - TortoiseHG 中的提交消息模板

sql - ORACLE/SQL - 需要帮助优化 'merge' 样式脚本

xml - 如何使用 XSLT(可以是 XSLT 2.0)合并两个 XML 文档?