30

How to merge branch back to trunk in SVN with all commit history? I know in Git I can use

merge -squash

Is there any equivalent command in SVN? I am using SVN 1.6.

zs2020
  • 53,766
  • 29
  • 154
  • 219
  • 4
    Which version of SVN is running on the server? 1.5 and later makes a huge difference to your question versus 1.4 or earlier. – William Leara Aug 24 '10 at 19:28

5 Answers5

43

With Subversion 1.5 or later the merge is recorded on your local working copy in the svn:mergeinfo property. So this information is not lost.

You can see the merged revisions if you use svn log -g instead of the normal svn log.

Normal merges are performed as

svn merge -rREV1:REV2 svn://server/branch my_trunk_wc 

But if you use a branch it is sometimes more convenient to use a reintegration merge. In this case you should first merge all trunk changes to the branch using something like

svn merge svn://server/trunk my_branch_wc

(This merges everything that is not already merged)

And after you commit this change to the branch you can use

svn merge --reintegrate svn://server/branch my_trunk_wc

To move all changes over as a single commit. (After this operation you should remove the branch)

Bert Huijben
  • 19,525
  • 4
  • 57
  • 73
  • _"after this operation you should remove the branch"_ . Why, shouldn't it just be "can remove" ? I like keeping all history around as long as it does not cause any issues. – Zitrax Oct 05 '15 at 10:10
  • 3
    The history is still around in the old revision as you can see when running `svn log -g`. But you shouldn't use the branch any more as it can't be merged again without more bookkeeping. (Note that much newer Subversion versions (1.8+) dropped the --reintegrate requirement and can even make the branch usable again with the right merge from trunk) – Bert Huijben Nov 13 '15 at 12:10
  • So suppose new branch is created. Suppose after that, the new branch incurs commits b1, b2 and b3, and trunk incurs commits, t1, t2, and t3. After performing your two phase merge, will an svn log of trunk contain separate commit entries for b1, b2, b3, t1, t2, and t3? – JohnC Mar 06 '19 at 19:42
6

To create a merge of a branch and create a single commit for each commit in the branch you can use a script, I'm using the following:

#/bin/bash

BRANCH="http://your branch url"

for i in {1127..1138} # list of revisions
do
  REV=$i
  echo $REV $BRANCH
  echo merged $REV from $BRANCH > tmps.commit
  svn log -c $REV $BRANCH >> tmps.commit
  svn up
  svn merge -c $REV $BRANCH ./
  svn commit -F tmps.commit
  rm tmps.commit
done

This will check out each revision you specify for the specific branch and perform a commit on the current directory, thus preserving each single change with the corresponding message.

Elmar Weber
  • 2,683
  • 28
  • 28
  • I just used this script successfully and it does work well. The only consideration is that as this script loops over all revision numbers from X to N, they are not purely consecutive numbers, we may have revision 1131 followed by revision 1135 for example. In this case we will merge a blank revision commit into the new branch creating a commit with no changes. I may modify this script next time to check if tmps.commit is empty and if so 'continue' to avoid these extra no change commits. Since SVN does not allow a commit without a comment this should work as expected. – jcpennypincher Oct 20 '14 at 20:56
  • [Windows version of the above script](https://stackoverflow.com/a/56139196/1529709) which also adds the skip-empty-commit-check as envisioned by [jcpennypincher](https://stackoverflow.com/users/407379/jcpennypincher). – zb226 Jun 26 '19 at 09:08
5

I'm a bit rusty with merging, but shouldn't that do the trick ?

svn merge -rREV1:REV2 svn://server/branch my_trunk_wc

See:

svn merge --help
DarkDust
  • 90,870
  • 19
  • 190
  • 224
  • 1
    it will just merge into your working copy, that you'll then commit - but the trunk history will remember only this commit - without the ones from the branch – Dmitry Yudakov Aug 20 '10 at 15:29
  • I think you're right... I was confusing with `copy` which preserves history. – DarkDust Aug 20 '10 at 16:28
  • 2
    Isn't this what `svn:mergeinfo` is for? – detly Aug 24 '10 at 02:53
  • 10
    With Subversion 1.5 or later the merge is recorded on your local working copy in the svn:mergeinfo property. So this information is not lost. You can see the merged revisions if you use svn log -g instead of the normal svn log. – Bert Huijben Aug 24 '10 at 08:07
  • @Bert Huijben: I think you gave the correct answer. Please make it an answer so that I can give you the bounty. Thanks. – zs2020 Aug 30 '10 at 17:35
1

You can save each changeset as a diff and then commit each one atop the trunk. This is commonly called "transplanting", and there are various tools to do this automatically.

Borealid
  • 95,191
  • 9
  • 106
  • 122
0

It sounds like you want to:

  1. Merge from possibly several branches.
  2. Have all the merges properly recorded as such.
  3. Commit as one new revision only.

I think this is supported by the underlying SVN architecture. But I don't know if there are any clients that provide it (though svnmucc will do it for multiple cp, mv, rm commands). Unless you want to do more research than I have (which would not take much), or write your own client which can drive the SVN libraries to do it (which may be hard but still doable); then I think you will have to sacrifice one of 2. and 3. above.

(If you sacrifice 3 you could dump the repository immediately after and hack the dump file to use one revision only, but I don't think it's worth the risk just to have a minutely simpler revision history...)

Edmund
  • 10,533
  • 3
  • 39
  • 57