svnmerge - Subversion merge tracking tool 


*** NOTICE: The information on this page is out of date; please see the svnmerge wiki page for updated information ***

svnmerge

svnmerge is a simple tool that tracks Subversion branch merges. It stores the repository path for each merge source ("head") along with the list of already-merged revisions in the svnmerge-integrated property associated with the destination ("branch") directory.

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 heads, plus some useful functionality for managing and updating that information.

Features:

Use of the tool is simple:

  1. Use svnmerge init to intialize 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.
  4. Commit the merge with svn commit.
  5. Return to step 2 and repeat.

Mailing List

A mailing list has been established. Details at: http://www.orcaware.com/mailman/listinfo/svnmerge. The mailing list is the place to go for information about active development and new features.

Download

svnmerge is now part of the Subversion source tree in the contrib/client-side directory. You can always download the latest version of svnmerge directly from the Subversion repository, though the $Keywords$ will not be properly substituted.

Giovanni Bajo has contributed a self-contained Windows executable based on it.

Changes

See the Subversion repository for change history.

Tips

Use the -f flag with svnmerge init and svnmerge merge to have svnmerge create a suitable commit message for you.

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, 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).

Merges of discontinuous revision ranges can produce conflicts or omissions; this is an inherent fact of discontinuous merges. For example, if a revision modifies a file that was created in a previous revision you haven't merged in yet. Pay attention to the output from svnmerge (that comes from the svn merge) for any ignored files or other complaints from subversion; fixing these cases is up to you. 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.''

Usage

The help message explains how it works:

$ svnmerge help

Examples

Example of a typical merge. This example merges in revision 1436 after reviewing the log message and diffs.

Note that the ``1436'' could have been an arbitrary list of revisions like ``1432-1437,1439,1441-1444''; it doesn't have to be just one as in this example. Nor is it a problem if you specify revisions that are already merged (they will be automatically ignored).

In this example, the new revision 1439 becomes available for merging after the final commit at the bottom. Revision 1439 will be ``empty'' (i.e., contain no changes in the head tree) and it can be merged in whenever, or not; it doesn't matter. Merging in empty revisions helps keep the available revision list smaller and more meaningful, since it will then only include non-empty merge candidates.

$ cd ~/svn/projects/edisplay/branches/1.0-branch
$ svn proplist -v .
Properties on '.':
  svnmerge-integrated : /projects/edisplay/trunk:1-1369,1377,1385-1430,1432-1433
$ svnmerge avail
1370-1376,1378-1384,1431,1434-1438
$ svnmerge avail -l -r 1436
------------------------------------------------------------------------
r1436 | archie | 2004-09-27 18:12:33 -0500 (Mon, 27 Sep 2004) | 2 lines
Changed paths:
   M /projects/edisplay/trunk/src/java/com/awarix/edsp/client/MainWindow.java

Ensure we create the reconnect timer before we might try to use it.

$ svnmerge avail -d -r 1436

svnmerge: changes in revisions 1436-1436 follow

Index: src/java/com/awarix/edsp/client/MainWindow.java
===================================================================
--- src/java/com/awarix/edsp/client/MainWindow.java   (revision 1435)
+++ src/java/com/awarix/edsp/client/MainWindow.java   (revision 1436)
@ -1096,6 +1096,9 @
         // Set initial status
         setStatus("Not connected.");
 
+        // Create timer for unattended mode auto-reconnection
+        reconnectTimer = new ReconnectTimer();
+        
         // Display the window
         SwingUtilities.invokeLater(new Runnable() {
              public void run() {

@ -1121,9 +1134,6 @
             numWindows++;
         }
         
-        // Create timer for unattended mode auto-reconnection
-        reconnectTimer = new ReconnectTimer();
-        
         // Start reconnect timer
         reconnectTimer.start();
     }
$ svnmerge merge -r 1436 -f commit.txt
U  src/java/com/awarix/edsp/client/MainWindow.java
$ cat commit.txt
Merged revisions 1436 via svnmerge from
http://svn.dellroad.org/svn/eng/projects/edisplay/trunk
$ svn status
?      commit.txt
 M     .
M      src/java/com/awarix/edsp/client/MainWindow.java
$ svn diff -N .

Property changes on: 
___________________________________________________________________
Name: svnmerge-integrated
   - /projects/edisplay/trunk:1-1369,1377,1385-1430,1432-1433
   + /projects/edisplay/trunk:1-1369,1377,1385-1430,1432-1433,1436

$ svn commit -F commit.txt && rm commit.txt
Sending        1.0-branch
Sending        1.0-branch/src/java/com/awarix/edsp/client/MainWindow.java
Transmitting file data .
Committed revision 1439.
$ svnmerge avail
1370-1376,1378-1384,1431,1434-1435,1437-1439

Here's an example of how to set up multi-way merging.

Suppose you have a trunk head and two spin-off branches branch1 and branch2. You want to be able to merge changes in both directions between head and either branch, i.e., bidirectionally between head and branch1 and bidirectionally between head and branch2, but not at all between branch1 and branch2.

$ cd /home/user/myproject/trunk
$ svnmerge init -f commit.txt /myproject/branches/branch1 && svn ci -F commit.txt && rm commit.txt
Sending        trunk
Transmitting file data .
Committed revision 1533.
$ svnmerge init -f commit.txt /myproject/branches/branch2 && svn ci -F commit.txt && rm commit.txt
Sending        trunk
Transmitting file data .
Committed revision 1534.
$ cd ../branches/branch1
$ svnmerge init -f commit.txt /myproject/trunk && svn ci -F commit.txt && rm commit.txt
Sending        branch1
Transmitting file data .
Committed revision 1535.
$ cd ../branch2
$ svnmerge init -f commit.txt /myproject/trunk && svn ci -F commit.txt && rm commit.txt
Sending        branch2
Transmitting file data .
Committed revision 1536.

If you only wanted to merge unidirectionally from the head to the branches, but not in the ``backwards'' direction, then you'd omit the first two steps above.



[ DellRoad Home ]