Harmonize RCS with Monotone

Revision control systems are like, in. Everyone’s using one, and you must have strong opinions about why yours is best and the others are toxic waste. If you use Subversion you must dis Arch. If you use Arch you must sneer at Subversion. It is acceptable for both Arch and Subversion users to unite in scorning both CVS and BitKeeper. For some reason, liking more than one is not acceptable.

Monotone is wisely mistrustful of anything that comes from a remote host, so it forces you to set up cryptographic authentication right from the start.

For those of us with actual work to do, a worthy new contender in the revision control fray is Monotone, by Graydon Hoare. Mr. Hoare does things differently than the developers of other revision control systems. He does not engage in public combat over the merits of the various RCS products. He just quietly improves Monotone.

Monotone has a different architecture and a different way of doing things than the others. The current version is 0.14. It has enough rough edges that you should spend some time testing it, and not just dump all of your vitally important projects into it, but already it’s impressive. It’s a lot simpler to set up and use than CVS, GNU Arch, or Subversion. Some of its features are:

  • Distributed repositories
  • Netsync protocol
  • SQLite backend
  • No hiccups over binary files
  • Direct import of RCS/CVS ,v files

If you prefer a central server/client mode, with strict control of a central server, like CVS or Subversion, Monotone might not be a good fit for you. Monotone is completely decentralized, working in three modes: local working copy, local repository, and netsync server. Each Monotone user is both a client and a server, if they so choose. Of course you can set up a centralized repository, but there’s nothing to stop users from going all anarchic and synchronizing directly with each other.

Monotone makes extensive use of SHA1 hashes to create unique identifiers for files, and RSA keys to verify authenticity of network operations. Monotone is wisely mistrustful of anything that comes from a remote host, so it forces you to set up cryptographic authentication right from the start.


There are a few tricky bits to installation. You can get sources, RPM, .deb, and a Windows .exe from Monotone’s home page. For Unix/Linux, you need these dependencies:

You don’t have to use Lua if you are an ace programmer or scripter who prefers other languages. Us ordinary mortals are better off following the Monotone instructions as they are written, and they call for Lua.

Debian, as usual, divides packages into microscopic fragments and calls them “lib” -everything. Get all the bits you need at once with this command:

# apt-get install libboost-date-time-dev libboost-filesystem-dev libboost-regex-dev libboost-dev libboost-test-dev libpopt-dev lua50

RPM users need only the boost-devel, popt, and lua packages.

Build-from-sources users, be sure to read the Monotone INSTALL page. You can download and build Monotone in your home directory. For ease of use, be sure that the Monotone directory is in your path, like this example in ~./bashrc, which assumes you use a ~/bin directory:

# set PATH so it includes user's private bin if it exists
if [ -d ~/bin ] ; then
	export PATH

Building A Local Repository

First, create your Monotone database in an existing directory:

$ monotone db init --db=~/project1/project1.db

Next, generate an RSA cryptographic key pair. The author of Monotone recommends using an email address as a key identifier; you may use whatever you like:

$  monotone --db=~/project1/project1.db  genkey [email protected]
monotone: generating key-pair '[email protected]'
enter passphrase for key ID [[email protected]]:
confirm passphrase for key ID [[email protected]]:
monotone: storing key-pair '[email protected]' in database

Now confirm that the keys were generated by listing them with the “list keys” command”

$ monotone --db=~/project1/project1.db list keys
[public keys]
dd2010598c67d438a8ed9a0b5521b545d0b28f38 [email protected]
[private keys]
b54b50db61f5032456c8449cb7773ed1068273d9 [email protected]

Continued on page 2: Adding Files and Watching for Gotchas

Continued From Page 1

Now add some files to your project. This example adds a directory of files to the working directory:

$ monotone --branch=config_files --db=~/project1/project1.db add configs/
monotone: adding configs/apache-1.3-https to working copy add set
monotone: adding configs/postfix-sa to working copy add set

Then commit the additions:

$ monotone commit '1st commit of configs for branch office servers'
monotone: committing e85116a6c24df94037ae4ccd60645e0044da58a5
monotone: committing to branch config_files
enter passphrase for key ID [[email protected]]:
monotone: committed e85116a6c24df94037ae4ccd60645e0044da58a5

There are a couple of gotchas to look out for. Monotone does not allow absolute filepaths when you’re listing files or directories to add to the repository. In this example, I made sure the Monotone binary was in my path, then ran the “add” and “commit” commands from the next directory above the “configs” directory. If Monotone is not in your path, you are doomed to specifying the entire path every time you run it, like ~/downloads/monotone-0.14/monotone.

Check the status of your nice new branch with this command:

$ monotone heads
monotone: fetching heads of branch 'config_files'
branch 'config_files' is currently merged:
e85116a6c24df94037ae4ccd60645e0044da58a5 [email protected] 2004-10-01T20:41:06

The “status” command reports any changes to the database:

$ monotone status
Old manifest: e85116a6c24df94037ae4ccd60645e0044da58a5
New manifest: e85116a6c24df94037ae4ccd60645e0044da58a5
Summary of changes:
  no changes

Suppose you want to edit a file. Just open and edit the file as you normally would, and save your changes. Then use the “commit” command to add the changed file to the repository:

$ monotone commit
monotone: committing b102fc029bde2d6b50c6e5bfd9d79ec2cba7cbc6
monotone: committing to branch config_files
enter passphrase for key ID [[email protected]]:
monotone: committed b102fc029bde2d6b50c6e5bfd9d79ec2cba7cbc6

Like any other RCS, your default editor will open to make the changelog entry.

Visualizing Confusion

Figure 1. With Monoton’s xvcg dump, you can track the evolution of your Monotone tree.
(Click for a larger image)

Using these 40-bit hashes instead of nice, human-readable names can get confusing. Fear not, for Monotone comes with a built-in xvcg dump, so you can easily create a graph showing the relationships of the branches and trees in your repository with xvcg. First, generate the xvcg data:

$ monotone agraph
node: { title : "71edb60beae79dc350cee1050af7c37ac04ddc9a"
        label : "fb71edb60beae79dc350cee1050af7c37ac04ddc9anfnconfig_files"}
node: { title : "b102fc029bde2d6b50c6e5bfd9d79ec2cba7cbc6"
        label : "fbb102fc029bde2d6b50c6e5bfd9d79ec2cba7cbc6nfnconfig_files"}
node: { title : "e85116a6c24df94037ae4ccd60645e0044da58a5"
        label : "fbe85116a6c24df94037ae4ccd60645e0044da58a5nfnconfig_files"}
edge: { sourcename : "b102fc029bde2d6b50c6e5bfd9d79ec2cba7cbc6"
        targetname : "71edb60beae79dc350cee1050af7c37ac04ddc9a" }
edge: { sourcename : "e85116a6c24df94037ae4ccd60645e0044da58a5"
        targetname : "b102fc029bde2d6b50c6e5bfd9d79ec2cba7cbc6" }

Then copy the output to a file, and generate a nice graph showing the evolution of your Monotone tree:

$ xvcg graph -

This spits out a graph like the one in Figure 1. (Note that it shows three levels, while only two levels were created in this article.)

Checkouts And Netsync

Come back next week to find out how to manage checkouts, share over a network, and find things in your repository. Or haul yourself over to Monotone now and get a head start.


Latest Articles

Follow Us On Social Media

Explore More