I am working in a simple repository, with a truck and one branch. No change s have been made to the trunk since the branch, and a number of commits have been made on the branch. How do I merge the branch back into the trunk so that I get the full history included changes while it was in the branch in one history?
2 Answers
Usually in Subversion, one merges whole ranges into a single commit, like a squash merge in git:
svn merge -r[REVISION1]:[REVISION2] svn://[REPO-URL]/[BRANCH] [TRUNK-DIR]
Since Subversion 1.5, the information about the individual original commits is retained in the svn:mergeinfo
property. In TortoiseSVN, you can find these under the menu item "Properties". On the command line, you can query that information as follows:
svn propget "svn:mergeinfo" [PATH]
If you really want to have a single merge commit per original commit, you need to do these yourself - which I imagine to be quite painful, especially with TortoiseSVN.
Alternatively, you can use a script to do the commits for you. Since you're using TortoiseSVN, I'm sure you're using Windows, so I whipped up a quick batch file to do the job. It will loop through a range of revisions, check if the source branch in fact has that revision, and if so, it will first merge it, and then commit it with a copy of the original commit message. [REVISION1]
will be the first commit of the source branch and [REVISION2]
will be the last commit of the source branch.
As it is and to keep things safe, this script only modifies your working copy (WC) by doing the svn merge
s, but it does not do the svn commit
s. So first, checkout the target branch (the trunk, in your case) into a fresh WC and inspect if this script runs as expected - i.e. if only the relevant revisions are merged into the WC. If so, checkout the target branch again into another fresh WC, and remove the last REM
in the script to activate committing.
@ECHO OFF
REM inspired by https://stackoverflow.com/a/6192099/1529709
SETLOCAL EnableDelayedExpansion
SET BRANCH=svn://[REPO-URL]/[BRANCH]
FOR /L %%G IN ([REVISION1],1,[REVISION2]) DO (
REM check if log is empty and only merge if not
svn log -c %%G %BRANCH% > tmp-log.txt
FINDSTR /V "\-----------" tmp-log.txt > NUL
IF NOT ERRORLEVEL 1 (
ECHO Merging revision %%G
ECHO merge commit from %BRANCH% > tmp-commit.txt && ECHO. >> tmp-commit.txt
TYPE tmp-log.txt >> tmp-commit.txt
svn merge -c %%G %BRANCH% .
REM *** check results first before you activate committing! ***
REM svn commit -F tmp-commit.txt
) ELSE (
ECHO Skipping revision %%G
)
)
IF EXIST tmp-commit.txt DEL tmp-commit.txt
IF EXIST tmp-log.txt DEL tmp-log.txt
Disclaimer: This script was inspired by this variant for linux (which doesn't check for empty revisions)

- 9,586
- 6
- 49
- 79
Thanks a lot for this batch. Works perfect for me! I have a small addition to it: I put svn update after the svn commit line. Like this:
svn commit -F tmp-commit.txt
svn update
otherwise on every next commit SVN would return you a message "Please, update your WC as you are trying to commit into a WC of not latest revision"

- 2,400
- 4
- 18
- 32

- 31
- 1
- 1
- 3