snax

svn branching best practices (in practice)

Notice: this article is extremely out of date. If you want to learn modern Subversion best practices, please look elsewhere.


You want to make a Subversion branch, and merge it later. You read the branching section in the official book, but are still confused. What to do?

creating the branch

1. Note the current head revision:

svn info svn://server.com/svn/repository/trunk | grep Revision

2. Make a clean, remote copy of trunk into the branches folder. Name it something. We’ll call it your_branch:

svn cp svn://server.com/svn/repository/trunk \
  svn://server.com/svn/repository/branches/your_branch \
  -m "Branching from trunk to your_branch at HEAD_REVISION"

Replace HEAD_REVISION with the revision number you noted in step 1.

Note that a backslash (\) means that the command continues onto the next line.

3. switch your local checkout to point to the new branch (this will not overwrite your changes):

svn switch --relocate \
  svn://server.com/svn/repository/trunk \
  svn://server.com/svn/repository/branches/your_branch

You don’t really need the --relocate svn://server.com/svn/repository/trunk bit, but I’m in the habit of being explicit about it.

4. Check that your local checkout is definitely now your_branch, and that you can update ok:

svn info | grep URL
svn up

5. commit your new changes.

(These steps will work even if you had already made local changes on trunk, but decided you wanted them on your_branch instead. If your trunk checkout was unmodified, just skip step 5.)

updating the branch

You’ve been developing for a while on your_branch, and so have other people on trunk, and now you have to add their changes to your_branch.

1. First, update your branch checkout and commit any outstanding changes.

2. Search the Subversion log to see at what revision number you last merged the changes (or when the original branch was made, if you’ve never merged). This is critical for making a successful merge:

svn log --limit 500 | grep -B 3 your_branch

3. Also note the current head revision:

svn info svn://server.com/svn/repository/trunk | grep Revision

4. Merge the difference of the last merged revision on trunk and the head revision on trunk into the your_branch working copy:

svn merge -r LAST_MERGED_REVISION:HEAD_REVISION \
  svn://server.com/svn/repository/trunk .

Replace LAST_MERGED_REVISION with the revision number you noted in step 2, and HEAD_REVISION with the revision number you noted in step 3.

Now look for errors in the output. Could all files be found? Did things get deleted that shouldn’t have been? Maybe you did it wrong. If you need to revert, run svn revert -R *.

5. Otherwise, if things seem ok, check for conflicts:

svn status | egrep '^C|^.C'

Resolve any conflicts. Make sure the application starts and the tests pass.
6. commit your merge.

svn ci -m "Merged changes from trunk to your_branch: COMMAND"

Replace COMMAND with the exact command contents from step 4.
Phew.

folding the branch back into trunk

Hey, your_branch is done! Now it has to become trunk, so everyone will use it and see how awesome it is.

This only happens once per branch.

1. First, follow every step in the previous section (“updating the branch”) so that your_branch is in sync with any recent changes on trunk.

2. Delete trunk completely:

svn del svn://server.com/svn/repository/trunk

3. Move your_branch onto the old trunk location:

svn mv svn://server.com/svn/repository/branches/your_branch \
  svn://server.com/svn/repository/trunk

4. Relocate your working copy back to trunk:

svn switch --relocate \
  svn://server.com/svn/repository/branches/your_branch \
  svn://server.com/svn/repository/trunk

All done.

footnote

Subversion 1.5 is scheduled to bring automatic merge tracking (notice the ticket comment that says “tip of the iceberg”). Until that fine day, if you want to automate this, the svnmerge.py tool is supposed to be pretty nice.