Subversion/branching guide
This page is obsolete. It is being retained for archival purposes. It may document extensions or features that are obsolete and/or no longer supported. Do not rely on the information here being up-to-date. MediaWiki used the Subversion version control system, but has since migrated MediaWiki core and nearly all extensions to Git. |
Making a branch
[edit]A branch in Subversion is "just" a copy of an already-existing directory tree which can be further edited independently. On the one hand this gives you more flexibility than, say, CVS, but on the other hand you sometimes have to have a little discipline to keep things sorted right.
Release branch example
[edit]For our quarterly releases, I make a branch directory and then copy MediaWiki's "phase3" directory off the current trunk:
svn mkdir svn+ssh://svn.wikimedia.org/svnroot/mediawiki/branches/REL1_8 svn copy \ svn+ssh://svn.wikimedia.org/svnroot/mediawiki/trunk/phase3 \ svn+ssh://svn.wikimedia.org/svnroot/mediawiki/branches/REL1_8/phase3 svn copy \ svn+ssh://svn.wikimedia.org/svnroot/mediawiki/trunk/extensions \ svn+ssh://svn.wikimedia.org/svnroot/mediawiki/branches/REL1_8/extensions
Then, for each individual release I make another copy which can be referenced to pull that particular version of the branch:
svn copy \ svn+ssh://svn.wikimedia.org/svnroot/mediawiki/branches/REL1_8 \ svn+ssh://svn.wikimedia.org/svnroot/mediawiki/tags/REL1_8_0
SVN has no specific concept of "tags" like CVS does; "branches" and "tags" are just directory names, and how their contents are treated is a matter of convention. Thus it's actually possible to make further changes to a tag; this is occasionally useful (for instance, to clean up some file corruption from botched line-ending conversions when we converted from CVS to SVN) but usually you should not alter things labeled as tags.
Merging trunk changes into your branch
[edit]To keep a work branch up to date, or to quickly merge an individual fix into a release branch, you can use Subversion's "merge" command.
This unfortunately likes big long URLs which are a pain to type, but some common cases can be simplified quite a bit; I find this shell script rather handy:
Listing 1: mw-merge
#!/bin/bash
if [ "x$2" == "x" ]
then
current="$1"
let prev="$current - 1"
else
prev="$1"
current="$2"
fi
svn merge -r$prev:$current svn+ssh://svn.wikimedia.org/svnroot/mediawiki/trunk/phase3
When run in a branch's working directory, this script merges either a single change from trunk (if given one revision number), or all changes on trunk from a start to an end revision into the working directory.
You may have to manually resolve conflicts, of course; see the online subversion documentation for some general hints.
Once conflicts are resolved, use 'svn commit' to commit the updates into the branch -- preferably before you do further work, to simplify your life when looking at the history later. I strongly recommend including the revision numbers you merged against in the commit comment, to remind yourself what you did (and where you'll have to work from next time!)
In fact, it's probably best if you use a tool such as svnmerge.py to keep track of this for you. Using a tool eliminates the very probable event of an error in merging, as well as the great tedium.
Merging branch changes into trunk
[edit]When your work branch is complete and ready for prime-time, you'll want to merge into trunk. Test and consult with others first if it's big and scary... but don't feel bad if you get reverted right away! Big changes might need fixes or further review before being finally accepted.
I find a useful workflow is to first make a diff from current trunk to the branch state, review that manually, and then once I'm satisfied I use the standard 'patch' command to apply the diff onto trunk.
You should also be able to use 'svn merge' as with the above merge-from-trunk script, though.