Branch Management

From Mpich2

Revision as of 19:07, 12 March 2008 by Goodell (Talk | contribs)
(diff) ← Older revision | Current revision (diff) | Newer revision → (diff)
Jump to: navigation, search


Contents


Merging Trouble

(from Goodell)

FYI, if anybody runs into a message like: "svn: Not authorized to open root of edit operation", then you may be hitting this bug: http://subversion.tigris.org/issues/show_bug.cgi?id=2712. You're probably not doing anything wrong, SVN is just buggy.

I encountered it when doing a merge between two branches recently. The workaround was to momentarily remove the anonymous access to the repository and run the merge command. Then restore the access when the merge is finished.

It doesn't look like there's a fix in any current version of SVN. Maybe by the time we are actually capable of moving away from svn 1.3.x the SVN developers will have gotten their act together.

Branching and Merging Theory

Without going into too much detail, it's worth explaining a bit about what merging and branching means in SVN. Understanding these concepts makes choosing and/or constructing the appropriate merge command much simpler later on.

Detailed information about SVN can be found in the "Version Control with Subversion" book.

Branching

Branching in SVN is accomplished via svn cp SRC_URL DEST_URL. This makes a copy of SRC_URL at DEST_URL, including file history information. There is no need for a svn commit since there is no working copy in this situation. It should be noted that these copies are "cheap" in the sense that they can be made quickly in the repository and do not increase the repository size very much because the whole file is not actually copied.

From SVN's perspective, a branch path is no different from any other path in the repository. The convention that we using has three major locations for branches:

SVN_ROOT=https://svn.mcs.anl.gov/repos/mpi
$SVN_ROOT/mpich2/trunk
$SVN_ROOT/mpich2/branches
$SVN_ROOT/mpich2/tags

The branches and tags directories are further subdivided into the following directories:

$SVN_ROOT/mpich2/branches/release
$SVN_ROOT/mpich2/branches/dev
$SVN_ROOT/mpich2/tags/release
$SVN_ROOT/mpich2/tags/dev

These release and dev directories exist to reduce the clutter when looking for and working with a release branch. Release branches are used to ensure a stable codebase for MPICH2 releases and allow us to easily create patches against a given release even if the trunk of development has diverged significantly since the release was cut. Development branches are used to keep potentially disruptive changes separate from the stable trunk development while still providing all the advantages of source code control to that development.

Merging

Merging is the process of moving changes between branches. In SVN, a svn merge is essentially shorthand for svn diff -r REV_SPEC SRC_URL | patch -p0 -d DEST_BRANCH_WC with a little bit of extra smarts thrown in for good measure. These extra smarts can take into account some of the common history information between the two branches. svn merge also understands SVN properties (such as svn:ignore), which is not properly handled by the regular diff/patch tools.

Because of this deeper understanding of history and properties, it is very important to always use svn merge when you are merging unless you are certain that you know what you are doing.

Common Merge Types

There are several types of merges that are performed much more often than others. These situations are listed below, along with examples. Merging isn't always intuitive, but it's certainly not something to be afraid of. These examples should help make the whole process go smoother. One common theme among all these merge scenarios is that there are always at least two steps that are the same:

  1. svn merge (some_args)
  2. svn commit

That is, all these changes take place in the context of a working copy and must be committed in order to take effect in the repository.

single change

Merging a single change is the easiest type of merge to do and should also be the most common in our regular development process. The command will look something like this:

svn merge -c NNN $SVN_ROOT/srcPath

Where NNN is the change number that you previously submitted to $SVN_ROOT/srcPath.

Example

Let's say that you find a bug in a comparison in all versions of MPICH2. You fix it in the trunk like so:

% svn checkout -q $SVN_ROOT/mpich2/trunk mpich2-trunk
% cd mpich2-trunk
% vim src/mpid/common/sock/poll/sock_post.i    # fix the bug here
% svn commit -m 'fix for req#1234, backwards comparison'
...
Committed revision 789.

Then you merge the change to the current release branch with the following commands:

% cd ..
% svn checkout -q $SVN_ROOT/mpich2/branches/release/MPICH2_1_0_7 mpich2-1.0.7
% cd mpich2-1.0.7
% svn merge -c 789 $SVN_ROOT/mpich2/trunk
...
% svn commit -m "merge r789 'trunk' -> 'MPICH2_1_0_7'"
...

The important parts are in BOLD, they show where the arguments for the actual svn merge command came from. Also, when performing this type of merge, it will be very helpful to you and others in the future if you write the source change (r789 in the example above) in the commit message of the merge, as well as the source and destination branch names.

trunk to release branch

XXX TODO

development branch to trunk

XXX TODO

Creating Patches

XXX TODO