Wednesday, September 17, 2008

Branches and Merging with Subversion

I found other posts elsewhere mystifying. None of them had a very good technical explanation for what Subversion was doing in the background, so the very best posts for me just had step by step instructions. You know... for monkeys.

So... here's my cookie-cutter, "joo can doo eet too" solution for dealing with branches and merges to and from a Subversion trunk repository.

1) Every day, I merged trunk -> branch and resolved conflicts. This kept shit from getting too far out of whack. I kept a log of what happened in case I needed it, and I tagged every commit from this procedure with the revision I merged from and to. For example (NOTE: I'm in a directory with the branch version of the code):

...
6/19 > svn merge -r 4130:4152 svn+ssh://svn.billy.net/data/svn/jooky/trunk
6/20 > svn merge -r 4152:4164 svn+ssh://svn.billy.net/data/svn/jooky/trunk
6/23 > svn merge -r 4164:4199 svn+ssh://svn.billy.net/data/svn/jooky/trunk
...
6/30 > svn merge -r 4368:4376 svn+ssh://svn.billy.net/data/svn/jooky/trunk

2) Ok, so, on the day of the big merge back you tell everyone to quit committing to either trunk or branch until the process is complete. I know, a revision control system should support locking. AFAIK, Subversion doesn't, so you just have to treat your fellow developers like adults and trust that they will follow your edict. Maybe tell them that whoever thwarts you by checking in has to do the merge for you :)

6/30 > svn merge -r 4368:4376 svn+ssh://svn.billy.net/data/svn/jooky/trunk

3) If that tests clean, here's the magic part: go to a directory that contains the trunk version of your code, and merge in this directory using this bizarre ordering:

> svn merge svn+ssh://svn.billy.net/data/svn/jooky/trunk svn+ssh://svn.billy.net/data/svn/jooky/branches/dbrb_4043

That's right: go to a directory with a trunk version of your code, and tell svn to merge trunk to branch (well, that's how *I* read that notation anyway. YMMV). Check it out! I have no freaking idea what Subversion is thinking here, but I can tell you from experience that this process works. ONLY the differences you want are carried from branch back to trunk.

[ Update ]

One thing that's crucial to this thing working right is keeping notes. Externally or using comments, note the revisions you're using.

Regarding the notes, I've seen a pretty common mistake using this technique that I think I need to make mention of. Don't ever use "HEAD" for any of these operations. You don't know what head is when you do this operation, and you will likely forget to make a note of it when you add your comment. This can cause gaps in your merge. Gaps are bad.

No comments: