Mercurial:虚拟合并后,分支特定的更改会继续出现 [英] Mercurial: Branch specific changes keep coming back after dummy merge
问题描述
我有一个Mercurial存储库,其中有两个永久分支,默认分支和UAT.我们不时地将应用程序的新版本部署(推广)到UAT环境中,我们通过将稳定的默认提交合并到UAT分支来做到这一点.有时,某些问题会在UAT分支中得到错误修复,并且这些错误修复会重新合并为默认值.
I have a mercurial repository with two permanent branches, default and UAT. Every once in a while, we deploy (promote) a new version of our application to the UAT environment and we do this by merging a stable default commit across to the UAT branch. Occasionally things will get bug-fixed in the UAT branch, and these bug-fixes get merged back to default.
在UAT分支上,出于部署目的,我需要更改一些内容-连接字符串和各种环境设置.我试图做的就是在UAT分支中进行这些更改,并在将默认值合并到UAT之后立即提交它们(全部作为一次提交).然后,我将这一提交虚拟化为默认值,这是因为默认值现在在其祖先中已经有了该提交,将来的错误修正从UAT合并到默认值将不会尝试重做这些特定于UAT的更改.
On the UAT branch I need to change a few things for deployment purposes - connection strings and various environmental settings. What I tried to do was to make these change in the UAT branch and commit them (all as one commit) right after having merged default into UAT. I then dummy-merged this one commit back onto default - the thinking being that because default now has this commit in its ancestry future bugfix merges from UAT onto default will not try to redo these UAT-specific changes.
但是事情并没有像我希望的那样顺利.从虚拟合并提交到默认值开始,我尝试了以下两种情况:
However things have not gone as smoothly as I had hoped. Starting with the dummy-merged commit onto default, I've tried both of the following scenarios:
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之间,我删除了所有内容,以便使两种情况都从同一点开始.
In between running #1 and #2 I've stripped everything out so that both scenarios start from the same point.
我看到的是,根据合并的最后方向,在进行一个或另一个合并并还原后,我仍然需要检查更改的文件-有时合并尝试将默认配置放入UAT中,有时将UAT配置中合并.
What I'm seeing is that depending on the last direction merged I still need to inspect the changed files after doing one or the other merge and revert - sometimes the merge tries to put the default configurations into UAT and sometimes the UAT configurations into merge.
如果我恢复配置更改并提交合并,则将来在同一方向上的合并会正常进行,但是当我朝另一个方向进行操作时,合并会再次将错误的配置放入文件中.
If I revert the configuration changes and commit the merge, then future merges in the same direction behave properly, but the minute I go in the other direction, the merge again puts the wrong configurations into the files.
我想念什么?
推荐答案
我认为问题类似于此问题:合并不会像您认为的那样起作用.合并仅是比较文件状态的问题,而不是将更改从一个分支应用于另一个分支的问题.
I believe the problem is similar to the problem in this question: merging doesn't work the way you think it works. Merging is only a question of comparing file-states, it's not a matter of applying changes from one branch onto another.
您的起点是这样的历史:
Your starting point is a history like this:
UAT: ... x --- y --- z
\
default: ..... a --- b --- c
其中x
和y
包含UAT的配置设置,而b
是没有配置设置的虚拟合并.因此,b
中的文件看起来就像在a
中的文件一样-它们是虚拟合并的.
where x
and y
contain the config settings for UAT and b
is the dummy merge with no config settings. So the files in b
look like they did in a
— they were dummy merged.
如果您现在要在default
上进行新更改以升级为UAT,则可以使用:
If you now make a new change on default
that you want to promote to UAT, you'll work with:
UAT: ... x --- y
\
default: ..... a --- b --- c
合并在y
和c
之间.这是一个简并的合并,其中共同祖先是y
本身.这意味着b
和c
之间的所有更改将在三路合并中获胜".大块如何在三向合并中合并的表为:
The merge is between y
and c
. It's a degenerate merge where the common ancestor is y
itself. This means that all changes between b
and c
will "win" in the three-way merge. The table for how hunks are merged in a three-way merge is:
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)
请注意,合并结果不取决于合并的方向":表关于local
和other
列是对称的.此处,ancestor
和local
均为y
,而other
为c
.因此表变为:
Note that the merge result doesn't depend on the "direction" of the merge: the table is symmetric with regard to the local
and other
columns. Here, both ancestor
and local
is y
, and other
is c
. So the table becomes:
ancestor local other -> merge
old old new new (they changed the hunk)
您可以看到合并结果始终包含在c
中进行的new
更改.
You can see that the merge result always contains the new
change that was made in c
.
合并退化并不重要.假设您有一个关于UAT的新提交,并且此提交不涉及配置字符串,那么合并时您将获得相同的行为(在任一方向上,合并都是对称的).
It's not important that the merge was degenerate. Assuming you have a new commit on UAT and that this commit doesn't touch the config strings, then you'll get the same behavior when you merge (in either direction, merges are symmetric).
此问题的常规解决方案是外部化配置字符串.将它们放在版本控制之外的某个位置(环境变量,未版本控制的配置文件等).如果可以,然后将配置文件作为 template 置于版本控制下.然后,您为UAT分支创建一个未版本控制的配置文件,其中包括版本控制的配置文件.您可以根据需要在此未版本控制的配置文件中覆盖设置.
The normal solution to this problem is to externalize the config strings. Put them somewhere outside of version control — environment variables, an unversioned config file, etc. If you can, then put a config file under version control as a template. You then create an unversioned config file for the UAT branch that includes the version controlled config file. You override settings as needed in this unversioned config file.
这篇关于Mercurial:虚拟合并后,分支特定的更改会继续出现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!