Subversion:当分支中进行多个连续更改时,如何仅将特定版本合并到主干?

18
我是一名有用的助手,能够翻译文本。
我已经使用TortoiseSVN、svn和subclipse,我认为我理解了基础知识,但有一件事情一直困扰着我:合并会引入不必要的代码。以下是步骤。 。创建了一个测试文件,并添加了“A”和一个回车符。
A
[EOF]

branches/TRY-XX-Foo/test.txt@r3。将trunk分支到TRY-XX-Foo

A
[EOF]

branches/TRY-XX-Foo/test.txt@r4。在TRY-XX-Foo中做了一个不想要的更改并提交:

A
B (unwanted change)
[EOF]

branches/TRY-XX-Foo/test.txt@r5。在TRY-XX-Foo分支中进行了重要的错误修复,并将其提交:

A
B (unwanted change)
C (important bug fix)
[EOF]

现在,我只想将重要的错误修复合并回主干。因此,我运行修订版4:5的合并。但是,在我的工作目录中,出现了冲突。

trunk/test.txt:

A
<<<<<<< .working
=======
B (unwanted change)
C (important bug fix)
>>>>>>> .merge-right.r5
[EOF]

Subversion不得已将“不需要的更改”包含在主干代码中,我需要手动清除它们。当在分支中进行多个连续更改时,有没有一种方法只合并指定的修订版本?
问题的一部分是B(不需要的更改)包含在.merge-right中,我无法区分它来自哪个修订版本。我通常使用TortoiseMerge,以下是它的外观。

text.txt.working


2
为了进行更真实的测试,您应该在更改的行之间添加一些“上下文”。文本差异和合并工具需要在更改之间添加几行上下文才能执行自动合并。当上下文不够大时,您将会看到冲突,就像您最后一个示例中所显示的那样。 - Bert Huijben
@Bert:请将其作为答案发布,以便进行投票。我认为你说得很有道理。 - Sunny Milenov
你能否编辑图片宽度?它会影响到问题文本的显示。 - Gavin Miller
LFSR Consulting 对于图片的大小提出了很好的建议,有人可以把它缩小一下吗? - Johan
8个回答

38

使用svnmerge仅合并修订版4、7和11-15:

svnmerge.py merge -r4,7,11-15

对于常规的svn:

svn merge -c4,7 -r10:15 http://.../branches/TRY-XX-Foo

从命令行运行仍会产生与TortoiseSVN相同的结果,导致冲突并拉取不必要的更改。 - Eugene Yokota
抱歉,我想我不理解你的情况。挑选要合并的修订版本就像我展示的那样(显然,就像你尝试的那样),我不确定问题出在哪里。 - orip
Orips的答案应该是正确的,并且可以给你想要的结果。也许你在命令行语句中没有留下第5个修订版本。那么显然你会将更改合并到合并中。 - boutta
@eed3si9n:我已经有一个形成的分支,向一个文件添加了(不想要的)更改,然后向同一文件添加了想要的更改,并将svn merge -c $revision URL合并到项目的主干中。这里$revision是所需更改的修订号。合并后,我只得到了想要的更改。 - boutta
我只使用命令行完成了所有操作,并加上了-c选项,因为在测试中,我只添加了两个进一步的修订,就像你的例子一样。 - boutta

5
问题是svn两种版本都存在。
A
<<<<<<< .working
=======
B (unwanted change)
C (important bug fix)
>>>>>>> .merge-right.r341

而TortoiseSVN将这种情况视为两方合并。我听说过三方合并的术语,所以我尝试了Beyond Compare。通过与TortoiseSVN的快速设置,编辑冲突现在会弹出以下屏幕。这还不完美,因为它仍然需要人工干预,但至少我可以知道哪些更改来自哪里。
请参见屏幕截图

使用Subclipse合并视图,您可以启用原始视图,从而获得三方合并视图。请检查右上角。 - Eduard Wirch
请将此信息放入您的问题中,因为这是一个答案。 - guerda
1
@guerda,我将3向合并工具的使用作为答案进行发布。 - Eugene Yokota
从技术上讲,你只是在改变数据的呈现方式。上面的文本已经是一个三方合并了,只是以一维的方式呈现。常规的合并是二维的呈现方式。你必须选择一个文件作为输出,并在与另一个文件进行比较时添加/删除更改...三方合并只是保留两个文件差异的一种方式,同时更改第三个文件。因此,从技术上讲,即使在上面的文本中使用一维差异(带有<<<<和====),你也可以解决问题。 - gcb

2

我相信你已经正确地包含了你想要的修改,但是合并算法无法找到要插入所需更改的位置,因此也包括它上面的一行。以下是相同的步骤,但使用不同的更改集,我相信它最初按照您的预期工作:

$ svnadmin create repo
$ svn mkdir -m '' file://`pwd`/repo/trunk
提交版本 1。 $ svn mkdir -m '' file://`pwd`/repo/branches
提交版本 2。 $ svn co file://`pwd`/repo/trunk co.trunk 检出版本 2。 $ cat > co.trunk/test.txt << EOF > A > B > C > EOF $ svn add co.trunk/test.txt A co.trunk/test.txt $ svn commit -m '' co.trunk 添加 co.trunk/test.txt 传输文件数据。 提交版本 3。 $ svn copy -m '' file://`pwd`/repo/trunk file://`pwd`/repo/branches/testbr 提交版本 4。 $ svn co file://`pwd`/repo/branches/testbr co.testbr A co.testbr/test.txt 检出版本 4。 $ cat > co.testbr/test.txt << EOF > A > A1 unwanted > B > C > EOF $ svn commit -m '' co.testbr 发送 co.testbr/test.txt 传输文件数据。 提交版本 5。 $ cat > co.testbr/test.txt << EOF > A > A1 unwanted > B > B1 wanted > C > EOF $ svn commit -m '' co.testbr 发送 co.testbr/test.txt 传输文件数据。 提交版本 6。 $ svn merge -r 5:6 file://`pwd`/repo/branches/testbr co.trunk --- 正在将 r6 合并到 'co.trunk' 中: U co.trunk/test.txt $ cat co.trunk/test.txt A B B1 wanted C

2

关于合并的事情,需要澄清的是它实际上有两个步骤。

  1. 合并
  2. 提交

这意味着在完成合并后,您可以手动对比主分支和其他分支以确保合并正确。如果有问题,例如在您的情况下,您可以在提交之前手动修复它。

/ Johan


2
在TortoiseSVN中,您只需要指定要合并的修订版本。与命令行客户端不同,在命令行客户端中,您必须指定例如-r4:5来合并r4和r5之间的更改,而在TortoiseSVN合并对话框中,您只需指定“5”作为要合并的修订版本号。如果您不确定,请始终使用合并对话框中的日志对话框,并在该日志对话框中选择要合并的修订版本(然后单击“确定”,所选修订版本将自动设置在合并对话框中)。
至于在TortoiseMerge中解决冲突: 根据您问题中的屏幕截图,TortoiseMerge向您显示了两个有冲突的行(在底部视图中显示为“?”)。 您想要包含变更“C”但不包括“B”吗?
1. 左键单击第一个“?”行以选择它,然后右键单击,从上下文菜单中选择“使用我的块”。 2. 左键单击第二个“?”行以选择它,然后右键单击,从上下文菜单中选择“使用他们的块”。 3. 单击保存按钮(或文件->保存)。 4. 可选地单击“标记为已解决”按钮。

首先,感谢您提供如此优秀的工具。我一直在关注TortoiseSVN的更新,所以我知道您需要指定5,而不是4-5。 - Eugene Yokota
在这个简化的例子中,很容易发现“不需要”的部分,但是Subversion不应该从r4带来任何变化。实际情况中,很难确定哪些部分来自我没有指定的不需要的版本。我经常合并其他人编写的分支更改。 - Eugene Yokota
嗯,Subversion实际上没有合并r4。你在这里看到的问题是Subversion遇到了冲突,并为了指示该冲突,它不仅标记了冲突行,还标记了冲突行周围的1行(即上下文行)。如果您有一行D,那么该行也将被标记。 - Stefan
被包含在冲突中。因此,实际上仍然很容易发现那些“不需要”的行。此外,如果您有更多的上下文行(此示例几乎没有上下文行,几乎所有行都包含在合并中),Subversion 在合并方面会更加准确。 - Stefan

1

正如其他用户所指出的(我不会因为没有注意到而获得荣誉),可能是这种合并的微不足道的特性(即缺乏变更周围的上下文)使工具感到困惑。

我经常进行合并,就像你发现的那样,Tortoise提供的合并工具很糟糕。如果您经常这样做,请使用三方合并工具。Beyond Compare是我个人最喜欢的,但还有其他免费的工具(Meld、KDiff3)和付费工具(Araxis)。

您将会注意到,在最后,Beyond Compare做了正确的事情,即使它需要您手动验证其正确性!


缺乏上下文肯定是关键,因此是“多个连续的更改”。 - Eugene Yokota

1

你可以手动撤销分支上的错误提交,然后像平常一样将分支合并回主干。

TortoiseSVN

使用TortoiseSVN,你可以在文件上打开日志视图,选择有问题的版本,然后从右键菜单中选择“还原此修订版本的更改”。提交它对你的工作副本所做的更改,然后你就可以轻松地将分支合并回来了。

命令行

要使用命令行客户端执行此操作,你需要执行反向合并(这是从《实用的源代码控制使用Subversion》书中摘取的),即将有问题的版本和前一个版本之间的更改合并到文件的工作副本中。然后像上面那样提交更改,就可以正常分支了。在你的例子中,你可以这样做:

svn merge -r 4:3 test.txt

撤销不是一个选项,因为分支/TRY-XX-Foo/中的不需要更改代表了半成品功能,还没有准备好合并到主干。 - Eugene Yokota

0
如果您不想要不必要的更改,请不要合并修订版本4:5,而只合并修订版本5。这意味着您将合并在修订版本5中提交的更改。

4:5 意味着取 4 和 5 之间的差异并将其应用于工作目录。我尝试了 -c5 命令行选项,但结果是相同的。 - Eugene Yokota

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