dialex
dialex

Reputation: 2856

Merging branches from the same trunk into one of the branches

The drawing below shows what we have (RGB) and what we want to have (Purple).

enter image description here

On different time, we made three branches from trunk (features A to C). We already updated (merged) changes from trunk to each branch.

We could merge each branch into trunk, however, we want to merge branch B and C into A, and keep developing on branch A.

Is this possible, since branch B and C were not created from A but from trunk?

Upvotes: 2

Views: 598

Answers (1)

Patrick Quirk
Patrick Quirk

Reputation: 23747

You'll need to use a 2-URL merge, as the text from svn help merge explains:

  1. This form is called a '2-URL merge':

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

    You should use this merge variant only if the other variants do not apply to your situation, as this variant can be quite complex to master.

    Two source URLs are specified, identifying two trees on the same branch or on different branches. The trees are compared and the difference from SOURCE1@REV1 to SOURCE2@REV2 is applied to the working copy of the target branch at TARGET_WCPATH. The target branch may be the same as one or both sources, or different again. The three branches involved can be completely unrelated.

    [...]

    2-URL Merge Example:

    Two features have been developed on separate branches called 'foo' and 'bar'. It has since become clear that 'bar' should be combined with the 'foo' branch for further development before reintegration.

    Although both feature branches originate from trunk, they are not directly related -- one is not a direct copy of the other. A 2-URL merge is necessary.

You say each branch has had all changes from trunk merged into it, so there should be no need to specify a revision for the first source.

First have a clean checkout of your A branch. Then, merge B to A:

svn merge ^/trunk ^/branches/B

This will merge the differences between B and trunk into your working copy, which is A. Verify and commit those changes (you can preview the merge by substituting diff for merge in the above command):

svn commit -m "Merging B to A"

Next, merge C to A:

svn merge ^/trunk ^/branches/C

This will merge the differences between C and trunk into your working copy, which is A with B's changes. Verify and commit those changes, and now your A branch will have all of B's and C's changes.


To verify this I created a simple script (Windows batch file). It starts by setting some path constants:

@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%

Then create a repository and 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%

Alternate between creating dummy content and branches so the branches have different contents:

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"

Now synchronize the branches by merging from 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"

Create some different content in branches B and C so a merge will actually do something:

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"

Switch our working copy back to branch A:

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

Now, we're ready for our merge of B onto 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.

So now epsilon.txt is in our A branch. Let's now merge C onto 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.

This merged zeta.txt into A, and we can verify that if we look at A now:

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

Upvotes: 2

Related Questions