Next: , Previous: , Up: Tutorial   [Contents][Index]

2.12 Branching and Merging

So by now you’re familiar with making changes, sharing them with other people, and integrating your changes with their changes. Sometimes, though, you may want to make some changes, and not integrate them with other people’s — or at least not right away. One way to do this would be to simply never run mtn merge; but it would quickly become confusing to try and keep track of which changes were in which revisions. This is where branches are useful.

Continuing our example, suppose that Jim is so impressed by Beth’s work on banana juice support that he assigns her to work on the JuiceBot 7’s surprise new feature: muffins. In the mean time, Abe will continue working on the JuiceBot’s basic juice-related functions.

The changes required to support muffins are somewhat complicated, and Beth is worried that her work might destabilize the program, and interfere with Abe’s work. In fact, she isn’t even sure her first attempt will turn out to be the right approach; she might work on it for a while and then decide it was a bad idea, and should be discarded. For all these reasons, she decides that she will work on a branch, and then once she is satisfied with the new code, she will merge back onto the mainline.

She decides that since main development is in branch, she will use branch So, she makes the first few edits to the new muffins code, and commits it on a new branch by simply passing --branch to commit:

$ mtn commit --message='autobake framework'
mtn: beginning commit on branch ''
mtn: committed revision d33caefd61823ecbb605c39ffb84705dec449857

Alternately, she could not specify a message on the command line, and edit the “Branch” field in the changelog editor.

That’s all there is to it — there is now a branch, with her initial checkin on it. She can make further checkins from the same workspace, and they will automatically go to the muffins branch; if anyone else wants to help her work on muffins, they can check out that branch as usual.

Of course, while Beth is working on the new muffins code, Abe is still making fixes to the main line. Occasionally, Beth wants to integrate his latest work into the muffins branch, so that her version doesn’t fall too far behind. She does this by using the propagate command:

$ mtn propagate
mtn: propagating ->
mtn: [source] da003f115752ac6e4750b89aaca9dbba178ac80c
mtn: [target] d0e5c93bb61e5fd25a0dadf41426f209b73f40af
mtn: common ancestor 853b8c7ac5689181d4b958504adfb5d07fd959ab 2004-10-26T:12:44:23 found
mtn: trying 3-way merge
mtn: [merged] 89585b3c5e51a5a75f5d1a05dda859c5b7dde52f

The propagate merges all of the new changes on one branch onto another.

When the muffins code is eventually stable and ready to be integrated into the main line of development, she simply propagates the other way:

$ mtn propagate
mtn: propagating ->
mtn: [source] 4e48e2c9a3d2ca8a708cb0cc545700544efb5021
mtn: [target] bd29b2bfd07644ab370f50e0d68f26dcfd3bb4af
mtn: common ancestor 652b1035343281a0d2a5de79919f9a31a30c9028 2004-10-26T:15:25:05 found
mtn: [merged] 03f7495b51cc70b76872ed019d19dee1b73e89b6

Monotone always records the full history of all merges, and is designed to handle an arbitrarily complicated graph of changes. You can make a branch, then branch off from that branch, propagate changes between arbitrary branches, and so on; monotone will track all of it, and do something sensible for each merge. Of course, it is still probably a good idea to come up with some organization of branches and a plan for which should be merged to which other ones. Monotone may keep track of graphs of arbitrary complexity — but you will have more trouble. Whatever arrangement of branches you come up with, though, monotone should be able to handle it.

If you are unsure of the name of a branch, you can list all branches using the ls branches command. This is very useful, but if you create a lot of branches then the list can become very long and unwieldy. To help this monotone has the suspend command which partially hides revisions/branches you are no longer using. Further commits on hidden branches will automatically unhide the branches.

For example, if Beth is now finished with the muffins branch, she can stop it from cluttering the list of branches by suspending the last revision in that branch:

$ mtn ls branches
$ mtn heads
mtn: branch '' is currently merged:
4e48e2c9a3d2ca8a708cb0cc545700544efb5021 2007-07-08T02:17:37
$ mtn suspend 4e48e2c9a3d2ca8a708cb0cc545700544efb5021
$ mtn ls branches

Next: , Previous: , Up: Tutorial   [Contents][Index]

Quick Links:    -     Downloads    -     Documentation    -     Wiki    -     Code Forge    -     Build Status