Svnmerge.py - SubversionWiki (original) (raw)

svnmerge.py is a tool for automatic branch management. It allows branch maintainers to merge changes from and to their branch very easily, and automatically records which changes were already merged. This allows displaying an always updated list of changes yet to be merged, and totally prevents merge mistakes (such as merging the same change twice).

You can think of svnmerge as the equivalent of yellow sticky notes on a Subversion branch that record which revisions have been merged in already from one or more other branches, plus some useful functionality for viewing, managing and updating that information.

See our feature list for a more detailed description.

Features

FAQ

What problem does svnmerge solve? If we have to apply the same change to another branch, subversion already has a method for doing this.

Traditional subversion will let you merge changes, but it doesn't "remember" what you've already merged. It also doesn't provide a convenient way to exclude a change set from being merged. svnmerge.py automates some of the work, and simplifies it. Svnmerge also creates a commit message with the log messages from all of the things it merged.

It sounds like maybe everyone has to use svnmerge if someone is going to get any use out of it... In other words, do manual merges wreck whatever it is svnmerge is trying to keep track of?

Manual merges don't wreck it, but it means that svnmerge doesn't give you quite as much benefit. However, once you've done an svnmerge on already manually propogated changes, the changes that were already propogated will be recorded as "merged" in its state tracking. From then onward, svnmerge won't try to re-merge those changes.

Why is merging the same thing twice a problem? Subversion doesn't seem to care -- the working copy doesn't appear to have any other changes than when I merged it once.

Merging the same change twice isn't usually a problem. It's a problem in two situations:

  1. if you don't want a certain change. Then you have to exclude it every single time you do a merge.
  2. If your trunk and your branch are both diverging. Developer A makes a change to line 10 in the trunk, and Developer B makes a change to line 10 in the branch. They're conflicting changes. If you do repeated merging, you will have to manually resolve the conflict every time.

When I merge changes from my branch into the trunk and then later merge trunk into the branch, I get the error "Trying to add new property 'svnmerge-integrated' with value 'xxx' but property already exists with value 'yyy'.

Apply the patch discussed here to avoid the problem, and use "svn resolved ." to fix it. Note that there is some controversy around the patch - see this discussion for the details.

How do I migrate from svnmerge.py to Subversion 1.5's Merge Tracking?

Use svnmerge-migrate-history.py to convert the merge history written by svnmerge.py into Subversion 1.5's format.

System requirements

System requirements are down to a bare minimum, to lower as much as possible the bar for using the tool. Currently, you need:

Downloads

Link Description
svnmerge.py trunk version This is the default development version, which is usually very stable. Get it without worrying too much!
svnmerge.py 1.4-branch version This is the version shipped with SVN 1.4. It's less updated than the trunk version so it will usually have less features but maybe be a little more stable. Get this if the current trunk version is temporarily broken.
SvnMergeGui Windows GUI front-end application to svnmerge.exe

svnmerge.py is maintained within the Subversion repository. There is not a proper release plan or development map, so there are no official releases. svnmerge.py gets shipped with Subversion mostly 'the way it is' when Subversion itself is shipped. Thus, the trunk version is recommended: we believe it to be mostly stable (there is a quite extensive testsuite).

Mailing List

A svnmerge mailing list has been established. The mailing list is the place to go for information about active development and new features.

List archives are available at:

Development

Patches, bugfixes, and development of svnmerge are all discussed on the mailing list. Patches to svnmerge are also tracked using the 'svnmerge' subcomponent on the Subversion bug tracker.

To submit a patch or bug report, please follow the buddy system as described here, but use the svnmerge mailing list.

Quick Usage Overview

  1. Use svnmerge init to initialize merge tracking on a branch directory.
  2. Use svnmerge avail to review the revisions available for merging.
  3. Use svnmerge merge to merge in some or all available revisions from other branches.
  4. Commit the merge changes using svn commit.
  5. Return to step 2 and repeat.

Quick tutorials

What follows are two quick tutorials for two common usage cases.

Development branches

This tutorial assumes that you are working on a recently-created development branch, made off the trunk. It also assumes that the development branch has never merged changes from the trunk.

The svnmerge.py command works as a pull operation, so all commands are run from the development branch working copy. This example pulls changes made on the trunk to your development branch.

$ svnmerge.py init

This command will scan the branch history to find out when the branch was created, so to initialize merge tracking support. This needs to be done only once for each branch you want to use svnmerge.py on. You should run this command with-in the top-level directory of the branch, otherwise it won't work as expected.

$ svn ci -F svnmerge-commit-message.txt $ rm svnmerge-commit-message.txt

Or use your favourite commit message.

foo/branch1/$ svnmerge.py merge

or, without chdir:

foo/$ svnmerge.py merge branch1

and that's it! You will always get the svnmerge-commit-message.txt in the current directory. Then, review the merge, fix any eventual conflict, and commit. There is a handy commit message listing the logs of all the merged revisions (can be quite long), which many people find useful.

/path/to/dir/myworkingcopy$ svnmerge.py init /path/to/dir/myworkingcopy$ svn ci -F svnmerge-commit-message.txt /path/to/dir/myworkingcopy$ cd .. /path/to/dir$ svnmerge.py merge myworkingcopy

$ svnmerge.py avail # show only the revision numbers $ svnmerge.py avail --log # show logs of the revisions on the trunk available for merging $ svnmerge.py avail --diff # show diffs of the revisions on the trunk available for merging

Release branches

This tutorial assumes that you are working on a recently-created release branch, made off the trunk, in which no changes were previously merged. With release branch, we mean a branch commonly used to stabilize a release: only a few selected changes must be merged from the trunk, the others must be ignored.

The svnmerge.py command works as a pull operation, so all commands are run from the release branch working copy. This example pulls selected changes made on the trunk to your release branch.

$ svnmerge.py init

This command will scan the branch history to find out when the branch was created, so to initialize merge tracking support. This needs to be done only once for each branch you want to use svnmerge.py on.

$ svn ci -F svnmerge-commit-message.txt $ rm svnmerge-commit-message.txt

Or use your favourite commit message.

Note, however, that svnmerge.py generates the commit message directly from svn client's output, so, on Windows, it'll have an OEM encoding. You need to tell that to svn if your log messages contains non-ASCII characters, otherwise it'll assume an ANSI encoding and the message may be written incorrectly to the repository. Then, instead of the command above you should use:

$ svn ci --encoding IBM850 -F svnmerge-commit-message.txt $ rm svnmerge-commit-message.txt

To know the current encoding used in the console one can use the chcp command.

$ svnmerge.py avail # show only the revision numbers $ svnmerge.py avail --log # show logs of the revisions $ svnmerge.py avail --diff # show diffs of the revisions

$ svnmerge.py merge -r4500,4671,4812

Then review the changes and commit them. The automatically generated commit message (svnmerge-commit-message.txt) quotes the logs of the revisions that you have merged. These revisions will of course disappear from the list shown by svnmerge.py avail.

$ svnmerge.py block -r6456-6460,6881

and commit. These revisions will disappear from the list shown by svnmerge.py avail, so that you don't have to re-review them every time.

Merging development branches back to trunk

This tutorial assumes that you have an active development branch, made off the trunk, in which you made changes and want to merge back to the trunk.

The svnmerge.py command works as a pull operation, so all commands are run from the trunk working copy. This example pulls changes made on the development branch to your trunk.

Handy Usage Tips

Revision lists are specified as comma separated ranges, e.g., 1412-1419,1423,1427,1433-1440. Ranges may overlap or be out of order; svnmerge will automaticaly normalize them. So 1413-1417,1410-1414,1402,1401 is equivalent to 1401-1402,1410-1417.

svnmerge never commits anything; it always leaves that final step to you. Use svn revert -R . if you need to start over. Note however that "svn revert" will not delete any files added by the merge, so you may have to remove some files yourself to get a complete reversion.

svnmerge merge requires that there be no outstanding changes in the branch directory (otherwise you could accidentally "merge" in a change that never existed in the head directory); use the --force flag to override this check.

Merges of discontinuous revision ranges can produce conflicts or omissions; this is an inherent fact of discontinuous merges, for example, if revision X modifies a file that was created in a previous revision Y < X that you haven't merged in yet. Pay special attention to the output from svnmerge (which comes directly from the "svn merge") for any ignored files or other complaints from Subversion; fixing these cases is up to you. Note that an "ignoring" message indicates a real conflict; it's just that the conflicting file doesn't exist in the target branch so Subversion can't mark it with a "C". In such cases, it's probably a good idea to include a comment in the commit message, e.g., "Note: patch to foo/bar.c in r1234 not included".