Subversion branching in my experience

In my working life I have lead teams developing some big projects and products. In all these development we had to control versions, releases, some QA dedicated version and so on.

Of course we used SCM for these stuffs, and I focused ,as usual for me, on open source solutions. So I started to use cvs a lot of year ago, and more recently (exactly since Jan 2004) subversion. As in all big projects I needed to track code for different development line and product releases, and use of branches have been quite natural (especially in svn world) achieving these goals.

In my career I have been lucky working with great developers, but we have needed to find an agreement about the use of branches (and tags) in our SCM, because they can easily become a nightmare if leaved out of control and convention. Moreover, it’s a matter of fact that SCM is easy to understand and use, but a correct use of branches and tags may be something which most developers don’t understand and use them without worries.

Some months ago I wrote 2 documents to cover 2 different needs: the first is an introduction to branching and tagging in general and in our environment for new hired people, the second is a checklist of operation needed in branching a project, respecting our “svn pattern”. Both documents was in italian language, but they need a review with minor adaptation of our newest best practice in these days, and so I decided to translate and generalize it to make it public. Originally our document describe svn pattern strictly coupled to jira, fisheye and hudson practice we are using, I tried to decouple them, to make this post easy to read for atlassian/hudson non-believer. If someone is interested I can describe in another post how we are using these tools in our environment. Just let me know by comments or by email.

Ok, stop describing background and go with documents: The first is this post itself, the second is attached here as pdf and txt, since I think it’s more useful in that format used as checklist.

Let’s start describing what is a branch and a tag in svn: branches and tags in subversion just a copy of sources. Branches is for convention a copy where teams do parallel development, tags is for convention a read only copy (and only for convention in svn), to store a copy of code in a particular stage of development (they are for convention not modifiable). How do you create a branch or a tag? Of course, being them just copies, with copy (or move) command. Let’s see the command (here and in the rest of post, I make an example of the most common use, at least for us, of the command…take a look to the “svn help <command>” and the good svn online manual for more detail

svn copy SRC DEST

Our normal convention used in svn is to create 2 directories on repository called branches and tags where you have to copy them. So for example, we can create a branch called “Experiment1″ with this command:

svn copy $REPO_PATH/trunk $REPO_PATH/branches/Experiment1

But how are we using branches? Well we are using 2 different kind of branching, with totally different goals: STABLE branches, used for stable product release maintenance, and personal branches, used for experimental code and/or for agile parallel development.

In this figure I sketched our repository layout. As you can see we have a current development line on trunk and we branch starting from there for e different reasons:

1) starting a new parallel personal development (red), which will be described in detail later in this post.

2) Create a branch for a stable release (green), which need maintenance. When the version reach the end of supported life we migrate the branch on a tag to keep “legacy” code with it’s story somewhere. This approach permit us to always have clean code for any version maintained, where investigate for bugs and stack trace reported by customers.

But where have we to fix a bug? In all branches having the same code? Of course here subversion merging help us a lot.

When we find a bug we correct it on trunk whenever it is possible and then merge the correction (backport in our slang) on all active branches. When the bugs can’t be corrected on trunk (i.e because the buggy code don’t exist in trunk anymore) we fix it on the newest branch available and then backport it on older code.

What we are doing here is in fact a single commit management and merging. It give us an high level of confidence on what we are doing on stable releases, especially used together with Jira, unit tests and hudson.

We always have a person or a team responsible of maintenance of a version, and it’s up to her (or them) to decide what bugs need backporst and it’s up to her (or them) to manage this merge:

cd branch_workingCopy_dirsvn merge –dry-run -r N-1:N $REPO/branches/$BRANCH_NAMEsvn merge -r N-1:N $REPO/branches/$BRANCH_NAME
svn commit -m”JARA-YYY: back porting of commit N, fixing JIRA-XXX”

We use svn also to make parallel development on the same project. Similar approach is described in detail in a lot of article of agile development (1,2). I don’t know, and I don’t care, if we are totally agile compliant, but we use the same idea to create personal branches, and commit on them all works around big Jira tasks.

Our idea is that our trunk have to be clean, buildable and with all test passing (and hudson verify this condition at every commit). Ideally trunk would be releasable at any moment, or at least can receive patch to be backported. But, of course, there are some bug issues and development to be done that can’t be developed in few hours by a single developer on her laptop (buildable, tests passing, feature complete and stable). But of course we needs to have new code somewhere making possible to an heterogeneous team to work on and to be available to all team members at any time. So the solution is to have parallel “personal” branches.

Personal branches is totally different from release ones described above, since they don’t die at some stage, but they have to be merged on trunk, applying to trunk all changes developed and tested in branch. But sometimes this development phase may take some time (in particular for experimental code development), and trunk may change a lot during this time. For this reason merging back a branch on a trunk which have changed a lot could easily become pain, with a lot of difficult to resolve conflict.

Our solution have been to keep personal branches updated, merging frequently from trunk and resolving day by day conflicts, and a final “publish” action reporting all changed code in branch into trunk. Few conflict at a time, and on a well known code base is much more easy to understand and to resolve.
But isn’t difficult to keep track of which revision is already merged on branch? (IOW a lot of merge, means keeping track of merge operations?).
It was true (even not impossible, we always kept track of them with a text file) before subversion 1.4, which includes a command “svnmerge to keep track of merges (it’s in fact a contribution, downloadable also for early versions as svnmerge.py)

What does it for you? It keep track of merges from trunk to branch (using properties on branch) and make much more easy merging in this direction. Theoretically it would also help you also merging back in other direction, but we don’t use it for this operation, since “traditional” merge does a good job in this final “pubblication” operation. There are commands we use to make these operations, refer to previous figure to better uinderstand what we are doing:

CREATE A PERSONAL BRANCH

svn copy $REPO/trunk $REPO/branches/$BRANCH_NAME -m”created branch”
svn co $REPO/branches/$BRANCH_NAME branch_workingCopy_dir
cd branch_workingCopy_dir
svnmerge init
svn commit -m”svnmerge initialized”

MERGING FROM TRUNK TO PERSONAL BRANCH (FREQUENTELLY)

cd branch_workingCopy_dir
svnmerge merge
svn commit -m”merged trunk to branch”

MERGING INTO TRUNK FROM PERSONAL BRANCH

cd branch_workingCopy_dir
svnmerge merge
svn commit -m”last merge of trunk to branch”
remove property used to track merges
svnmerge uninit
svn commit -m”svnmerge uninit”
cd trunk_workingCopy_dir
svn update

(get the revison number….suppose 346)
svn merge –dry-run $REPO/trunk@346 $REPO/branches/$BRANCH_NAME@346
svn merge $REPO/trunk@346 $REPO/branches/$BRANCH_NAME@346
svn commit -m”reported changes from $BRANCH_NAME trunk”
svn delete $REPO/branches/$BRANCH_NAME@346

That’s all. Just one more advice………

Last, but not least, merging works on difference, so don’t forget to ensure that difference are real changes on code, and not simple formatting!!!

Use of some tools to format code automatically at some time is more than useful: eclipse at save file defining a code style formatter profile, jalopy used in ant or in maven or what else you can figure out, but please don’t leave it to developers, use an automatic tool! Of course it’s just my humble opinion, but to many times I have been in pain merging code (and mainly understanding difference on fisheye) with stupid formatting problems!

Hoping they would be useful for use here you have our checklist document in txt and pdf formats.

Have fun!

11 Responses to “Subversion branching in my experience”

  1. Jeff says:

    Great post. ;-)

  2. Nice article; we are using some similar setup with jira, quickbuild and polarion webclient for Subversion. :)

  3. ruben says:

    Hi,

    Prior to svn 1.4, there is no need for an external text file to record the merge revisions. As recommended in the redbook, you can have them in the commit messages.

    Cheers

  4. Danni says:

    That sure seems like a hassle compared to just using streams. See if this blog gives you an “AHA!” moment.

    http://daveonscm.blogspot.com/2007/09/agile-branches-vs-streams.html

    ~D

  5. sandrar says:

    Hi! I was surfing and found your blog post… nice! I love your blog. :) Cheers! Sandra. R.

  6. James Bailey says:

    Hi there,

    I’ve just come across your very informative blog post.

    We’re running our own Subversion Community Site (and I notice that one of our members has already commented on this blog post!) and I’d love it if you could take a moment of your time to have a look at our site and possibly also publish your blog on there.

    We’d certainly love to see you there :)

    James

    http://subversion.community.com

  7. [...] 我期待在TortoiseSVN的版本图的权利,但它有更多的细节比我想和错误的布局。我在寻找的东西更多的图像,例如这篇文章 。 [...]

  8. [...] I’m looking at the TortoiseSVN Revision Graph right now, but it has more detail than I want and the wrong layout. I’m looking for something more like the images in this article. [...]

  9. ferch says:

    Hi, nice article,

    unfortunately, the links to the images and the pdf are broke. Could you repair it?
    Thanks

    Ingo

  10. gianni says:

    Hi, thanks for the post. I want to inform you (hoping somebody will read this reply) that there’s no more linked images in the article….

    understanding’s not so easy!

  11. Fixed, thanks for the report

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>