将来自同一主干的分支合并到其中一个分支中

时间:2016-01-14 16:34:54

标签: svn tortoisesvn branching-and-merging

下图显示了我们拥有的(RGB)和我们想要的东西(紫色)。

enter image description here

在不同的时间,我们从主干(功能A到C)制作了三个分支。我们已经从trunk更新(合并)更改到每个分支。

我们可以将每个分支合并到trunk但是,我们希望将分支B和C合并到A 中,并继续在分支A上进行开发。

这是否可行,因为分支B和C不是从A创建的,而是从trunk创建的?

1 个答案:

答案 0 :(得分:2)

您需要使用2-URL合并,因为svn help merge中的文字说明了这一点:

  
      
  1. 此表单称为' 2-URL合并':

         

    svn merge SOURCE1[@REV1] SOURCE2[@REV2] [TARGET_WCPATH]

         

    仅当其他变体不使用时,才应使用此合并变体   适用于您的情况,因为此变体可能非常复杂   主

         

    指定了两个源URL,同时标识两个树   分支或在不同的分支机构。比较和树木   从SOURCE1 @ REV1到SOURCE2 @ REV2的差异应用于   TARGET_WCPATH目标分支的工作副本。目标   分支可以与一个或两个源相同,也可以不同。   涉及的三个分支可以完全不相关。

         

    [...]

         

    2-URL合并示例:

         

    已经在不同的分支机构上开发了两个功能,称为“foo'和   '栏&#39 ;.从那以后,很明显,' bar'应该结合   这个' foo'在重返社会之前进一步发展的分支。

         

    虽然两个功能分支都来自主干,但它们不是   直接相关 - 一个不是另一个的直接副本。一个2-URL   合并是必要的。

  2.   

您说每个分支都已将 trunk 的所有更改合并到其中,因此不需要为第一个源指定修订。

首先清理 A 分支。然后,将 B 合并到 A

svn merge ^/trunk ^/branches/B

这会将 B trunk 之间的差异合并到您的工作副本中,即 A 。验证并提交这些更改(您可以通过在上面的命令中用diff替换merge来预览合并:

svn commit -m "Merging B to A"

接下来,将 C 合并到 A

svn merge ^/trunk ^/branches/C

这会将 C trunk 之间的差异合并到您的工作副本中, A B 的变化。验证并提交这些更改,现在您的 A 分支将包含所有 B C 的更改

为了验证这一点,我创建了一个简单的脚本(Windows批处理文件)。它首先设置一些路径常量:

@ECHO OFF

SET CWD=%~dp0
SET REPO_NAME=repo
SET REPO_PATH="%CWD%%REPO_NAME%"
SET WC_NAME=wc
SET WC_PATH="%CWD%%WC_NAME%"

:: Create REPO URI (C:\path\to\repo -> file:///C:/path/to/repo, see http://stackoverflow.com/a/27817626/1698557)
FOR /f "delims=" %%R IN (%REPO_PATH%) DO SET REPO_URL=%%~fR%
SET REPO_URL=file:///%REPO_URL%
SET REPO_URL=%REPO_URL:///\\=//%
SET REPO_URL=%REPO_URL:\=/%
SET REPO_URL="%REPO_URL%"

:: Cleanup previous run
RMDIR /S /Q %REPO_PATH%
RMDIR /S /Q %WC_PATH%

然后创建一个存储库和checkout trunk:

svnadmin create %REPO_PATH%
svn mkdir %REPO_URL%/trunk -m "Creating trunk directory"
svn mkdir %REPO_URL%/branches -m "Creating branches directory"

:: Checkout trunk
svn checkout %REPO_URL%/trunk %WC_PATH%

在创建虚拟内容和分支之间交替,以便分支具有不同的内容:

echo alpha > %WC_PATH%\alpha.txt
svn add %WC_PATH%\alpha.txt
svn commit %WC_PATH% -m "Creating alpha.txt in trunk"
svn copy %REPO_URL%/trunk %REPO_URL%/branches/A -m "Creating branch A"

echo beta > %WC_PATH%\beta.txt
svn add %WC_PATH%\beta.txt
svn commit %WC_PATH% -m "Creating beta.txt in trunk"
svn copy %REPO_URL%/trunk %REPO_URL%/branches/B -m "Creating branch B"

echo gamma > %WC_PATH%\gamma.txt
svn add %WC_PATH%\gamma.txt
svn commit %WC_PATH% -m "Creating gamma.txt in trunk"
svn copy %REPO_URL%/trunk %REPO_URL%/branches/C -m "Creating branch C"

echo delta > %WC_PATH%\delta.txt
svn add %WC_PATH%\delta.txt
svn commit %WC_PATH% -m "Creating delta.txt in trunk"

现在通过从trunk合并来同步分支:

svn switch %REPO_URL%/branches/A %WC_PATH%
svn merge %REPO_URL%/trunk %WC_PATH%
svn commit %WC_PATH% -m "Synchronizing branch A with trunk"

svn switch %REPO_URL%/branches/B %WC_PATH%
svn merge %REPO_URL%/trunk %WC_PATH%
svn commit %WC_PATH% -m "Synchronizing branch B with trunk"

svn switch %REPO_URL%/branches/C %WC_PATH%
svn merge %REPO_URL%/trunk %WC_PATH%
svn commit %WC_PATH% -m "Synchronizing branch C with trunk"

在分支 B C 中创建一些不同的内容,这样合并实际上会做一些事情:

svn switch %REPO_URL%/branches/B %WC_PATH%
echo epsilon > %WC_PATH%\epsilon.txt
svn add %WC_PATH%\epsilon.txt
svn commit %WC_PATH% -m "Creating epsilon.txt in B"

svn switch %REPO_URL%/branches/C %WC_PATH%
echo zeta > %WC_PATH%\zeta.txt
svn add %WC_PATH%\zeta.txt
svn commit %WC_PATH% -m "Creating zeta.txt in C"

将我们的工作副本切换回分支 A

> svn switch %REPO_URL%/branches/A %WC_PATH%
D    wc\zeta.txt
 U   wc
Updated to revision 14.

现在,我们已准备好将 B 合并到 A

> svn merge %REPO_URL%/trunk %REPO_URL%/branches/B %WC_PATH%
--- Merging differences between repository URLs into 'wc':
A    wc\epsilon.txt
 G   wc
--- Recording mergeinfo for merge between repository URLs into 'wc':
 G   wc
Sending        wc
Adding         wc\epsilon.txt

> svn commit %WC_PATH% -m "Merged B to A"
Committing transaction...
Committed revision 15.

> svn update %WC_PATH%
Updating 'wc':
At revision 15.

现在 epsilon.txt 位于我们的 A 分支中。现在让我们将 C 合并到 A

> svn merge %REPO_URL%/trunk %REPO_URL%/branches/C %WC_PATH%
--- Merging differences between repository URLs into 'wc':
A    wc\zeta.txt
 G   wc
--- Recording mergeinfo for merge between repository URLs into 'wc':
 G   wc
Sending        wc
Adding         wc\zeta.txt

> svn commit %WC_PATH% -m "Merged C to A"
Committing transaction...
Committed revision 16.

> svn update %WC_PATH%
Updating 'wc':
At revision 16.

zeta.txt 合并到 A 中,如果我们现在查看 A ,我们可以验证:

> svn ls %REPO_URL%/branches/A
alpha.txt
beta.txt
delta.txt
epsilon.txt
gamma.txt
zeta.txt