Up until now, branch renaming has been a tricky issue with monotone... and for good reasons. What makes it tricky is that as soon as a branch has left the building (in this case, your own database) out into the world (basically, any other database), you're stuck with what there is unless you track down every damn database where it has ended up and convince every last owner of those databases to do the same change you did. That might be hard work.

So far, it has been recommended to think of what globally unique name you should use for your branch from the start, since you can't undo it later.

My question is, though, is that really true any more? After all, since that time, monotone has evolved further, new features have been added, and they might help us in this case.

Let me introduce you to this little command:

mtn suspend

This little command, which has been around since version 0.41 (September 2008), allows anyone to mark a revision as suspended, discontinued. If all heads of a branch are suspended, that branch will not be displayed any more. It will become invisible.

$ ########################################
$ # Preparations
$ #
$ mtn -d foo.mtn db init
$ mtn -d foo.mtn setup workspace -b foo -k richard@levitte.org
$ cd workspace
$ echo a > a; mtn add a; mtn ci -m "initial commit"
mtn: adding a to workspace manifest
mtn: beginning commit on branch 'foo'
mtn: committed revision bb0a1222004d13502ff27be2c92fbe6cb3f7ebf2
$ ########################################
$ # Done with the preparations
$ #
$ mtn ls branch
foo
$ mtn suspend w:
mtn: expanding selection 'w:'
mtn: expanded to 'bb0a1222004d13502ff27be2c92fbe6cb3f7ebf2'
$ mtn ls branch
$

Now, if you commit a new revision on a branch where the head is suspended, that branch will reappear.

$ echo b > b; mtn add b; mtn ci -m 'b' b
mtn: adding b to workspace manifest
mtn: beginning commit on branch 'foo'
mtn: committed revision fc6c73dc99a8f71350507a5369bdd0fa93664b41
$ mtn ls branch
foo
$

However, if you commit that same new revision with a new branch name, the old branch (whose head is the parent of the newly committed revision) will remain invisible, while the new one appears, with a history that goes back into the old (now invisible) branch.

$ # This example is instead of the previous commit
$ echo b > b; mtn add b; mtn ci -b bar -m 'b' b
mtn: adding b to workspace manifest
mtn: beginning commit on branch 'bar'
mtn: committed revision fc6c73dc99a8f71350507a5369bdd0fa93664b41
$ mtn ls branch
bar
$ mtn log --no-graph
----------------------------------------------------------------------
Revision: fc6c73dc99a8f71350507a5369bdd0fa93664b41
Parent:   bb0a1222004d13502ff27be2c92fbe6cb3f7ebf2
Author:   Richard Levitte <richard@levitte.ord>
Date:     02/28/11 08:32:41
Branch:   bar

Changelog: 

b

Changes against parent bb0a1222004d13502ff27be2c92fbe6cb3f7ebf2

  added    b

----------------------------------------------------------------------
Revision: bb0a1222004d13502ff27be2c92fbe6cb3f7ebf2
Author:   Richard Levitte <richard@levitte.ord>
Date:     02/28/11 08:31:19
Branch:   foo

Changelog: 

initial commit

Changes

  added    
  added    a

$

Another way to achieve the same effect without committing something new is, of course, to simply add another branch cert to the revision you just suspended.

$ # This example is instead of any of the two previous commits
$ mtn cert bb0a1222004d13502ff27be2c92fbe6cb3f7ebf2 branch "bar"
$ mtn ls branch
bar
$ mtn log --no-graph
----------------------------------------------------------------------
Revision: bb0a1222004d13502ff27be2c92fbe6cb3f7ebf2
Author:   Richard Levitte <richard@levitte.ord>
Date:     02/28/11 08:31:19
Branch:   bar
Branch:   foo

Changelog: 

initial commit

Changes

  added    
  added    a

$

So, this isn't reeeally branch renaming per se, but it has the same effect in practice, and it comes with the benefit that this is entirely supported by monotone, there's no need to remove a whole bunch of branch certs and add the same number of new ones, there's no need to chase down every damn database this might have spread to. There's no need for trickery.

blog comments powered by Disqus