Svn Subversion:在分支中进行多个连续更改时,如何仅将特定修订合并到主干中?

Svn Subversion:在分支中进行多个连续更改时,如何仅将特定修订合并到主干中?,svn,version-control,merge,three-way-merge,Svn,Version Control,Merge,Three Way Merge,我一直在使用OrtoiseSVN、svn和subclipse,我认为我了解基本原理,但有一件事困扰了我一段时间:合并引入了不需要的代码。这是步骤 trunk/test。txt@r2。创建了带有“A”和返回的测试文件: A [EOF] 分支/尝试XX Foo/test。txt@r3。将主干扩展到尝试XX Foo: A [EOF] 分支/尝试XX Foo/test。txt@r4。在中进行了不必要的更改TRY XX Foo并提交: A B (unwanted change) [EOF] A B

我一直在使用OrtoiseSVN、svn和subclipse,我认为我了解基本原理,但有一件事困扰了我一段时间:合并引入了不需要的代码。这是步骤

trunk/test。txt@r2
。创建了带有“A”和返回的测试文件:

A
[EOF]
分支/尝试XX Foo/test。txt@r3
。将
主干扩展到
尝试XX Foo

A
[EOF]
分支/尝试XX Foo/test。txt@r4
。在
中进行了不必要的更改TRY XX Foo
并提交:

A
B (unwanted change)
[EOF]
A
B (unwanted change)
C (important bug fix)
[EOF]
分支/尝试XX Foo/test。txt@r5
。在
TRY XX Foo
中修复了一个重要的bug并提交了它:

A
B (unwanted change)
[EOF]
A
B (unwanted change)
C (important bug fix)
[EOF]
现在,我只想将重要的bug修复合并回trunk。因此,我对修订版运行merge
4:5
。我在工作目录中的结果是冲突

trunk/test.txt

A
<<<<<<< .working
=======
B (unwanted change)
C (important bug fix)
>>>>>>> .merge-right.r5
[EOF]
A
>.merge-right.r5
[EOF]
违背我的意愿,Subversion现在在主干代码中包含了“不需要的更改”,我需要手动删除它们。在分支中进行多个连续更改时,是否有方法仅合并指定的修订

问题的一部分是B(未经修改的更改)包含在.merge right中,我无法区分它来自哪个版本。我通常用乌龟,下面是它的样子


仅将修订版4、7和11-15与以下内容合并:

对于常规svn:

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

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

问题是,两个svn

A
<<<<<<< .working
=======
B (unwanted change)
C (important bug fix)
>>>>>>> .merge-right.r341
A
>.merge-right.r341
陆龟VN将这种情况视为双向合并。我听说过三方合并这个术语,所以我试了一下。使用OrtoiseSVN快速设置后,“编辑冲突”现在将显示以下屏幕。这并不完美,因为它仍然需要人工干预,但至少我可以知道哪些变化来自哪里


.

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

陆龟vn

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

命令行

要对命令行客户端执行此操作,您需要执行反向合并(这是从使用Subversion book的实用源代码管理中获取的),在这里,您可以将有问题的版本和以前版本之间的更改合并到文件的工作副本中。然后,如上所述,您将提交更改,然后可以正常进行分支。在您的示例中,您可以执行以下操作:

svn merge -r 4:3 test.txt

我相信您正确地包含了所需的修订,但是合并算法无法找到插入所需更改的位置,因此也包含了上面的行。以下是相同的步骤,但有不同的更改,我相信它的工作原理与您最初预期的一样:

$ 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 $svnadmin创建回购 $svn mkdir-m“”文件://`pwd`/repo/trunk 承诺修订1。 $svn mkdir-m“”文件://`pwd`/repo/branchs 承诺修订2。 $svn co文件://`pwd`/repo/trunk co.trunk 已签出修订版2。 $cat>co.trunk/test.txt A >B >C >EOF $svn add co.trunk/test.txt A co.trunk/test.txt $svn提交-m''co.trunk 添加co.trunk/test.txt 传输文件数据。 承诺修订3。 $svn copy-m“”文件://`pwd`/repo/trunk文件://`pwd`/repo/branchs/testbr 承诺修订4。 $svn co file://`pwd`/repo/branchs/testbr co.testbr A co.testbr/test.txt 已签出修订版4。 $cat>co.testbr/test.txt A >不需要的 >B >C >EOF $svn提交-m''co.testbr 发送co.testbr/test.txt 传输文件数据。 承诺修订5。 $cat>co.testbr/test.txt A >不需要的 >B >B1通缉犯 >C >EOF $svn提交-m''co.testbr 发送co.testbr/test.txt 传输文件数据。 承诺修订6。 $svn merge-r 5:6文件://`pwd`/repo/branchs/testbr co.trunk ---将r6合并到“co.trunk”: U co.trunk/test.txt $cat co.trunk/test.txt A. B B1通缉犯 C
正如其他用户所指出的那样(我没有注意到这一点,所以我不认为这是值得赞扬的),可能是这种合并的琐碎性质(即缺少更改的上下文)让工具感到困惑

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


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

要澄清关于合并的一点,它实际上有两个步骤

  • 合并
  • 承诺
  • 这意味着在合并完成后,可以对head和另一个分支进行手动差异,以确保合并是正确的。 如果有什么问题,比如你的情况, 您可以在提交之前手动修复它


    /Johan

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

    至于解决您在乌龟问题上的冲突: 手风琴