Subversion:如果在分支中进行多次连续更改,如何仅将特定修订合并到trunk中?

时间:2008-11-29 00:09:28

标签: svn version-control merge three-way-merge

我一直在使用TortoiseSVN,svn和subclipse,我认为我理解基础知识,但有一件事一直困扰着我:合并引入了不需要的代码。这是步骤。

trunk/test.txt@r2。使用“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]

现在,我想只将重要的bug修复程序合并到trunk。所以,我为版本4:5运行合并。我最终在工作目录中发生了冲突。

trunk/test.txt

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

违背我的意愿,Subversion现在已将“不需要的更改”包含在中继代码中,我需要手动清除它们。当在分支中进行多次连续更改时,是否有办法仅合并指定的修订版?

问题的一部分是B(unwated change)包含在.merge-right中,我无法区分它来自哪个版本。我通常使用TortoiseMerge,这是它的外观。

text.txt.working

8 个答案:

答案 0 :(得分:37)

仅将修订版4,7和11-15与svnmerge合并:

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

使用常规svn:

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

答案 1 :(得分:5)

问题是两者都是svn

A
<<<<<<< .working
=======
B (unwanted change)
C (important bug fix)
>>>>>>> .merge-right.r341

和TortoiseSVN将这种情况视为双向合并。我听说过3-way merge这个术语,所以我给了Beyond Compare一个镜头。通过使用TortoiseSVN进行快速设置,编辑冲突现在会显示以下屏幕。这并不完美,因为它仍然需要人工干预,但至少我可以判断哪些变化来自哪里。

See screenshot

答案 2 :(得分:2)

我相信您正在包含您想要的修订版,但合并算法无法找到插入所需更改的位置,因此也包括它上面的行。以下是相同的步骤,但是有一组不同的更改,我相信它的工作方式与您最初的预期相同:

$ svnadmin create repo
$ svn mkdir -m '' file://`pwd`/repo/trunk

Committed revision 1.
$ svn mkdir -m '' file://`pwd`/repo/branches

Committed revision 2.
$ svn co file://`pwd`/repo/trunk co.trunk
Checked out revision 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
Adding         co.trunk/test.txt
Transmitting file data .
Committed revision 3.
$ svn copy -m '' file://`pwd`/repo/trunk file://`pwd`/repo/branches/testbr

Committed revision 4.
$ svn co file://`pwd`/repo/branches/testbr co.testbr
A    co.testbr/test.txt
Checked out revision 4.
$ cat > co.testbr/test.txt << EOF
> A
> A1 unwanted
> B
> C
> EOF
$ svn commit -m '' co.testbr
Sending        co.testbr/test.txt
Transmitting file data .
Committed revision 5.
$ cat > co.testbr/test.txt << EOF
> A
> A1 unwanted
> B
> B1 wanted
> C
> EOF
$ svn commit -m '' co.testbr
Sending        co.testbr/test.txt
Transmitting file data .
Committed revision 6.
$ svn merge -r 5:6 file://`pwd`/repo/branches/testbr co.trunk
--- Merging r6 into 'co.trunk':
U    co.trunk/test.txt
$ cat co.trunk/test.txt
A
B
B1 wanted
C

答案 3 :(得分:2)

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

  1. 合并
  2. 提交
  3. 这意味着在完成合并后,您可以对头部和另一个分支进行手动差异,以确保合并正确。 如果出现问题,就像你的情况一样, 您可以在提交之前手动修复它。

    /约翰

答案 4 :(得分:2)

在TortoiseSVN中,您只能指定要合并的修订。与您必须指定的命令行客户端不同,例如-r4:5合并r4和r5之间的更改,您只需指定'5'作为要在TortoiseSVN合并对话框中合并的修订号。如果您不确定,请始终使用合并对话框中的日志对话框,然后在该日志对话框中选择要合并的修订版(然后单击“确定”,将在合并对话框中自动设置所选修订版本。)

至于解决TortoiseMerge中的冲突: 根据您问题中的屏幕截图,TortoiseMerge会显示两条冲突的线条(底部视图中显示为“????”的线条)。 你想要的是包括改变'C'而不是'B'?

  • 左键点击第一个'???'选择它,然后右键单击,从上下文菜单中选择“使用块”“我的”
  • 左键点击第二个'???'要选择它,然后右键单击,从上下文菜单中选择“使用”他们的“块”
  • 点击保存按钮(或文件 - >保存)
  • (可选)单击“标记为已解决”按钮

答案 5 :(得分:1)

您可以做的另一件事是手动撤消分支上的错误提交,然后允许您像往常一样将分支合并回主干。

<强> TortoiseSVN的

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

命令行

要使用命令行客户端执行此操作,请执行反向合并(这取自使用Subversion书的Pragmatic源代码控制),其中将违规版本和先前版本之间的更改合并到文件的工作副本中。然后如上所述,您将提交更改,然后可以正常分支。在您的示例中,您将执行以下操作:

svn merge -r 4:3 test.txt

答案 6 :(得分:1)

正如其他用户所指出的那样(我不会因为我没有注意到这一点而受到赞扬),但这种合并的微不足道的性质(即缺乏关于变化的背景)可能会使工具混乱。

我做了很多合并,正如你所发现的,Tortoise提供的合并工具很糟糕。如果经常这样做,三向合并工具绝对是必须的。超越比较是我个人的最爱,但还有其他免费(Meld,KDiff3)和非(Araxis)。

你会注意到Beyond Compare最终做了正确的事情,即使它让你手动验证它的正确性!

答案 7 :(得分:0)

如果您不希望进行不必要的更改,请不要合并修订版本4:5,而只修改版本5.这意味着您合并修订版本5中提交的更改。