Below is the file 'monotone.texi' from this revision. You can also download the file.
\input texinfo @c -*-texinfo-*-
@c %**start of header
@setfilename monotone.info
@settitle monotone documentation
@setchapternewpage odd
@c %**end of header
@syncodeindex fn cp
@include version.texi
@ifinfo
This manual is for the ``monotone'' distributed version control system.
This edition documents version @value{VERSION}.
Copyright 2003, 2004 Graydon Hoare
Copyright 2004, 2005 Nathaniel Smith
Copyright 2005 Derek Scherger
All rights reserved
Licensed to the public under the terms of the GNU FDL (>= 1.1).
See the file COPYING for details
@end ifinfo
@dircategory Programming
@direntry
* monotone: (monotone). Monotone version control system
@end direntry
@titlepage
@title Monotone
@subtitle A distributed version control system
@author Graydon Hoare
@page
@vskip 0pt plus 1filll
Copyright @copyright{} 2003, 2004 Graydon Hoare
Copyright @copyright{} 2004 Nathaniel Smith
All rights reserved
Licensed to the public under the terms of the GNU FDL (>= 1.1).
See the file COPYING for details
@end titlepage
@ifnottex
@node Top
@top Top
Monotone Documentation
Monotone is a distributed version control tool. It can help automate
many tedious and error-prone tasks in group software development.
@itemize
@item
Store multiple versions of files you are working on efficiently.
@item
Transmit changes to files between you and your colleagues.
@item
Merge changes you make with those your colleagues make.
@item
Make notes about your opinion of the quality of versions of files.
@item
Make decisions about using or ignoring versions, depending on the notes
you receive from others.
@end itemize
Please be aware that monotone is a slightly unorthodox version control
tool, and many of its concepts are slightly similar --- but
significantly different --- from concepts with similar names in other
version control tools.
@end ifnottex
@menu
* Concepts:: Taxonomy of monotone
* Tutorial:: A detailed example of using monotone
* Advanced Uses:: Going beyond the basics
* CVS Phrasebook:: Transitional guide for CVS users
* Command Reference:: Details of each monotone command
* Hook Reference:: Functions which extend monotone
* Special Topics:: Extra explanations and details
* Man Page:: That other document
* Default hooks:: The standard hook definitions
* Index:: Index of concepts and functions
@end menu
Complete table of contents
@contents
@node Concepts
@chapter Concepts
This chapter should familiarize you with the concepts, terminology,
and behavior described in the remainder of the user manual. Please
take a moment to read it, as later sections will assume familiarity
with these terms.
@menu
* Versions of files:: Tracking changes to single files
* Versions of trees:: Tracking changes to collections of files
* Historical records:: Tracking the history of changes
* Certificates:: Tracking extended information
* Storage and workflow:: Saving, sending, and receiving changes
* Forks and merges:: Managing divergence of code
* Branches:: Intentional divergence and automatic merging
@end menu
@page
@node Versions of files
@section Versions of files
Suppose you wish to modify a file @file{file.txt} on your
computer. You begin with one @i{version} of the file, load it into
an editor, make some changes, and save the file again. Doing so
produces a new @i{version} of the file. We will say that the older
version of the file was a @dfn{parent}, and the new version is a
@dfn{child}, and that you have performed an @dfn{edit} between the
parent and the child. We may draw the relationship between parent and
child using a graph, where the arrow in the graph indicates the
direction of the edit, from parent to child.
@ifinfo
@smallexample
@group
+----------------+
| |
| parent version |
| of file.txt |
| |
+----------------+
|
|
\|/
V
+----------------+
| |
| child version |
| of file.txt |
| |
+----------------+
@end group
@end smallexample
@end ifinfo
@ifnotinfo
@image{figures/parent-child}
@end ifnotinfo
We may want to identify the parent and the child precisely, for sake
of reference. To do so, we will compute a @i{cryptographic hash
function}, called @sc{sha1}, of each version. The details of this
function are beyond the scope of this document; in summary, the @sc{sha1}
function takes a version of a file and produces a short string of 20
bytes, which we will use to uniquely identify the version@footnote{We
say @sc{sha1} values are ``unique'' here, when in fact there is a
small probability of two different versions having the same @sc{sha1}
value. This probability is very small, so we discount it.}. Now our
graph does not refer to some ``abstract'' parent and child, but rather
to the exact edit we performed between a specific parent and a
specific child.
@ifinfo
@smallexample
@group
+---------------------------------------------------+
| parent version |
| of file.txt |
| |
| SHA1 = 65f1bde1f38262034e7c3457301e8f736ba6381b |
+---------------------------------------------------+
|
|
\|/
V
+---------------------------------------------------+
| child version |
| of file.txt |
| |
| SHA1 = a91566316d208dc405795904f8d67ae3a0e765cb |
+---------------------------------------------------+
@end group
@end smallexample
@end ifinfo
@ifnotinfo
@image{figures/parent-child-names-hashes}
@end ifnotinfo
When dealing with versions of files, we will dispense with writing out
``file names'', and identify versions @i{purely} by their @sc{sha1}
value, which we will also refer to as their @dfn{file ID}. Using IDs
alone will often help us accommodate the fact that people often wish
to call files by different names. So now our graph of parent and child
is just a relationship between two versions, only identified by ID.
@ifinfo
@smallexample
@group
+---------------------------------------------------+
| parent version |
| SHA1 = 65f1bde1f38262034e7c3457301e8f736ba6381b |
+---------------------------------------------------+
|
|
\|/
V
+---------------------------------------------------+
| child version |
| SHA1 = a91566316d208dc405795904f8d67ae3a0e765cb |
+---------------------------------------------------+
@end group
@end smallexample
@end ifinfo
@ifnotinfo
@image{figures/parent-child-hashes}
@end ifnotinfo
Version control systems, such as monotone, are principally concerned
with the storage and management of @i{multiple} versions of some files.
One way to store multiple versions of a file is, literally, to save a
separate @i{complete} copy of the file, every time you make a
change. When necessary, monotone will save complete copies of your
files, compressed with the @command{zlib} compression format.
@ifinfo
@smallexample
@group
+--------------+ +--------------+ +--------------+
| | | | | |
| Hello | | Hello, | | Why, Hello |
| | | world! | | there world, | . . .
| | | | | how do you |
| | | | | do? |
| | | | | |
+--------------+ +--------------+ +--------------+
\______ ______/ \______ ______/ \______ ______/
\/ \/ \/
1st version 2nd version 3rd version
@end group
@end smallexample
@end ifinfo
@ifnotinfo
@image{figures/three-versions}
@end ifnotinfo
Often we find that successive versions of a file are very similar to
one another, so storing multiple complete copies is a waste of
space. In these cases, rather than store @i{complete} copies of each
version of a file, we store a compact description of only the
@i{changes} which are made between versions. Such a description of
changes is called a @dfn{delta}.
Storing deltas between files is, practically speaking, as good as
storing complete versions of files. It lets you undo changes from a
new version, by applying the delta backwards, and lets your friends
change their old version of the file into the new version, by applying
the delta forwards. Deltas are usually smaller than full files, so
when possible monotone stores deltas, using a modified @command{xdelta}
format. The details of this format are beyond the scope of this
document.
@ifinfo
@smallexample
@group
difference
between versions
_____/\____
+--------------+ / \ +--------------+
| | | |
| Hello | +[, world!] | Hello, |
| | | world! |
| | | |
| | | |
| | | |
+--------------+ +--------------+
\______ ______/ \______ ______/
\/ \/
1st version 2nd version
@end group
@end smallexample
@end ifinfo
@ifnotinfo
@image{figures/difference-between-versions}
@end ifnotinfo
@page
@node Versions of trees
@section Versions of trees
After you have made many different files, you may wish to capture a
``snapshot'' of the versions of all the files in a particular collection.
Since files are typically collected into @i{trees} in a file system,
we say that you want to capture a @i{version of your tree}. Doing
so will permit you to undo changes to multiple files at once, or send
your friend a @i{set} of changes to many files at once.
To make a snapshot of a tree, we begin by writing a special file
called a @dfn{manifest}. In fact, monotone will write this file for
us, but we could write it ourselves too. It is just a plain text
file. Each line of a manifest file contains two columns. In the first
column we write the ID of a file in your tree, and in the second
column we write the path to the file, from the root of our tree to the
filename.
@ifinfo
@smallexample
@group
+--------------------------------------------------------------+
| |
| f2e5719b975e319c2371c98ed2c7231313fac9b5 fs/readdir.c |
| 81f0c9a0df254bc8d51bb785713a9f6d0b020b22 fs/read_write.c |
| 943851e7da46014cb07473b90d55dd5145f24de0 fs/pipe.c |
| ddc2686e000e97f670180c60a3066989e56a11a3 fs/open.c |
| 295d276e6c9ce64846d309a8e39507bcb0a14248 fs/namespace.c |
| 71e0274f16cd68bdf9a2bf5743b86fcc1e597cdc fs/namei.c |
| 1112c0f8054cebc9978aa77384e3e45c0f3b6472 fs/iobuf.c |
| 8ddcfcc568f33db6205316d072825d2e5c123275 fs/inode.c |
| |
+--------------------------------------------------------------+
\_____________________________ _______________________________/
\/
an example
manifest file
@end group
@end smallexample
@end ifinfo
@ifnotinfo
@image{figures/manifest}
@end ifnotinfo
Now we note that a manifest is itself a file. Therefore a manifest can
serve as input to the @sc{sha1} function, and thus every manifest has
an ID of its own. By calculating the @sc{sha1} value of a manifest, we
capture the @i{state of our tree} in a single @dfn{manifest ID}. In
other words, the ID of the manifest essentially captures all the IDs
and file names of every file in our tree, combined. So we may treat
manifests and their IDs as @i{snapshots} of a tree of files, though
lacking the actual contents of the files themselves.
@ifinfo
@smallexample
@group
+--------------------------+
| int readdir(...) @{ |
| ... |
| @} |
+--------------------------+
\____________ ___________/
\/
SHA1
||
+--------------||----------------------------------------------+
| \/ |
| f2e5719b975e319c2371c98ed2c7231313fac9b5 fs/readdir.c |
| 81f0c9a0df254bc8d51bb785713a9f6d0b020b22 fs/read_write.c |
| 943851e7da46014cb07473b90d55dd5145f24de0 fs/pipe.c |
| . . . . . . |
+--------------------------------------------------------------+
\_____________________________ _______________________________/
\/
SHA1
||
||
\/
manifest ID:
a2eeaa28574141a7d48fa1cc2802070150b93ec4
@end group
@end smallexample
@end ifinfo
@ifnotinfo
@image{figures/file-id-manifest-id}
@end ifnotinfo
As with versions of files, we may decide to store manifests in their
entirety, or else we may store only a compact description of changes
which occur between different versions of manifests. As with files,
when possible monotone stores compact descriptions of changes between
manifests; when necessary it stores complete versions of manifests.
@page
@node Historical records
@section Historical records
Suppose you sit down to edit some files. Before you start working, you
may record a manifest of the files, for reference sake. When you
finish working, you may record another manifest. These ``before and
after'' snapshots of the tree of files you worked on can serve as
historical records of the set of changes, or @dfn{changeset}, that you
made. In order to capture a ``complete'' view of history -- both the
changes made and the state of your file tree on either side of those
changes -- monotone builds a special composite file called a
@dfn{revision} each time you make changes. Like manifests, revisions
are ordinary text files which can be passed through the @sc{sha1}
function and thus assigned a @dfn{revision ID}.
@ifinfo
@smallexample
@group
+--------------------------------------------------------------+
| |
| ... content of revision ... |
| |
+--------------------------------------------------------------+
\_____________________________ _______________________________/
\/
SHA1
||
\/
revision ID:
1c83997e7ab40c0df47554c81b7d4e7ee691eb0d
@end group
@end smallexample
@end ifinfo
@ifnotinfo
@image{figures/revision}
@end ifnotinfo
The content of a revision makes reference to file IDs, in describing
a changeset, and manifest IDs, in describing tree states ``before and
after'' the changeset. Crucially, revisions also make reference to
@i{other revision IDs}. This fact -- that revisions include the IDs of
other revisions -- causes the set of revisions to join together into a
historical @i{chain of events}, somewhat like a ``linked list''. Each
revision in the chain has a unique ID, which includes @i{by reference}
all the revisions preceeding it. Even if you undo a changeset, and
return to a previously-visited manifest ID during the course of your
edits, each revision will incorporate the ID of its predecessor, thus
forming a new unique ID for each point in history.
@ifinfo
@smallexample
@group
||
+-----------------------------||-------------------------------+
| \/ |
| old_revision: 86d06a095529dca003ad62715dc2be7873edade0 |
| change_set: . . . |
| old_manifest: 1b24ba8b8dc3ff9c87b5198315eced1b279dc74e <----- manifest ID
| new_manifest: dbd022dc423fd7f473e0fa79842cd9901cc2dd69 <----- manifest ID
| |
+--------------------------------------------------------------+
\_____________________________ _______________________________/
\/
SHA1
||
+-----------------------------||-------------------------------+
| \/ |
| old_revision: f45add3bfb21cb459d99b6a9c0111df75f6d9f85 |
| change_set: . . . |
| old_manifest: dbd022dc423fd7f473e0fa79842cd9901cc2dd69 <----- manifest ID
| new_manifest: 8a05c60422770bbf49a3192c2367ddaa066538ca <----- manifest ID
| |
+--------------------------------------------------------------+
\_____________________________ _______________________________/
\/
SHA1
||
\/
revision ID:
1c83997e7ab40c0df47554c81b7d4e7ee691eb0d
@end group
@end smallexample
@end ifinfo
@ifnotinfo
@image{figures/revision-chaining}
@end ifnotinfo
@page
@node Certificates
@section Certificates
Often, you will wish to make a @i{statement} about a revision, such as
stating the reason that you made some changes, or stating the time at
which you made the changes, or stating that the revision passes a test
suite. Statements such as these can be thought of, generally, as a
bundle of information with three parts:
@itemize
@item
an @i{ID}, indicating which revision you are making a statement about
@item
a @i{name} indicating the type of statement you are making, such as
``changelog'', ``date'' or ``testresult''
@item
a @i{value} indicating the remaining detail of the statement, such as
``fixed a bug'', ``March 9th'' or ``1''
@end itemize
For example, if you want to say that a particular revision was
composed on April 4, 2003, you might make a statement like this:
@ifinfo
@smallexample
@group
+------------------------------------------------------+
| revision ID |
| a2eeaa28574141a7d48fa1cc2802070150b93ec4 |
+--------------------------+---------------------------+
| statement name | statement value |
| "date" | "2003-04-04T07:39:51" |
+--------------------------+---------------------------+
@end group
@end smallexample
@end ifinfo
@ifnotinfo
@image{figures/statement}
@end ifnotinfo
In an ideal world, these are all the parts of a statement we would
need in order to go about our work. In the real world, however, there
are sometimes malicious people who would make false or misleading
statements; so we need a way to verify that a particular person made a
particular statement about a revision. We therefore will add two more
pieces of information to our bundle:
@itemize
@item
a @i{key} which identifies the person making a statement
@item
a @i{signature} --- just a large number with particular properties ---
certifying the fact that the person made the statement
@end itemize
When these 2 items accompany a statement, we call the total bundle of
5 items a @dfn{certificate}, or @i{cert}. A cert makes a statement in
a secure fashion. The security of the signature in a cert is derived
from the @sc{rsa} cryptography system, the details of which are beyond
the scope of this document.
@ifinfo
@smallexample
@group
+------------------------------------------------------+
| revision ID |
| a2eeaa28574141a7d48fa1cc2802070150b93ec4 |
+--------------------------+---------------------------+
| cert name | cert value |
| "date" | "2003-04-04T07:39:51" |
+--------------------------+---------------------------+
| signed by key | signature |
| "jrh@@example.com" | "a02380def....0983fe90" |
+--------------------------+---------------------------+
@end group
@end smallexample
@end ifinfo
@ifnotinfo
@image{figures/cert}
@end ifnotinfo
Monotone uses certs extensively. Any ``extra'' information which needs
to be stored, transmitted or retrieved --- above and beyond files,
manifests, and revisions --- is kept in the form of certs. This
includes change logs, time and date records, branch membership,
authorship, test results, and more. When monotone makes a decision
about storing, transmitting, or extracting files, manifests, or
revisions, the decision is often based on certs it has seen, and the
trustworthiness you assign to those certs.
The @sc{rsa} cryptography system --- and therefore monotone itself ---
requires that you exchange special ``public'' numbers with your
friends, before they will trust certificates signed by you. These
numbers are called @dfn{public keys}. Giving someone your public key
does not give them the power to @i{impersonate} you, only to verify
signatures made by you. Exchanging public keys should be done over a
trusted medium, in person, or via a trusted third party. Advanced
secure key exchange techniques are beyond the scope of this document.
Most of monotone's certs refer to revision IDs. Some certs may refer
to file IDs or manifest IDs, depending on context. This capability may
also be removed in the future, at which point certs will @emph{only}
refer to revisions.
@page
@node Storage and workflow
@section Storage and workflow
Monotone moves information in and out of three different types of
storage:
@itemize
@item
a @i{working copy} in the local file system
@item
a @i{local database} in the local file system
@item
a @i{remote database} elsewhere on the internet
@end itemize
All information passes @emph{through} your local database, en route to
some other destination. For example, when changes are made in a
working copy, you may save those changes to your database, and later
you may synchronize your database with someone else's. Monotone will
not move information directly between a working copy and a remote
database, or between working copies. Your local database is always
the ``switching point'' for communication.
@ifinfo
@smallexample
@group
pull, push, sync
(untrusted network exchanges)
_________/\________
/ \
+-------------+ +------------+ +--------------+
| | | | | |
| remote db | <==> | local db | <==> | working copy |
| | | | | |
+-------------+ +------------+ +--------------+
\________ _______/
\/
commit, update
(certified local exchanges)
@end group
@end smallexample
@end ifinfo
@ifnotinfo
@image{figures/general-workflow}
@end ifnotinfo
A @dfn{working copy} is a tree of files in your file system, arranged
according to the list of file paths and IDs in a particular
manifest. A special directory called @file{MT} exists in the root of
any working copy. Monotone keeps some special files in the @file{MT}
directory, in order to track changes you make to your working copy.
Aside from the special @file{MT} directory, a working copy is just a
normal tree of files. You can directly edit the files in a working
copy using a plain text editor or other program; monotone will
automatically notice when you make any changes. If you wish to add
files, remove files, or move files within your working copy, you must
tell monotone explicitly what you are doing, as these actions cannot
be deduced.
If you do not yet have a working copy, you can @dfn{check out} a
working copy from a database, or construct one from scratch and
@dfn{add} it into a database. As you work, you will occasionally
@dfn{commit} changes you have made in a working copy to a database,
and @dfn{update} a working copy to receive changes that have arrived
in a database. Committing and updating take place purely between a
database and a working copy; the network is not involved.
@ifinfo
@smallexample
@group
----------------- check out, working copy
( ) or update +----------------
----------------- ----------> |
| | | src/func.c
| local | <---------- | src/func.h
| database | add, | src/main.c
| | or commit | Makefile
\_________________/ | MT/
|
@end group
@end smallexample
@end ifinfo
@ifnotinfo
@image{figures/local-workflow}
@end ifnotinfo
A @dfn{database} is a single, regular file. You can copy or back it up
using standard methods. Typically you keep a database in your home
directory. Databases are portable between different machine types. You
can have multiple databases and divide your work between them, or keep
everything in a single database if you prefer. You can dump portions of
your database out as text, and read them back into other databases, or
send them to your friends. Underneath, databases are accessed using a
standard, robust data manager, which makes using even very large
databases efficient. In dire emergencies, you can directly examine and
manipulate a database using a simple SQL interface.
A database contains many files, manifests, revisions, and
certificates, some of which are not immediately of interest, some of
which may be unwanted or even false. It is a collection of information
received from network servers, working copies, and other
databases. You can inspect and modify your databases without affecting
your working copies, and vice-versa.
Monotone knows how to exchange information in your database with other
remote databases, using an interactive protocol called @dfn{netsync}.
It supports three modes of exchange: pushing, pulling, and
synchronizing. A @dfn{pull} operation copies data from a remote
database to your local database. A @dfn{push} operation copies data
from your local database to a remote database. A @dfn{sync} operation
copies data both directions. In each case, only the data missing from
the destination is copied. The netsync protocol calculates the data to
send ``on the fly'' by exchanging partial hash values of each
database.
@ifinfo
@smallexample
@group
----------------- -----------------
( ) ( )
----------------- --- pull ---> -----------------
| | | |
| remote | <--- sync ---> | local |
| database | | database |
| | <--- push --- | |
\_________________/ \_________________/
@end group
@end smallexample
@end ifinfo
@ifnotinfo
@image{figures/network-workflow}
@end ifnotinfo
In general, work flow with monotone involves 3 distinct stages:
@itemize
@item
When you @i{commit} changes from your working copy to your database,
your database stores the changes but does not communicate with the
network. Your commits happen immediately, without consulting any other
party, and do not require network connectivity.
@item
When you are ready to @i{exchange} work with someone else, you can
push, pull, or sync with other databases on the network. When you talk
to other servers on the network, your database may change, but your
working copy will not. In fact, you do not need a working copy at all
when exchanging work.
@item
When you @i{update} your working copy, some (but not all) of the
changes which your database received from the network are applied to
your working copy. The network is not consulted during updates.
@end itemize
The last stage of workflow is worth clarifying: monotone does
@emph{not} blindly apply all changes it receives from a remote
database to your working copy. Doing so would be very dangerous,
because remote databases are not always trustworthy systems. Rather,
monotone evaluates the certificates it has received along with the
changes, and decides which particular changes are safe and desirable
to apply to your working copy.
You can always adjust the criteria monotone uses to judge the
trustworthiness and desirability of changes in your database. But keep
in mind that it always uses @emph{some} criteria; receiving changes
from a remote server is a @emph{different} activity than applying
changes to a working copy. Sometimes you may receive changes which
monotone judges to be untrusted or bad; such changes may stay in your
database but will @emph{not} be applied to your working copy.
Remote databases, in other words, are just untrusted ``buckets'' of
data, which you can trade with promiscuously. There is no trust
implied in communication.
@page
@node Forks and merges
@section Forks and merges
So far we have been talking about revisions as though each logically
follows exactly one revision before it, in a simple sequence of
revisions.
@ifinfo
@smallexample
@group
+-----------------------+
| parent revision |
+-----------------------+
|
|
+-----------------------+
| child revision |
+-----------------------+
|
|
+-----------------------+
| grandchild revision |
+-----------------------+
@end group
@end smallexample
@end ifinfo
@ifnotinfo
@image{figures/linear-history}
@end ifnotinfo
This is a rosy picture, but sometimes it does not work out this
way. Sometimes when you make new revisions, other people are
@i{simultaneously} making new revisions as well, and their revisions
might be derived from the same parent as yours, or contain different
changesets. Without loss of generality, we will assume simultaneous
edits only happen two-at-a-time; in fact many more edits may happen at
once but our reasoning will be the same.
We call this situation of simultaneous edits a @dfn{fork}, and will
refer to the two children of a fork as the @i{left child} and @i{right
child}. In a large collection of revisions with many people editing
files, especially on many different computers spread all around the
world, forks are a common occurrence.
@ifinfo
@smallexample
@group
+-----------------+
| parent revision |
+-----------------+
| |
+--------+ +---------+
| |
+-------------+ +--------------+
| left child | | right child |
+-------------+ +--------------+
@end group
@end smallexample
@end ifinfo
@ifnotinfo
@image{figures/fork}
@end ifnotinfo
If we analyze the changes in each child revision, we will often find
that the changeset between the parent and the left child are unrelated
to the changeset between the parent and the right child. When this
happens, we can usually @dfn{merge} the fork, producing a common
grandchild revision which contains both changesets.
@ifinfo
@smallexample
@group
+-----------------+
| parent revision |
+-----------------+
| |
+--------+ +---------+
| |
+-------------+ +--------------+
| left child | | right child |
+-------------+ +--------------+
| |
+--------+ +---------+
| |
+-----------------+
| merged revision |
+-----------------+
@end group
@end smallexample
@end ifinfo
@ifnotinfo
@image{figures/merge}
@end ifnotinfo
@page
@node Branches
@section Branches
Sometimes, people intentionally produce forks which are @emph{not
supposed to be merged}; perhaps they have agreed to work independently
for a time, or wish to change their files in ways which are not
logically compatible with each other. When someone produces a fork
which is supposed to last for a while (or perhaps permanently) we say
that the fork has produced a new @dfn{branch}. Branches tell monotone
which revisions you would like to merge, and which you would like to
keep separate.
You can see all the available branches using @code{monotone list branches}.
Branches are indicated with certs. The cert name @code{branch} is
reserved for use by monotone, for the purpose of identifying the
revisions which are members of a branch. A @code{branch} cert has a
symbolic ``branch name'' as its value. When we refer to ``a branch'',
we mean all revisions with a common branch name in their @code{branch}
certs.
For example, suppose you are working on a program called ``wobbler''.
You might develop many revisions of wobbler and then decide to split
your revisions into a ``stable branch'' and an ``unstable branch'', to
help organize your work. In this case, you might call the new branches
``wobbler-stable'' and ``wobbler-unstable''. From then on, all
revisions in the stable branch would get a cert with name @code{branch}
and value @code{wobbler-stable}; all revisions in the unstable branch
would get a cert with name @code{branch} and value
@code{wobbler-unstable}. When a @code{wobbler-stable} revision forks,
the children of the fork will be merged. When a
@code{wobbler-unstable} revision forks, the children of the fork will
be merged. However, the @code{wobbler-stable} and
@code{wobbler-unstable} branches will not be merged together, despite
having a common ancestor.
@ifinfo
@smallexample
@group
+--------------------------+
| common ancestor revision |
+--------------------------+
| |
+---------+ +---------+
| |
+-----------------+ +-------------------+
| stable revision | | unstable revision |
+-----------------+ +-------------------+
| | | |
+-------+ +-------+ +-------+ +-------+
| | | |
+-------------+ +--------------+ +---------------+ +----------------+
| left stable | | right stable | | left unstable | | right unstable |
| child | | child | | child | | child |
+-------------+ +--------------+ +---------------+ +----------------+
| | | |
+-------+ +--------+ +-------+ +--------+
| | | |
+----------------+ +------------------+
| merged stable | | merged unstable |
| revision | | revision |
+----------------+ +------------------+
\_____________ _______________/ \_______________ _________________/
\/ \/
stable branch unstable branch
@end group
@end smallexample
@end ifinfo
@ifnotinfo
@image{figures/two-branches}
@end ifnotinfo
For each branch, the set of revisions with @emph{no children} is
called the @dfn{heads} of the branch. Monotone can automatically
locate, and attempt to merge, the heads of a branch. If it fails to
automatically merge the heads, it may ask you for assistance or else
fail cleanly, leaving the branch alone.
For example, if a fork's left child has a child of its own (a ``left
grandchild''), monotone will merge the fork's right child with the
left grandchild, since those revisions are the heads of the branch. It
will not merge the left child with the right child, because the left
child is not a member of the heads.
@ifinfo
@smallexample
@group
+-----------------+
| parent revision |
+-----------------+
| |
+--------+ |
| |
+-------------+ |
| left child | |
+-------------+ |
| |
*************|****************|************
* | | *
* +-----------------+ +-------------+ *
* | left grandchild | | right child | * the heads of the branch
* +-----------------+ +-------------+ * (before the merge)
* | | *
*************|****************|************
| |
+--------+ +---+
| |
+-----------------+
| merged revision |
+-----------------+
@end group
@end smallexample
@end ifinfo
@ifnotinfo
@image{figures/branch-heads}
@end ifnotinfo
When there is only one revision in the heads of a branch, we say that
@i{the heads are merged}, or more generally that @i{the branch is
merged}, since the heads is the logical set of candidates for any
merging activity. If there are two or more revisions in the heads of a
branch, and you ask to merge the branch, monotone will merge them
two-at-a-time until there is only one.
@subsection Branch Names
The branch names used in the above section are fine for an example, but
they would be bad to use in a real project. The reason is, monotone
branch names must be @emph{globally} unique, over all branches in the
world. Otherwise, bad things can happen. Fortunately, we have a handy
source of globally unique names --- the DNS system.
When naming a branch, always prepend the reversed name of a host that
you control or are otherwise authorized to use. For example, monotone
development happens on the branch @code{net.venge.monotone}, because
@code{venge.net} belongs to monotone's primary author. The idea is that
this way, you can coordinate with other people using a host to make sure
there are no conflicts --- in the example, monotone's primary author can
be certain that no-one else using @code{venge.net} will start up a
different program named @code{monotone}. If you work for Yoyodyne,
Inc. (owners of yoyodyne.com), then all your branch names should look
like @code{com.yoyodyne.@emph{something}}.
What the @code{@emph{something}} part looks like is up to you, but
usually the first part is the project name (the @code{monotone} in
@code{net.venge.monotone}), and then possibly more stuff after that to
describe a particular branch. For example, monotone's win32 support
was initially developed on the branch @code{net.venge.monotone.win32}.
(For more information, see @ref{Naming Conventions}.)
@node Tutorial
@chapter Tutorial
This chapter illustrates the basic uses of monotone by means of an
example, fictional software project. Before we walk through the
tutorial, there are two minor issues to address: standard options and
revision selectors.
@subsection Standard Options
Before operating monotone, two important command-line options should
be explained.
@itemize
@item
Most commands operate on a @i{database}, which is selected with
the @option{--db} option.
@item
Many commands operate on a subset of the database, called a
@i{branch}, which is selected with the @option{--branch} option.
@end itemize
Monotone will cache the settings for these options in your working
copy, so ordinarily once you have checked out a project, you will not
need to specify them again. We will therefore only mention these
arguments in the first example.
@subsection Revision Selectors
Many commands require you to supply 40-character @sc{sha1} values as
arguments, which identify revisions. These ``revision IDs'' are
tedious to type, so monotone permits you to supply ``revision
selectors'' rather than complete revision IDs. Selectors are a more
``human friendly'' way of specifying revisions by combining certificate
values into unique identifiers. This ``selector'' mechanism can be
used anywhere a revision ID would normally be used. For details on
selector syntax, see @ref{Selectors}.
We are now ready to explore our fictional project.
@page
@section The Fictional Project
Our fictional project involves 3 programmers cooperating to write
firmware for a robot, the JuiceBot 7, which dispenses fruit juice. The
programmers are named Jim, Abe and Beth.
@itemize
@item
Jim lives in Japan, and owns JuiceBot Inc. You will know when we're talking
about Jim, because everything he does involves the letter ``j''.
@item
Abe lives in Australia and writes code related to apple juice. You will
know when we're talking about Abe, because everything he does involves
the letter ``a''.
@item
Beth lives in Brazil and writes code related to banana juice. You will
know when we're talking about Beth, because everything she does involves
the letter ``b''.
@end itemize
In our example the programmers work privately on laptops, and are
usually @emph{disconnected} from the network. They share no storage
system. Thus when each programmer enters a command, it affects only
his or her own computer, unless otherwise stated.
In the following, our fictional project team will work through several
version control tasks. Some tasks must be done by each member of our
example team; other tasks involve only one member.
@menu
* Creating a Database::
* Generating Keys::
* Starting a New Project::
* Adding Files::
* Committing Work::
* Network Service::
* Making Changes::
* Dealing with a Fork::
* Branching and Merging::
@end menu
@page
@node Creating a Database
@section Creating a Database
The first step Jim, Abe and Beth each need to perform is to create a
new database. This is done with the @code{monotone db init} command,
providing a @option{--db} option to specify the location of the new
database. Each programmer creates their own database, which will
reside in their home directory and store all the revisions, files and
manifests they work on. Monotone requires this step as an explicit
command, to prevent spurious creation of databases when an invalid
@option{--db} option is given.
In real life, most people prefer to keep one database for each project
they work on. If we followed that convention here in the tutorial,
though, then all the databases would be called @code{juicebot.db}, and
that would make things more confusing to read. So instead, we'll have
them each name their database after themselves.
Thus Jim issues the command:
@smallexample
@group
$ monotone db init --db=~/jim.db
@end group
@end smallexample
Abe issues the command:
@smallexample
@group
$ monotone db init --db=~/abe.db
@end group
@end smallexample
And Beth issues the command:
@smallexample
@group
$ monotone db init --db=~/beth.db
@end group
@end smallexample
@page
@node Generating Keys
@section Generating Keys
Now Jim, Abe and Beth must each generate an @sc{rsa} key pair for
themselves. This step requires choosing a key identifier. Typical key
identifiers are similar to email addresses, possibly modified with
some prefix or suffix to distinguish multiple keys held by the same
owner. Our example programmers will use their email addresses at the
fictional ``juicebot.co.jp'' domain name. When we ask for a key to be
generated, monotone will ask us for a passphrase. This phrase is used
to encrypt the key when storing it on disk, as a security measure.
Jim does the following:
@smallexample
@group
$ monotone --db=~/jim.db genkey jim@@juicebot.co.jp
enter passphrase for key ID [jim@@juicebot.co.jp] : @i{<Jim enters his passphrase>}
monotone: generating key-pair 'jim@@juicebot.co.jp'
monotone: storing key-pair 'jim@@juicebot.co.jp' in database
@end group
@end smallexample
Abe does something similar:
@smallexample
@group
$ monotone --db=~/abe.db genkey abe@@juicebot.co.jp
enter passphrase for key ID [abe@@juicebot.co.jp] : @i{<Abe enters his passphrase>}
monotone: generating key-pair 'abe@@juicebot.co.jp'
monotone: storing key-pair 'abe@@juicebot.co.jp' in database
@end group
@end smallexample
as does Beth:
@smallexample
@group
$ monotone --db=~/beth.db genkey beth@@juicebot.co.jp
enter passphrase for key ID [beth@@juicebot.co.jp] : @i{<Beth enters her passphrase>}
monotone: generating key-pair 'beth@@juicebot.co.jp'
monotone: storing key-pair 'beth@@juicebot.co.jp' in database
@end group
@end smallexample
Each programmer has now generated a key pair and placed it in their
local database. Each can list the keys in their database, to ensure
the correct key was generated. For example, Jim might see this:
@smallexample
@group
$ monotone --db=~/jim.db list keys
[public keys]
9e9e9ef1d515ad58bfaa5cf282b4a872d8fda00c jim@@juicebot.co.jp
[private keys]
771ace046c27770a99e5fddfa99c9247260b5401 jim@@juicebot.co.jp
@end group
@end smallexample
The hexadecimal string printed out before each key name is a
@emph{fingerprint} of the key, and can be used to verify that the key
you have stored under a given name is the one you intended to
store. Monotone will never permit one database to store two keys with
the same name or the same fingerprint.
This output shows one private and one public key stored under the name
@code{jim@@juicebot.co.jp}, so it indicates that Jim's key-pair has
been successfully generated and stored. On subsequent commands, Jim
will need to re-enter our passphrase in order to perform
security-sensitive tasks. To simplify matters, Jim decides to store
his security passphrase in his @code{monotonerc} file, by writing a
@emph{hook function} which returns the passphrase, so that he does not
need to repeatedly be prompted for it:
@smallexample
@group
$ mkdir ~/.monotone
$ cat >>~/.monotone/monotonerc
function get_passphrase(keypair_id)
return "jimsekret"
end
^D
@end group
@end smallexample
Note that we are appending the new hook to the (possibly existing) file.
We do this to avoid loosing other changes by mistake; therefore, be sure
to check that no other @code{get_passphrase} function appears in the
configuration file.
Abe and Beth do the same, with their secret passphrases.
@page
@node Starting a New Project
@section Starting a New Project
Before he can begin work on the project, Jim needs to create a
@i{working copy} --- a directory whose contents monotone will keep track
of. Often, one works on projects that someone else has started, and
creates working copies with the @code{checkout} command, which you'll
learn about later. Jim is starting a new project, though, so he does
something a little bit different. He uses the @code{monotone setup}
command to create a new working copy.
This command creates the named directory (if it doesn't already exist),
and creates the @file{MT} directory within it. The @file{MT} directory
is how monotone recognizes that a directory is a working copy, and
monotone stores some bookkeeping files within it. For instance, command
line values for the @option{--db}, @option{--branch} or @option{--key}
options to the @code{setup} command will be cached in a file called
@file{MT/options}, so you don't have to keep passing them to monotone
all the time.
Jim creates his working copy:
@smallexample
@group
/home/jim$ monotone setup juice
/home/jim$ cd juice
/home/jim/juice$
@end group
@end smallexample
Notice that Jim has changed his current directory to his newly created
working copy. For the rest of this example we will assume that everyone
issues all further monotone commands from their working copy
directories.
@page
@node Adding Files
@section Adding Files
Next Jim decides to add some files to the project. He writes up
a file containing the prototypes for the JuiceBot 7:
@smallexample
@group
$ mkdir include
$ cat >include/jb.h
/* Standard JuiceBot hw interface */
#define FLOW_JUICE 0x1
#define POLL_JUICE 0x2
int spoutctl(int port, int cmd, void *x);
/* JuiceBot 7 API */
#define APPLE_SPOUT 0x7e
#define BANANA_SPOUT 0x7f
void dispense_apple_juice ();
void dispense_banana_juice ();
^D
@end group
@end smallexample
Then adds a couple skeleton source files which he wants Abe and Beth
to fill in:
@smallexample
@group
$ mkdir src
$ cat >src/apple.c
#include "jb.h"
void
dispense_apple_juice()
@{
/* Fill this in please, Abe. */
@}
^D
$ cat >src/banana.c
#include "jb.h"
void
dispense_banana_juice()
@{
/* Fill this in please, Beth. */
@}
^D
@end group
@end smallexample
Now Jim tells monotone to add these files to its record of his working
copy. He specifies one filename and one directory; monotone
recursively scans the directory and adds all its files.
@smallexample
@group
$ monotone --db=~/jim.db add include/jb.h src
monotone: adding include/jb.h to working copy add set
monotone: adding src/apple.c to working copy add set
monotone: adding src/banana.c to working copy add set
@end group
@end smallexample
This command produces a record of Jim's intentions in a special file
called @file{MT/work}, stored in the working copy. The file is plain
text:
@smallexample
@group
$ cat MT/work
add_file "include/jb.h"
add_file "src/apple.c"
add_file "src/banana.c"
@end group
@end smallexample
Jim then gets up from his machine to get a coffee. When he returns
he has forgotten what he was doing. He asks monotone:
@smallexample
@group
$ monotone --db=jim.db status
new_manifest [2098eddbe833046174de28172a813150a6cbda7b]
old_revision []
old_manifest []
add_file "include/jb.h"
add_file "src/apple.c"
add_file "src/banana.c"
patch "include/jb.h"
from []
to [3b12b2d0b31439bd50976633db1895cff8b19da0]
patch "src/apple.c"
from []
to [2650ffc660dd00a08b659b883b65a060cac7e560]
patch "src/banana.c"
from []
to [e8f147e5b4d5667f3228b7bba1c5c1e639f5db9f]
@end group
@end smallexample
The output of this command tells Jim that his edits, so far,
constitute only the addition of some files. In the output we can see
one pecularity of monotone's changeset format. The pecularity is that
when monotone records a ``new file'', it actually records two separate
events: the addition of an empty file to the working copy, and a patch
of that file from empty to its intended contents.
Jim wants to see the actual details of the files he added, however, so
he runs a command which prints out the status @emph{and} a GNU
``unified diff'' of the patches involved in the changeset:
@smallexample
@group
$ monotone --db=jim.db diff
#
# add_file "include/jb.h"
#
# add_file "src/apple.c"
#
# add_file "src/banana.c"
#
# patch "include/jb.h"
# from []
# to [3b12b2d0b31439bd50976633db1895cff8b19da0]
#
# patch "src/apple.c"
# from []
# to [2650ffc660dd00a08b659b883b65a060cac7e560]
#
# patch "src/banana.c"
# from []
# to [e8f147e5b4d5667f3228b7bba1c5c1e639f5db9f]
#
--- include/jb.h
+++ include/jb.h
@@ -0,0 +1,13 @@
+/* Standard JuiceBot hw interface */
+
+#define FLOW_JUICE 0x1
+#define POLL_JUICE 0x2
+#define SET_INTR 0x3
+int spoutctl(int port, int cmd, void *x);
+
+/* JuiceBot 7 API */
+
+#define APPLE_SPOUT 0x7e
+#define BANANA_SPOUT 0x7f
+void dispense_apple_juice ();
+void dispense_banana_juice ();
--- src/apple.c
+++ src/apple.c
@@ -0,0 +1,7 @@
+#include "jb.h"
+
+void
+dispense_apple_juice()
+@{
+ /* Fill this in please, Abe. */
+@}
--- src/banana.c
+++ src/banana.c
@@ -0,0 +1,7 @@
+#include "jb.h"
+
+void
+dispense_banana_juice()
+@{
+ /* Fill this in please, Beth. */
+@}
@end group
@end smallexample
@page
@node Committing Work
@section Committing Work
Satisfied with the work he's done, Jim wants to save his changes. He
chooses @code{jp.co.juicebot.jb7} as a branch name. (See @ref{Naming
Conventions} for more information about appropriate branch names.) He
then commits his working copy, which causes monotone to process the
@file{MT/work} file and record the file contents, manifest, and revision
into the database.
@smallexample
@group
$ monotone --db=jim.db --branch=jp.co.juicebot.jb7 commit --message="initial checkin of project"
monotone: beginning commit on branch 'jp.co.juicebot.jb7'
monotone: committed revision 2e24d49a48adf9acf3a1b6391a080008cbef9c21
@end group
@end smallexample
Monotone did a number of things when committing the new
revision. First, we can see from the output that monotone generated a
manifest of the tree Jim committed. The manifest is stored inside the
database, but Jim can print it out if he wants to see the exact state
of all the files referenced by the revision he committed:
@smallexample
@group
$ monotone cat manifest
3b12b2d0b31439bd50976633db1895cff8b19da0 include/jb.h
2650ffc660dd00a08b659b883b65a060cac7e560 src/apple.c
e8f147e5b4d5667f3228b7bba1c5c1e639f5db9f src/banana.c
@end group
@end smallexample
The column on the left contains cryptographic hashes of the files
listed in the column on the right. Such a hash is also called the
``file ID'' of the file. The file ID identifies the state of each file
stored in Jim's tree. The manifest is just a plain text file,
identical to the output from the popular @command{sha1sum} unix
command.
When monotone committed Jim's revision, it also erased the
@file{MT/work} file, and wrote a new file called @file{MT/revision},
which contains the working copy's new base revision ID. Jim can use
this revision ID in the future, as an argument to the
@command{checkout} command, if he wishes to return to this revision:
@smallexample
@group
$ cat MT/revision
2e24d49a48adf9acf3a1b6391a080008cbef9c21
@end group
@end smallexample
Finally, monotone also generated a number of certificates, attached to
the new revision. These certs store metadata about the commit. Jim can
ask monotone for a list of certs on this revision.
@smallexample
@group
$ monotone ls certs 2e24d49a48adf9acf3a1b6391a080008cbef9c21
-----------------------------------------------------------------
Key : jim@@juicebot.co.jp
Sig : ok
Name : branch
Value : jp.co.juicebot.jb7
-----------------------------------------------------------------
Key : jim@@juicebot.co.jp
Sig : ok
Name : date
Value : 2004-10-26T02:53:08
-----------------------------------------------------------------
Key : jim@@juicebot.co.jp
Sig : ok
Name : author
Value : jim@@juicebot.co.jp
-----------------------------------------------------------------
Key : jim@@juicebot.co.jp
Sig : ok
Name : changelog
Value : initial checkin of project
@end group
@end smallexample
The output of this command has a block for each cert found. Each block
has 4 significant pieces of information. The first indicates the
signer of the cert, in this case @code{jim@@juicebot.co.jp}. The
second indicates whether this cert is ``ok'', meaning whether the
@sc{rsa} signature provided is correct for the cert data. The third is
the cert name, and the fourth is the cert value. This list shows us
that monotone has confirmed that, according to
@code{jim@@juicebot.co.jp}, the revision
@code{2e24d49a48adf9acf3a1b6391a080008cbef9c21} is a member of the
branch @code{jp.co.juicebot.jb7}, written by
@code{jim@@juicebot.co.jp}, with the given date and changelog.
It is important to keep in mind that revisions are not ``in'' or
``out'' of a branch in any global sense, nor are any of these cert
values @i{true} or @i{false} in any global sense. Each cert indicates
that @i{some person} -- in this case Jim -- would like to associate a
revision with some value; it is up to you to decide if you want to
accept that association.
Jim can now check the status of his branch using the ``heads''
command, which lists all the head revisions in the branch:
@smallexample
@group
$ monotone heads
branch 'jp.co.juicebot.jb7' is currently merged:
2e24d49a48adf9acf3a1b6391a080008cbef9c21 jim@@juicebot.co.jp 2004-10-26T02:53:08
@end group
@end smallexample
The output of this command tells us that there is only one current
``head'' revision in the branch @code{jp.co.juicebot.jb7}, and it is
the revision Jim just committed. A head revision is one without any
descendents. Since Jim has not committed any changes to this revision
yet, it has no descendents.
@page
@node Network Service
@section Network Service
Jim now decides he will make his base revision available to his
employees. To do this he gives Abe and Beth permission to access his
database. There are two parts to this: first, he has to get a copy of
each of their public keys; then, he has to tell monotone that the
holders of those keys are permitted to access his database.
First, Abe exports his public key:
@smallexample
@group
$ monotone --db=~/abe.db pubkey abe@@juicebot.co.jp >~/abe.pubkey
@end group
@end smallexample
His public key is just a plain block of ASCII text:
@smallexample
@group
$ cat ~/abe.pubkey
[pubkey abe@@juicebot.co.jp]
MIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQCbaVff9SF78FiB/1nUdmjbU/TtPyQqe/fW
CDg7hSg1yY/hWgClXE9FI0bHtjPMIx1kBOig09AkCT7tBXM9z6iGWxTBhSR7D/qsJQGPorOD
DO7xovIHthMbZZ9FnvyB/BCyiibdWgGT0Gtq94OKdvCRNuT59e5v9L4pBkvajb+IzQIBEQ==
[end]
@end group
@end smallexample
Beth also exports her public key:
@smallexample
@group
$ monotone --db=~/beth.db pubkey beth@@juicebot.co.jp >~/beth.pubkey
@end group
@end smallexample
Then Abe and Beth both send their keys to Jim. The keys are not secret,
but the team members must be relatively certain that they are
communicating with the person they intend to trust, when exchanging
keys, and not some malicious person pretending to be a team
member. Key exchange may involve sending keys over an encrypted
medium, or meeting in person to exchange physical copies, or any
number of techniques. All that matters, ultimately, is that Jim receives
both Abe's and Beth's key.
So eventually, after key exchange, Jim has the public key files in his
home directory. He tells monotone to read the associated key packets
into his database:
@smallexample
@group
$ monotone --db=~/jim.db read <~/abe.pubkey
monotone: read 1 packet
$ monotone --db=~/jim.db read <~/beth.pubkey
monotone: read 1 packet
@end group
@end smallexample
Now Jim's monotone is able to identify Beth and Abe, and he is ready to
give them permission to access his database. He does this by adding a
small amount of extra information to his @file{monotonerc} file:
@smallexample
@group
$ cat >>~/.monotone/monotonerc
function get_netsync_read_permitted (branch, identity)
if (identity == "abe@@juicebot.co.jp") then return true end
if (identity == "beth@@juicebot.co.jp") then return true end
return false
end
function get_netsync_write_permitted (branch, identity)
if (identity == "abe@@juicebot.co.jp") then return true end
if (identity == "beth@@juicebot.co.jp") then return true end
return false
end
function get_netsync_anonymous_read_permitted (branch)
return false
end
^D
@end group
@end smallexample
He then makes sure that his TCP port 5253 is open to incoming
connections, adjusting his firewall settings as necessary, and runs
the monotone @command{serve} command:
@smallexample
@group
$ monotone --db=jim.db serve jim-laptop.juicebot.co.jp "jp.co.juicebot.jb7.*"
@end group
@end smallexample
This command sets up a single listener loop on the host
@code{jim-laptop.juicebot.co.jp}, serving all branches matching
@code{jp.co.juicebot.jb7.*}. This will naturally
include the @code{jp.co.juicebot.jb7} branch, and any sub-branches.
Now Abe decides he wishes to fetch Jim's code. To do this he issues
the monotone @code{sync} command:
@smallexample
@group
monotone --db=abe.db sync jim-laptop.juicebot.co.jp "jp.co.juicebot.jb7.*"
monotone: rebuilding merkle trees for pattern jp.co.juicebot.jb7.*
monotone: connecting to jim-laptop.juicebot.co.jp
monotone: [bytes in: 3200] [bytes out: 673]
monotone: successful exchange with jim-laptop.juicebot.co.jp
@end group
@end smallexample
Abe now has, in his database, a copy of everything Jim put in the
branch. Therefore Abe can disconnect from the expensive network
connection he's on and work locally for a while. When Abe wants to
send work back to Jim, or get new work Jim has added, all he needs to
do is run the @command{sync} command again and work will flow both
ways, bringing each party up to date with the work of the other.
At this point Jim is operating as a sort of ``central server'' for the
company. If Jim wants to, he can leave his server running forever, or
even put his server on a dedicated computer with better network
connectivity. But if Jim is ever unable to play this role of ``central
server'', perhaps due to a network failure, either Beth or Abe can run
the @command{serve} command and provide access for the other to
@command{sync} with. In fact, each employee can run a server if they
like, concurrently, to help minimize the risk of service disruption from
hardware failures. Changes will flow between servers automatically as
clients access them and trade with one another.
In practice, most people like to use at least one central server that is
always running; this way, everyone always knows where to go to get the
latest changes, and people can push their changes out without first
calling their friends and making sure that they have their servers
running. To make this style of working more convenient, monotone
remembers the first server you use, and makes that the default for
future operations.
@page
@node Making Changes
@section Making Changes
Abe decides to do some work on his part of the code. He has a copy of
Jim's database contents, but cannot edit any of that data yet. He
begins his editing by checking out the head of the
@code{jp.co.juicebot.jb7} branch into a working copy, so he can edit
it:
@smallexample
@group
$ monotone --db=abe.db --branch=jp.co.juicebot.jb7 checkout .
@end group
@end smallexample
Monotone unpacks the set of files in the head revision's manifest
directly into Abe's current directory. (If he had specified something
other than @file{.} at the end, monotone would have created that
directory and unpacked the files into it.) Abe then opens up one of the
files, @file{src/apple.c}, and edits it:
@smallexample
@group
$ vi src/apple.c
@i{<Abe writes some apple-juice dispensing code>}
@end group
@end smallexample
The file @file{src/apple.c} has now been @emph{changed}. Abe gets
up to answer a phone call, and when he returns to his work he has
forgotten what he changed. He can ask monotone for details:
@smallexample
@group
$ monotone diff
#
# patch "src/apple.c"
# from [2650ffc660dd00a08b659b883b65a060cac7e560]
# to [e2c418703c863eabe70f9bde988765406f885fd0]
#
--- src/apple.c
+++ src/apple.c
@@ -1,7 +1,10 @@
#include "jb.h"
void
dispense_apple_juice()
@{
- /* Fill this in please, Abe. */
+ spoutctl(APPLE_SPOUT, FLOW_JUICE, 1);
+ while (spoutctl(APPLE_SPOUT, POLL_JUICE, 1) == 0)
+ usleep (1000);
+ spoutctl(APPLE_SPOUT, FLOW_JUICE, 0);
@}
@end group
@end smallexample
Satisfied with his day's work, Abe decides to commit.
@smallexample
@group
$ monotone commit
monotone: beginning commit on branch 'jp.co.juicebot.jb7'
monotone: commited revision 70decb4b31a8227a629c0e364495286c5c75f979
@end group
@end smallexample
Abe neglected to provide a @option{--message} option specifying the
change log on the command line and the file @file{MT/log} is empty
because he did not document his changes there. Monotone therefore
invokes an external ``log message editor'' --- typically an editor
like @command{vi} --- with an explanation of the changes being
committed and the opportunity to enter a log message.
@smallexample
@group
polling implementation of src/apple.c
MT:
MT: ----------------------------------------------------------------------
MT: Enter Log. Lines beginning with `MT:' are removed automatically
MT:
MT: new_manifest [b33cb337dccf21d6673f462d677a6010b60699d1]
MT:
MT: old_revision [2e24d49a48adf9acf3a1b6391a080008cbef9c21]
MT: old_manifest [2098eddbe833046174de28172a813150a6cbda7b]
MT:
MT: patch "src/apple.c"
MT: from [2650ffc660dd00a08b659b883b65a060cac7e560]
MT: to [e2c418703c863eabe70f9bde988765406f885fd0]
MT:
MT: ----------------------------------------------------------------------
MT:
@end group
@end smallexample
Abe enters a single line above the explanatory message, saying
``polling implementation of src/apple.c''. He then saves the file and
quits the editor. Monotone deletes all the lines beginning with
``MT:'' and leaves only Abe's short message. Returning to the shell,
Abe's commit completes:
@smallexample
@group
monotone: committed revision 70decb4b31a8227a629c0e364495286c5c75f979
@end group
@end smallexample
Abe then sends his new revision back to Jim:
@smallexample
@group
$ monotone sync jim-laptop.juicebot.co.jp "jp.co.juicebot.jb7.*"
monotone: rebuilding merkle trees for pattern jp.co.juicebot.jb7.*
monotone: including branch jp.co.juicebot.jb7
monotone: [keys: 2] [rcerts: 8]
monotone: connecting to jim-laptop.juicebot.co.jp
monotone: [bytes in: 630] [bytes out: 2844]
monotone: successful exchange with jim-laptop.juicebot.co.jp
@end group
@end smallexample
Beth does a similar sequence. First she syncs her database with
Jim's:
@smallexample
@group
$ monotone --db=beth.db sync jim-laptop.juicebot.co.jp "jp.co.juicebot.jb7.*"
monotone: rebuilding merkle trees for pattern jp.co.juicebot.jb7.*
monotone: connecting to jim-laptop.juicebot.co.jp
monotone: [bytes in: 3200] [bytes out: 673]
monotone: successful exchange with jim-laptop.juicebot.co.jp
@end group
@end smallexample
She checks out a copy of the tree from her database:
@smallexample
@group
$ monotone --db=beth.db --branch=jp.co.juicebot.jb7 checkout .
@end group
@end smallexample
She edits the file @file{src/banana.c}:
@smallexample
@group
$ vi src/banana.c
@i{<Beth writes some banana-juice dispensing code>}
@end group
@end smallexample
and logs her changes in @file{MT/log} right away so she does not
forget what she has done like Abe.
@smallexample
@group
$ vi MT/log
* src/banana.c: Added polling implementation
@end group
@end smallexample
Later, she commits her work. Monotone again invokes an external editor
for her to edit her log message, but this time it fills in the messages
she's written so far, and she simply checks them over one last time
before finishing her commit:
@smallexample
@group
$ monotone commit
monotone: beginning commit on branch 'jp.co.juicebot.jb7'
monotone: committed revision 80ef9c9d251d39074d37e72abf4897e0bbae1cfb
@end group
@end smallexample
And she syncs with Jim again:
@smallexample
@group
$ monotone sync jim-laptop.juicebot.co.jp "jp.co.juicebot.jb7.*"
monotone: rebuilding merkle trees for pattern jp.co.juicebot.jb7.*
monotone: including branch jp.co.juicebot.jb7
monotone: [keys: 3] [rcerts: 12]
monotone: connecting to jim-laptop.juicebot.co.jp
monotone: [bytes in: 630] [bytes out: 2844]
monotone: successful exchange with jim-laptop.juicebot.co.jp
@end group
@end smallexample
@page
@node Dealing with a Fork
@section Dealing with a Fork
Careful readers will note that, in the previous section, the JuiceBot
company's work was perfectly serialized:
@enumerate
@item Jim did some work
@item Abe synced with Jim
@item Abe did some work
@item Abe synced with Jim
@item Beth synced with Jim
@item Beth did some work
@item Beth synced with Jim
@end enumerate
The result of this ordering is that Jim's work entirely preceeded
Abe's work, which entirely preceeded Beth's work. Moreover, each
worker was fully informed of the ``up-stream'' worker's actions, and
produced purely derivative, ``down-stream'' work:
@enumerate
@item Jim made revision 2e24d...
@item Abe changed revision 2e24d... into revision 70dec...
@item Beth derived revision 70dec... into revision 80ef9...
@end enumerate
This is a simple, but sadly unrealistic, ordering of events. In real
companies or work groups, people often work in parallel,
@emph{diverging} from commonly known revisions and @emph{merging}
their work together, sometime after each unit of work is complete.
Monotone supports this diverge/merge style of operation naturally; any
time two revisions diverge from a common parent revision, we say that
the revision graph has a @dfn{fork} in it. Forks can happen at any
time, and require no coordination between workers. In fact any
interleaving of the previous events would work equally well; with one
exception: if forks were produced, someone would eventually have to
run the @command{merge} command, and possibly resolve any conflicts
in the fork.
To illustrate this, we return to our workers Beth and Abe. Suppose Jim
sends out an email saying that the current polling juice dispensers
use too much CPU time, and must be rewritten to use the JuiceBot's
interrupt system. Beth wakes up first and begins working immediately,
basing her work off the revision 80ef9... which is currently in her
working copy:
@smallexample
@group
$ vi src/banana.c
@i{<Beth changes her banana-juice dispenser to use interrupts>}
@end group
@end smallexample
Beth finishes and examines her changes:
@smallexample
@group
$ monotone diff
#
# patch "src/banana.c"
# from [7381d6b3adfddaf16dc0fdb05e0f2d1873e3132a]
# to [5e6622cf5c8805bcbd50921ce7db86dad40f2ec6]
#
--- src/banana.c
+++ src/banana.c
@@ -1,10 +1,15 @@
#include "jb.h"
+static void
+shut_off_banana()
+@{
+ spoutctl(BANANA_SPOUT, SET_INTR, 0);
+ spoutctl(BANANA_SPOUT, FLOW_JUICE, 0);
+@}
+
void
-dispense_banana_juice()
+dispense_banana_juice()
@{
+ spoutctl(BANANA_SPOUT, SET_INTR, &shut_off_banana);
spoutctl(BANANA_SPOUT, FLOW_JUICE, 1);
- while (spoutctl(BANANA_SPOUT, POLL_JUICE, 1) == 0)
- usleep (1000);
- spoutctl(BANANA_SPOUT, FLOW_JUICE, 0);
@}
@end group
@end smallexample
She commits her work:
@smallexample
@group
$ monotone commit --message="interrupt implementation of src/banana.c"
monotone: beginning commit on branch 'jp.co.juicebot.jb7'
monotone: committed revision 8b41b5399a564494993063287a737d26ede3dee4
@end group
@end smallexample
And she syncs with Jim:
@smallexample
@group
$ monotone sync jim-laptop.juicebot.co.jp jp.co.juicebot.jb7
@end group
@end smallexample
Unfortunately, before Beth managed to sync with Jim, Abe had woken up
and implemented a similar interrupt-based apple juice dispenser, but
his working copy is 70dec..., which is still ``upstream'' of
Beth's.
@smallexample
@group
$ vi apple.c
@i{<Abe changes his apple-juice dispenser to use interrupts>}
@end group
@end smallexample
Thus when Abe commits, he unknowingly creates a fork:
@smallexample
@group
$ monotone commit --message="interrupt implementation of src/apple.c"
@end group
@end smallexample
Abe does not see the fork yet; Abe has not actually seen @emph{any} of
Beth's work yet, because he has not synchronized with Jim. Since
he has new work to contribute, however, he now syncs:
@smallexample
@group
$ monotone sync jim-laptop.juicebot.co.jp jp.co.juicebot.jb7
@end group
@end smallexample
Now Jim and Abe will be aware of the fork. Jim sees it when he sits
down at his desk and asks monotone for the current set of heads of
the branch:
@smallexample
@group
$ monotone heads
monotone: branch 'jp.co.juicebot.jb7' is currently unmerged:
39969614e5a14316c7ffefc588771f491c709152 abe@@juicebot.co.jp 2004-10-26T02:53:16
8b41b5399a564494993063287a737d26ede3dee4 beth@@juicebot.co.jp 2004-10-26T02:53:15
@end group
@end smallexample
Clearly there are two heads to the branch: it contains an un-merged
fork. Beth will not yet know about the fork, but in this case it
doesn't matter: anyone can merge the fork, and since there are no
conflicts Jim does so himself:
@smallexample
@group
$ monotone merge
monotone: merging with revision 1 / 2
monotone: [source] 39969614e5a14316c7ffefc588771f491c709152
monotone: [source] 8b41b5399a564494993063287a737d26ede3dee4
monotone: common ancestor 70decb4b31a8227a629c0e364495286c5c75f979 found
monotone: trying 3-way merge
monotone: [merged] da499b9d9465a0e003a4c6b2909102ef98bf4e6d
monotone: your working copies have not been updated
@end group
@end smallexample
The output of this command shows Jim that two heads were found,
combined via a 3-way merge with their ancestor, and saved to a new
revision. This happened automatically, because the changes between the
common ancestor and heads did not conflict. If there had been a
conflict, monotone would have invoked an external merging tool to help
resolve it.
After merging, the branch has a single head again, and Jim updates
his working copy.
@smallexample
@group
$ monotone update
monotone: selected update target da499b9d9465a0e003a4c6b2909102ef98bf4e6d
monotone: updating src/apple.c to f088e24beb43ab1468d7243e36ce214a559bdc96
monotone: updating src/banana.c to 5e6622cf5c8805bcbd50921ce7db86dad40f2ec6
monotone: updated to base revision da499b9d9465a0e003a4c6b2909102ef98bf4e6d
@end group
@end smallexample
The update command selected an update target --- in this case the newly merged
head --- and performed an in-memory merge between Jim's working copy
and the chosen target. The result was then written to Jim's working copy. If
Jim's working copy had any uncommitted changes in it, they would have been
merged with the update in exactly the same manner as the merge of multiple
committed heads.
Monotone makes very little distinction between a ``pre-commit'' merge
(an update) and a ``post-commit'' merge. Both sorts of merge use the
exact same algorithm. The major difference concerns the recoverability
of the pre-merge state: if you commit your work first, and merge after
committing, then even if the merge somehow fails (due to difficulty in a
manual merge step, for instance), your committed state is still safe.
If you update, on the other hand, you are requesting that monotone
directly modify your working copy, and while monotone will try hard not
to break anything, this process is inherently more open to error. It is
therefore recommended that you commit your work @emph{first}, before
merging.
If you have previously used another version control system, this may at
first seem surprising; there are some systems where you are
@emph{required} to update, and risk the above problems, before you can
commit. Monotone, however, was designed with this problem in mind, and
thus @emph{always} allows you to commit before merging. A good rule of
thumb is to only use @command{update} in working copies with no local
modifications, or when you actually want to work against a different
base revision (perhaps because finishing your change turns out to
require some fixes made in another revision, or because you discover
that you have accidentally started working against a revision that
contains unrelated bugs, and need to back out to a working revision for
testing).
@page
@node Branching and Merging
@section 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 @emph{not} integrate them
with other people's --- or at least not right away. One way to do this
would be to simply never run @command{monotone merge}; but it would
quickly become confusing to try and keep track of which changes were in
which revisions. This is where @emph{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
@code{jp.co.juicebot.jb7}, she will use branch
@code{jp.co.juicebot.jb7.muffins}. So, she makes the first few edits to
the new muffins code, and commits it on a new branch by simply passing
@option{--branch} to commit:
@smallexample
@group
$ monotone commit --branch=jp.co.juicebot.jb7.muffins --message='autobake framework'
monotone: beginning commit on branch 'jp.co.juicebot.jb7.muffins'
monotone: committed revision d33caefd61823ecbb605c39ffb84705dec449857
@end group
@end smallexample
That's all there is to it --- there is now a
@code{jp.co.juicebot.jb7.muffins} branch, with her initial checkin on
it. She can make further checkins from the same working copy, 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 @command{propagate}
command:
@smallexample
@group
$ monotone propagate jp.co.juicebot.jb7 jp.co.juicebot.jb7.muffins
monotone: propagating jp.co.juicebot.jb7 -> jp.co.juicebot.jb7.muffins
monotone: [source] da003f115752ac6e4750b89aaca9dbba178ac80c
monotone: [target] d0e5c93bb61e5fd25a0dadf41426f209b73f40af
monotone: common ancestor 853b8c7ac5689181d4b958504adfb5d07fd959ab found
@end group
@end smallexample
The @command{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 simple propagates the other way:
@smallexample
@group
$ monotone propagate jp.co.juicebot.jb7.muffins jp.co.juicebot.jb7
monotone: propagating jp.co.juicebot.jb7 -> jp.co.juicebot.jb7.muffins
monotone: [source] 4e48e2c9a3d2ca8a708cb0cc545700544efb5021
monotone: [target] bd29b2bfd07644ab370f50e0d68f26dcfd3bb4af
monotone: common ancestor 652b1035343281a0d2a5de79919f9a31a30c9028 found
@end group
@end smallexample
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.
@node Advanced Uses
@chapter Advanced Uses
This chapter covers slightly less common aspects of using
monotone. Some users of monotone will find these helpful, though
possibly not all. We assume that you have read through the taxonomy
and tutorial, and possibly spent some time playing with the program to
familiarize yourself with its operation.
@menu
* Selectors:: Selecting revisions by certificate.
* Restrictions:: Limit working copy changes to specified files.
* Scripting:: Running monotone from other programs.
* Inodeprints:: Trading off safety for speed in your working copy.
* Quality Assurance:: Integrating testing and review with development.
* Vars:: Simple per-database configuration information.
* Reserved Files:: File names with special meanings.
* Reserved Certs:: Certificate names with special meanings.
* Naming Conventions:: Choosing appropriate names for keys and branches.
* File Attributes:: Marking files as executable, or other attributes.
* Merging:: Merging with external tools, handling binary files.
* Migrating and Dumping:: Changing the underlying storage system.
* Importing from CVS:: Building a monotone database from a CVS repository.
@end menu
@page
@node Selectors
@section Selectors
Revisions can be specified on the monotone command line, precisely, by
entering the entire 40-character hexadecimal @sc{sha1} code. This can
be cumbersome, so monotone also allows a more general syntax called
``selectors'' which is less precise but more ``human friendly''. Any
command which expects a precise revision ID can also accept a selector
in its place; in fact a revision ID is just a special type of selector
which is very precise.
@heading Simple examples
Some selector examples are helpful in clarifying the idea:
@table @code
@item a432
Revision IDs beginning with the string @code{a432}
@item graydon@@pobox.com/2004-04
Revisions written by @code{graydon@@pobox.com} in April 2004.
@item "jrh@@example.org/2 weeks ago"
Revisions written by @code{jrh@@example.org} 2 weeks ago.
@item graydon/net.venge.monotone.win32/yesterday
Revisions in the @code{net.venge.monotone.win32} branch, written by
@code{graydon}, yesterday.
@end table
A moment's examination reveals that these specifications are ``fuzzy''
and indeed may return multiple values, or may be ambiguous. When
ambiguity arises, monotone will inform you that more detail is
required, and list various possibilities. The precise specification
of selectors follows.
@heading Selectors in detail
A selector is a combination of a selector type, which is a single
ASCII character, followed by a @code{:} character and a selector
string. All selectors strings except for selector type @code{c}
are just values. The value is matched against identifiers or certs,
depending on its type, in an attempt to match a single revision.
Selectors are matched as prefixes. The current set of selection
types are:
@table @asis
@item Generic cert selector
Uses selector type @code{c}. The selector string has the syntax
@var{name} or @var{name}@code{=}@var{value}. The former syntax will
select any revision that has a cert with that name, regardless of
value; the latter will match any revision that has a cert with that
name and value. Values to match for can have wildcards.
@item Author selection
Uses selector type @code{a}. For example, @code{a:graydon} matches
@code{author} certs where the cert value begins with @code{graydon}.
@item Branch selection
Uses selector type @code{b}. For example, @code{b:net.venge} matches
@code{branch} certs where the cert value begins with @code{net.venge}.
@item Date selection
Uses selector type @code{d}. For example, @code{d:2004-04} matches
@code{date} certs where the cert value begins with
@code{2004-04}. This selector also accepts expanded date syntax (see below).
@item "Earlier or equal than" selection
Uses selector type @code{e}. For example, @code{e:2004-04-25} matches
@code{date} certs where the cert value is less or equal than
@code{2004-04-25T00:00:00}. If the time component is unspecified,
monotone will assume 00:00:00. This selector also accepts expanded date
syntax (see below)
@item "Later than" selection
Uses selector type @code{l}. For example, @code{l:2004-04-25} matches
@code{date} certs where the cert value is strictly less than
@code{2004-04-25T00:00:00}. If the time component is unspecified,
monotone will assume 00:00:00. This selector also accepts expanded date
syntax (see below)
@item Identifier selection
Uses selector type @code{i}. For example, @code{i:0f3a} matches
revision IDs which begin with @code{0f3a}.
@item Tag selection
Uses selector type @code{t}. For example, @code{t:monotone-0.11}
matches @code{tag} certs where the cert value begins with
@code{monotone-0.11}.
@end table
Further selector types may be added in the future.
@heading Composite selectors
Selectors may be combined with the @code{/} character. The combination
acts as database intersection (or logical @code{and}). For example,
the selector @code{a:graydon/d:2004-04} can be used to select a
revision which has an @code{author} cert beginning with @code{graydon}
@emph{as well as} a @code{date} cert beginning with @code{2004-04}.
@heading Selector expansion
Before selectors are passed to the database, they are expanded using a
lua hook: @code{expand_selector}. The default definition of this hook
attempts to guess a number of common forms for selection, allowing you
to omit selector types in many cases. For example, the hook guesses
that the typeless selector @code{jrh@@example.org} is an author
selector, due to its syntactic form, so modifies it to read
@code{a:jrh@@example.org}. This hook will generally assign a selector
type to values which ``look like'' partial hex strings, email
addresses, branch names, or date specifications. For the complete
source code of the hook, see @ref{Hook Reference}.
@heading Expanding dates
All date-related selectors (@code{d}, @code{e}, @code{l}) support an
english-like syntax similar to CVS. This syntax is expanded to the
numeric format by a lua hook: @code{expand_date}.
The allowed date formats are:
@table @asis
@item now
Expands to the current date and time.
@item today
Expands to today's date. @code{e} and @code{l} selectors assume time 00:00:00
@item yesterday
Expands to yesterday's date. @code{e} and @code{l} selectors assume
time 00:00:00
@item <number> @{minute|hour@} <ago>
Expands to today date and time, minus the specified @code{number} of
minutes|hours.
@item <number> @{day|week|month|year@} <ago>
Expands to today date, minus the specified @code{number} of
days|weeks|months|years. @code{e} and @code{l} selectors assume time
00:00:00
@item <year>-<month>[-day[Thour:minute:second]]
Expands to the supplied year/month. The day and time component are
optional. If missing, @code{e} and @code{l} selectors assume the first
day of month and time 00:00:00.
The time component, if supplied, must be complete to the second.
@end table
For the complete source code of the hook, see @ref{Hook Reference}.
@heading Typeless selection
If, after expansion, a selector still has no type, it is matched as a
special ``unknown'' selector type, which will match either a tag, an
author, or a branch. This costs slightly more database access, but
often permits simple selection using an author's login name and a
date. For example, the selector
@code{graydon/net.venge.monotone.win32/yesterday} would pass through
the selector @code{graydon} as an unknown selector; so long as there
are no branches or tags beginning with the string @code{graydon} this
is just as effective as specifying @code{a:graydon}.
@page
@node Restrictions
@section Restrictions
Several monotone commands accept optional @var{pathname...} arguments in
order to establish a ``restriction''. Restrictions are used to limit
the files and directories these commands examine for changes when
comparing the working copy to the revision it is based on. Restricting a
command to a specified set of files or directories simply ignores
changes to files or directories not included by the restriction.
The following commands all support restrictions using optional
@var{pathname...} arguments:
@itemize
@item @command{status}
@item @command{diff}
@item @command{revert}
@item @command{commit}
@item @command{list known}
@item @command{list unknown}
@item @command{list ignored}
@item @command{list missing}
@end itemize
Including either the old or new name of a renamed file or directory will
cause both names to be included in a restriction. If in doubt, the
@command{status} command can be used to ``test'' a set of pathnames to
ensure that the expected files are included or excluded by a
restriction.
Commands which support restrictions also support the
@option{--depth=@var{n} } option, where @var{n} specifies the maximum
number of directories to descend. For example, @var{n}=0 disables
recursion, @var{n}=1 means descend at most one directory, and so on.
One variant of the @command{diff} command takes two @option{--revision}
options and does not operate on a working copy, but instead compares two
arbitrary database revisions. In this form the @command{diff} command
does not currently support a restriction or optional @var{pathname...}
arguments. This may be changed in the future.
The @command{update} command does not allow for updates to a
restricted set of files, which may be slightly different than other
version control systems. Partial updates don't really make sense in
monotone, as they would leave the working copy based on a revision that
doesn't exist in the database, starting an entirely new line of
development.
@heading Subdirectory restrictions
The restrictions facility also allows commands to operate from within a
subdirectory of the working copy. By default, the @i{entire working
copy} is always examined for changes. However, specifying an explicit
"." pathname to a command will restrict it to the current subdirectory.
Note that this is quite different from other version control systems and
may seem somewhat surprising.
The expectation is that requiring a single "." to restrict to the
current subdirectory should be simple to use. While the alternative,
defaulting to restricting to the current subdirectory, would require a
somewhat complicated ../../.. sequence to remove the restriction and
operate on the whole tree.
This default was chosen because monotone versions whole project trees
and generally expects to commit all changes in the working copy as a
single atomic unit. Other version control systems often version
individual files or directories and may not support atomic commits at
all.
When working from within a subdirectory of the working copy all
paths specified to monotone commands must be relative to the current
subdirectory.
@heading Finding a working copy
Monotone only stores a single @file{MT} directory at the root of a
working copy. Because of this, a search is done to find the @file{MT}
directory in case a command is executed from within a subdirectory of a
working copy. Before a command is executed, the search for a working
copy directory is done by traversing parent directories until an
@file{MT} directory is found or the filesystem root is reached. Upon
finding an @file{MT} directory, the @file{MT/options} file is read for
default options. The @option{--root} option may be used to stop the
search early, before reaching the root of the physical filesystem.
Many monotone commands don't require a working copy and will simply
proceed with no default options if no @file{MT} directory is found.
However, some monotone commands do require a working copy and will fail
if no @file{MT} directory can be found.
The @command{checkout} and @command{setup} commands create a @i{new
working copy} and initialize a new @file{MT/options} file based on their
current option settings.
@page
@node Scripting
@section Scripting
People often want to write programs that call monotone --- for example,
to create a graphical interface to monotone's functionality, or to
automate some task. For most programs, if you want to do this sort of
thing, you just call the command line interface, and do some sort of
parsing of the output. Monotone's output, however, is designed for
humans: it's localized, it tries to prompt the user with helpful
information depending on their request, if it detects that something
unusual is happening it may give different output in an attempt to make
this clear to the user, and so on. As a result, it is not particularly
suitable for programs to parse.
Rather than trying to design output to work for both humans and
computers, and serving neither audience well, we elected to create a
separate interface to make programmatically extracting information from
monotone easier. The command line interface has a command
@code{automate}; this command has subcommands that print various sorts
of information on standard output, in simple, consistent, and easily
parseable form.
For details of this interface, see @ref{Automation}.
@page
@node Inodeprints
@section Inodeprints
Fairly often, in order to accomplish its job, monotone has to look at
your working copy and figure out what has been changed in it since your
last commit. Commands that do this include @command{status},
@command{diff}, @command{update}, @command{commit}, and others. There
are two different techniques it can use to do this. The default, which
is sufficient for most projects, is to simply read every file in the
working copy, compute their @sc{sha1} hash, and compare them to the
hashes monotone has stored. This is very safe and reliable, and turns
out to be fast enough for most projects. However, on very large
projects, ones whose source trees are many megabytes in size, it can
become unacceptably slow.
The other technique, known as @emph{inodeprints}, is designed for this
situation. When running in inodeprints mode, monotone does not read the
whole working copy; rather, it keeps a cache of interesting information
about each file (its size, its last modification time, and so on), and
skips reading any file for which these values have not changed. This is
inherently somewhat less safe, and, as mentioned above, unnecessary for
most projects, so it is disabled by default.
If you do determine that it is necessary to use inodeprints with your
project, it is simple to enable them. Simply run @command{monotone
refresh_inodeprints}; this will enable inodeprints mode and generate an
initial cache. If you ever wish to turn them off again, simply delete
the file @file{MT/inodeprints}. You can at any time delete or truncate
the @file{MT/inodeprints} file; monotone uses it only as a cache and
will continue to operate correctly.
Normally, instead of enabling this up on a per-working-copy basis, you
will want to simply define the @code{use_inodeprints} hook to return
@code{true}; this will automatically enable inodeprints mode in any new
working copies you create. See @ref{Hook Reference} for details.
@page
@node Quality Assurance
@section Quality Assurance
Monotone was constructed to serve both as a version control tool and
as a quality assurance tool. The quality assurance features permit
users to ignore, or ``filter out'', versions which do not meet their
criteria for quality. This section describes the way monotone
represents and reasons about quality information.
Monotone often views the collection of revisions as a directed graph,
in which revisions are the nodes and changes between revisions are the
edges. We call this the @dfn{revision graph}. The revision graph has a
number of important subgraphs, many of which overlap. For example,
each branch is a subgraph of the revision graph, containing only the
nodes carrying a particular @code{branch} cert.
Many of monotone's operations involve searching the revision graph for
the ancestors or descendents of a particular revision, or extracting
the ``heads'' of a subgraph, which is the subgraph's set of nodes with
no descendents. For example, when you run the @code{update} command,
monotone searches the subgraph consisting of descendents of the base
revision of the current working copy, trying to locate a unique head to
update the base revision to.
Monotone's quality assurance mechanisms are mostly based on
restricting the subgraph each command operates on. There are two
methods used to restrict the subgraph:
@itemize
@item
By restricting the set of trusted @code{branch} certificates, you
can require that specific code reviewers have approved of each edge in
the subgraph you focus on.
@item
By restricting the set of trusted @code{testresult} certificates, you
can require that the @emph{endpoints} of an update operation have a
certificate asserting that the revision in question passed a certain
test, or testsuite.
@end itemize
The evaluation of trust is done on a cert-by-cert basis by calling a
set of lua hooks: @code{get_revision_cert_trust},
@code{get_manifest_cert_trust} and @code{get_file_cert_trust}. These
hooks are only called when a cert has at least one good signature from
a known key, and are passed @emph{all} the keys which have signed the
cert, as well as the cert's ID, name and value. The hook can then
evaluate the set of signers, as a group, and decide whether to grant
or deny trust to the assertion made by the cert.
The evaluation of testresults is controlled by the
@code{accept_testresult_change} hook. This hook is called when
selecting update candidates, and is passed a pair of tables describing
the @code{testresult} certs present on the source and proposed
destination of an update. Only if the change in test results are
deemed ``acceptable'' does monotone actually select an update target
to merge into your working copy.
For details on these hooks, see the @ref{Hook Reference}.
@page
@node Vars
@section Vars
Every monotone database has a set of @emph{vars} associated with it.
Vars are simple configuration variables that monotone refers to in some
circumstances; they are used for configuration that monotone needs to be
able to modify itself, and that should be per-database (rather than
per-user or per-working copy, both of which are supported by
@file{monotonerc} scripts). Vars are local to a database, and never
transferred by netsync.
A var is a @emph{name} = @emph{value} pairing inside a @emph{domain}.
Domains define what the vars inside it are used for; for instance, one
domain might contain database-global settings, and particular vars
inside it would define things like that database's default netsync
server. Another domain might contain key fingerprints for servers that
monotone has interacted with in the past, to detect man-in-the-middle
attacks; the vars inside this domain would map server names to their
fingerprints.
You can set vars with the @command{set} command, delete them with the
@command{unset} command, and see them with the @command{ls vars}
command. See the documentation for these specific commands for more
details.
@heading Existing vars
There are several pre-defined domains that monotone knows about:
@table @code
@item database
Contains database-global configuration information. Defined names are:
@table @code
@item default-server
The default server for netsync operations to use. Automatically set
by first use of netsync.
@item default-pattern
The default regex pattern for netsync operations to use. Automatically
set by first use of netsync.
@end table
@item known-servers
Contains key hashes for servers that we have netsynced with in the
past. Analogous to @command{ssh}'s @file{known_hosts} file, this is
needed to detect man-in-the-middle attacks. Automatically set the first
time you netsync with any given server. If that server's key later
changes, monotone will notice, and refuse to connect until you have run
@command{monotone unset known-servers @var{server-name}}.
@end table
@page
@node Reserved Files
@section Reserved Files
A monotone working copy consists of control files and non-control
files. Each type of file can be versioned or non-versioned. These
classifications lead to four groups of files:
@itemize
@item versioned control files
@item non-versioned control files
@item versioned non-control files
@item non-versioned non-control files
@end itemize
Control files contain special content formatted for use by
monotone. Versioned files are recorded in a monotone database and have
their state tracked as they are modified.
If a control file is versioned, it is considered @emph{part of} the
state of the working copy, and will be recorded as a manifest
entry. If a control file is not versioned, it is used to @emph{manage}
the state of the working copy, but it not considered an intrinsic part
of it.
Most files you manage with monotone will be versioned non-control
files. For example, if you keep source code or documents in a monotone
database, they are versioned non-control files. Non-versioned,
non-control files in your working copy are generally temporary or junk
files, such as backups made by editors or object files made by
compilers. Such files are ignored by monotone.
@heading Identifying control files
Control files are identified by their names. Non-control files can
have any name @emph{except} the names reserved for control files. The
names of control files follow a regular pattern:
@table @asis
@item Versioned control files
Any file name beginning with @file{.mt-}
@item Non-versioned control files
Any file in the directory @file{MT/}
@end table
@heading Existing control files
The following control files are currently used. More control files may be added
in the future, but they will follow the patterns given above.
@table @file
@item .mt-attrs
Contains versioned attributes of files, associated with the files'
pathnames.
@item MT/revision
Contains the identity of the ``base'' revision of the working copy.
Each working copy has a base revision. When the working copy is
committed, the base revision is considered to be the ancestor of the
committed revision.
@item MT/options
Contains ``sticky'' command-line options such as @option{--db} or
@option{--branch}, such that you do not need to enter them repeatedly
after checking out a particular working copy.
@item MT/work
Contains a list of additions, deletions, and renames which have occurred
in the current working copy, relative to the base version.
@item MT/log
Contains log messages to append to the ``changelog'' cert upon
commit. The user may add content to this file while they work. Upon a
successful commit monotone will empty the file making it ready for the
next edit/commit cycle.
@item MT/inodeprints
If this file exists, monotone considers the directory to be in
@ref{Inodeprints} mode, and uses this file to cache the inodeprints.
@item MT/debug
If monotone detects a bug in itself or crashes, then before exiting it
dumps a log of its recent activity to this file, to aid in debugging.
@end table
@page
@node Reserved Certs
@section Reserved Certs
Every certificate has a name. Some names have meaning which is built
in to monotone, others may be used for customization by a particular
user, site, or community. If you wish to define custom certificates,
you should prefix such certificate names with @code{x-}. For example,
if you want to make a certificate describing the existence of security
vulnerabilities in a revision, you might wish to create a certificate
called @code{x-vulnerability}. Monotone reserves all names which do
not begin with @code{x-} for possible internal use. If an @code{x-}
certificate becomes widely used, monotone will likely adopt it as a
reserved cert name and standardize its semantics.
Most reserved certificate names have no meaning yet; some do. Usually
monotone is also responsible for @emph{generating} these certificates,
so you should generally have no cause to make them yourself. They are
described here to help you understand monotone's operation.
The pre-defined, reserved certificate names are:
@table @code
@item author
This cert's value is the name of a person who committed the revision
the cert is attached to. The cert is generated when you commit a
revision. It is displayed by the @code{log} command.
@item branch
This cert's value is the name of a branch. A @code{branch} cert
associates a revision with a branch. The revision is said to be ``in
the branch'' named by the cert. The cert is generated when you commit
a revision, either directly with the @code{commit} command or
indirectly with the @code{merge} or @code{propagate} commands. The
@code{branch} certs are read and directly interpreted by @emph{many}
monotone commands, and play a fundamental role in organizing work in
any monotone database.
@item changelog
This cert's value is the change log message you provide when you
commit a revision. It is displayed by the @code{log} command.
@item comment
This cert's value is an additional comment, usually provided after
committing, about a revision. Certs with the name @code{comment} can
be applied to files as well, and will be shown by the @code{log}
command.
@item date
This cert's value is an ISO date string indicating the time at which a
revision was committed. It is displayed by the @code{log} command, and
may be used as an additional heuristic or selection criterion in other
commands in the future.
@item tag
This cert's value is a symbolic name given to a revision, which may be
used in the future as a way of selecting versions for @code{checkout}.
@item testresult
This cert's value is interpreted as a boolean string, either @code{0}
or @code{1}. It is generated by the @code{testresult} command and
represents the results of running a particular test on the underlying
revision. Typically you will make a separate signing key for each test
you intend to run on revisions. This cert influences the
@command{update} algorithm.
@end table
@page
@node Naming Conventions
@section Naming Conventions
Some names in monotone are private to your work, such as
filenames. Other names are potentially visible outside your project,
such as @sc{rsa} key identifiers or branch names. It is possible that if
you choose such names carelessly, you will choose a name which someone
else in the world is using, and subsequently you may cause confusion
when your work and theirs is received simultaneously by some third
party.
We therefore recommend two naming conventions:
@itemize
@item
For @sc{rsa} keys, use the name of an active email address you
own. This will minimize conflicts, and also serves as a mnemonic to
associate your personal @emph{identity} with signatures made with your
key. For example, monotone's primary author uses the key identifier
@code{graydon@@pobox.com}.
@item
For branch names, select any name you like but prefix it with the
``inverted domain name'' of a DNS domain you control or are otherwise
authorized to use. This behavior mimics the package naming convention
in the java programming language. For example, monotone itself is
developed within the @code{net.venge.monotone} branch, because the
author owns the DNS domain @code{venge.net}.
@end itemize
@page
@node File Attributes
@section File Attributes
Monotone contains a mechanism for storing @dfn{persistent file
attributes}. These differ from file certificates in an important way:
attributes are associated with a path name in your working copy,
rather than a particular version of a file. Otherwise they are
similar: a file attribute associates a simple name/value pair with a
file in your working copy.
The attribute mechanism is motivated by the fact that some people like
to store executable programs in version control systems, and would like
the programs to remain executable when they check out a working copy.
For example, the @code{configure} shell script commonly shipped with
many programs should be executable.
Similarly, some people would like to store devices, symbolic links,
read-only files, and all manner of extra attributes of a file, not
directly related to a file's data content.
Rather than try to extend the manifest file format to accommodate
attributes, monotone requires that you place your attributes in a
specially named file in the root of your working copy. The file is
called @file{.mt-attrs}, and it has a simple stanza-based format, for
example:
@smallexample
@group
file "analyze_coverage"
execute "true"
file "autogen.sh"
execute "true"
otherattr "bob"
@end group
@end smallexample
Each stanze of the @file{.mt-attrs} file assigns attributes to a file in
your working copy. The first line of each stanza is @code{file}
followed by the quoted name of the file you want to assign attributes
to. Each subsequent line is the name of an attribute, followed by a
quoted value for that attribute. Stanzas are separated by blank lines.
As a convenience, you can use the @code{monotone attr} command to set
and view the values of these attributes; see @ref{Working Copy}.
You can tell monotone to automatically take actions based on these
attributes by defining hooks; see the @code{attr_functions} entry in
@ref{Hook Reference}.
Every time your working copy is written to, monotone will look for the
@file{.mt-attrs} file, and if it exists, run the corresponding hooks
registered for each attribute found in the file. This way, you can
extend the vocabulary of attributes understood by monotone simply by
writing new hooks.
Aside from its special interpretation, the @file{.mt-attrs} file is a
normal text file. If you want other people to see your attributes, you
should @code{add} and @code{commit} the @file{.mt-attrs} file in your
working copy. If you make changes to it which conflict with changes
other people make, you will have to resolve those conflicts, as plain
text, just as with any other text file in your working copy.
@page
@node Merging
@section Merging
Monotone has two merging modes, controlled by the @code{manual_merge}
attribute.
By default all files are merged in automatic mode, unless the
@code{manual_merge} attribute for that file is present and
@code{true}.
In automatic mode files are merged without user intervention, using
monotone internal three-way merging algorithm.
Only if there are conflicts or an ancestor is not available monotone
switches to manual mode, essentially escalating the merging to the user.
When working in manual mode, monotone invokes the merge2 (for two-way
merging) or merge3 (three-way) hooks to start an user defined external
merge tool.
If the tool terminates without writing the merged file, monotone aborts the
merging, reverting any changes made.
By redefining the aforementioned hooks the user can not only choose a
preferred merge tool, but even select different programs for different
file types. For example, gimp for .png files, OpenOffice.org for
.doc, and so on.
Starting with monotone 0.20, the @code{manual_merge} attribute is
automatically set at add time for all ``binary'' files, i.e. all files
for wich the @code{binary_file} hook returns true.
Currently, this means all files with extension gif, jpeg, png, bz2, gz
and zip, plus files containing at least one of the following
bytes:
@smallexample
@group
0x00 thru 0x06
0x0E thru 0x1a
0x1c thru 0x1f
@end group
@end smallexample
The attribute could also be manually forced or removed using the
appropriate monotone commands.
Remember that monotone switches to manual merging even if only one of
the files to be merged has the @code{manual_merge} attribute set.
@page
@node Migrating and Dumping
@section Migrating and Dumping
While the state of your database is logically captured in terms of a
packet stream, it is sometimes necessary or desirable (especially
while monotone is still in active development) to modify the SQL table
layout or storage parameters of your version database, or to make
backup copies of your database in plain text. These issues are not
properly addressed by generating packet streams: instead, you must use
@dfn{migration} or @dfn{dumping} commands.
The @command{monotone db migrate} command is used to alter the SQL
schema of a database. The schema of a monotone database is identified
by a special hash of its generating SQL, which is stored in the
database's auxiliary tables. Each version of monotone knows which
schema version it is able to work with, and it will refuse to operate
on databases with different schemas. When you run the
@command{migrate} command, monotone looks in an internal list of SQL
logic which can be used to perform in-place upgrades. It applies
entries from this list, in order, attempting to change the database it
@emph{has} into the database it @emph{wants}. Each step of this
migration is checked to ensure no errors occurred and the resulting
schema hashes to the intended value. The migration is attempted inside
a transaction, so if it fails --- for example if the result of
migration hashes to an unexpected value --- the migration is aborted.
If more drastic changes to the underlying database are made, such as
changing the page size of sqlite, or if you simply want to keep a
plain text version of your database on hand, the @command{monotone db
dump} command can produce a plain ASCII SQL statement which generates
the state of your database. This dump can later be reloaded using the
@command{monotone db load} command.
Note that when reloading a dumped database, the schema of the dumped
database is @emph{included} in the dump, so you should not try to
@command{init} your database before a @command{load}.
@page
@node Importing from CVS
@section Importing from CVS
Monotone is capable of reading CVS files directly and importing them
into a database. This feature is still somewhat immature, but
moderately large ``real world'' CVS trees on the order of 1GB have
successfully been imported.
Note however that the machine requirements for CVS trees of this size
are not trivial: it can take several hours on a modern system to
reconstruct the history of such a tree and calculate the millions of
cryptographic certificates involved. We recommend experimenting with
smaller trees first, to get a feel for the import process.
We will assume certain values for this example which will differ in your case:
@itemize
@item
Your domain name, @code{example.net} in this example.
@item
Your key name, @code{import@@example.net} in this example.
@item
Your project name, @code{wobbler} in this example.
@item
Your database name, @file{test.db} in this example.
@item
Your CVS repository path, @file{/usr/local/cvsroot} in this example.
@item
The CVS module name for your project, @code{wobbler} in this example.
@end itemize
Accounting for these differences at your site, the following is an
example procedure for importing a CVS repository ``from scratch'', and
checking the resulting head version of the import out into a working
copy:
@smallexample
@group
$ monotone --db=test.db db init
$ monotone --db=test.db genkey import@@example.net
$ monotone --db=test.db --branch=net.example.wobbler cvs_import /usr/local/cvsroot/wobbler
$ monotone --db=test.db --branch=net.example.wobbler checkout wobber-checkout
@end group
@end smallexample
@page
@node CVS Phrasebook
@chapter CVS Phrasebook
This chapter translates common CVS commands into monotone commands. It
is an easy alternative to reading through the complete command
reference.
@heading Checking Out a Tree
@multitable @columnfractions .4 .4
@item
@smallexample
@group
$ CVSROOT=:pserver:cvs.foo.com/wobbler
$ cvs -d $CVSROOT checkout -r 1.2
@end group
@end smallexample
@tab
@smallexample
@group
$ monotone pull www.foo.com com.foo.wobbler
$ monotone checkout --revision=fe37 wobbler
@end group
@end smallexample
@end multitable
The CVS command contacts a network server, retrieves a revision, and
stores it in your working copy. There are two cosmetic differences
with the monotone command: remote databases are specified by hostnames
and regexes, and revisions are denoted by @sc{sha1} values (or
selectors).
There is also one deep difference: pulling revisions into your
database is a separate step from checking out a single revision; after
you have pulled from a network server, your database will contain
@emph{several} revisions, possibly the entire history of a
project. Checking out is a separate step, after communication, which
only copies a particular revision out of your database and into a named
directory.
@heading Committing Changes
@multitable @columnfractions .4 .4
@item
@smallexample
@group
$ cvs commit -m "log message"
@end group
@end smallexample
@tab
@smallexample
@group
$ monotone commit --message="log message"
$ monotone push www.foo.com com.foo.wobbler
@end group
@end smallexample
@end multitable
As with other networking commands, the communication step with
monotone is explicit: committing changes only saves them to the local
database. A separate command, @command{push}, sends the changes to a
remote database.
@heading Incorporating New Changes
@multitable @columnfractions .4 .4
@item
@smallexample
@group
$ cvs update -d
@end group
@end smallexample
@tab
@smallexample
@group
$ monotone pull www.foo.com com.foo.wobbler
$ monotone merge
$ monotone update
@end group
@end smallexample
@end multitable
This command, like other networking commands, involves a separate
communication step with monotone. The extra command, @command{merge},
ensures that the branch your are working on has a unique head. You can
omit the @command{merge} step if you only want @command{update} to
examine descendents of your base revision, and ignore other heads on
your branch.
@heading Moving Working Copy to Another Revision
@multitable @columnfractions .4 .4
@item
@smallexample
@group
$ cvs update -r FOO_TAG -d
@end group
@end smallexample
@tab
@smallexample
@group
$ monotone update 830ac1a5f033825ab364f911608ec294fe37f7bc
$ monotone update t:FOO_TAG
@end group
@end smallexample
@end multitable
With a revision parameter, the @command{update} command operates
similarly in monotone and CVS. One difference is that a subsequent
@command{commit} will be based off the chosen revision in monotone,
while a @command{commit} in the CVS case is not possible without going
back to the branch head again. This version of @command{update} can
thus be very useful if, for example, you discover that the tree you are
working against is somehow broken --- you can @command{update} to an
older non-broken version, and continue to work normally while waiting
for the tree to be fixed.
@heading Viewing Differences
@multitable @columnfractions .4 .4
@item
@smallexample
@group
$ cvs diff
@end group
@end smallexample
@tab
@smallexample
@group
$ monotone diff
@end group
@end smallexample
@item
@smallexample
@group
$ cvs diff -r 1.2 -r 1.4
@end group
@end smallexample
@tab
@smallexample
@group
$ monotone diff -r 3e7db -r 278df
@end group
@end smallexample
@end multitable
Monotone's @command{diff} command is modeled on that of CVS, so the
main features are the same: @command{diff} alone prints the
differences between your working copy and its base revision, whereas
@command{diff} accompanied by two revision numbers prints the
difference between those two revisions. The major difference between
CVS and monotone here is that monotone's revision numbers are
@emph{revision IDs}, so the @command{diff} command prints the
difference between the two entire trees.
@heading Showing Working Copy Status
@multitable @columnfractions .4 .4
@item
@smallexample
@group
$ cvs status
@end group
@end smallexample
@tab
@smallexample
@group
$ monotone status
@end group
@end smallexample
@end multitable
This command operates similarly in monotone and CVS. The only major
difference is that monotone's @command{status} command always gives a
status of the whole tree, and outputs a more compact summary than CVS.
@heading Adding Directories and Files to Working Copy
@multitable @columnfractions .4 .4
@item
@smallexample
@group
$ cvs add dir
$ cvs add dir/subdir
$ cvs add dir/subdir/file.txt
@end group
@end smallexample
@tab
@smallexample
@group
$ monotone add dir/subdir/file.txt
@end group
@end smallexample
@end multitable
Monotone does not explicitly store directories, so adding a file only
involves adding the file's complete path, including any directories.
Directories are created as needed, and empty directories are ignored.
@heading Removing Directories and Files from Working Copy
@multitable @columnfractions .4 .4
@item
@smallexample
@group
$ rm file.txt
$ cvs remove file.txt
@end group
@end smallexample
@tab
@smallexample
@group
$ monotone drop file.txt
@end group
@end smallexample
@end multitable
Monotone does not require that you erase a file from the working copy
before you drop it. Dropping a file merely removes its entry in the
manifest of the current revision.
@heading Importing a New Project
@multitable @columnfractions .4 .4
@item
@smallexample
@group
$ cvs import wobbler vendor start
@end group
@end smallexample
@tab
@smallexample
@group
$ monotone --db=/path/to/database.db --branch=com.foo.wobbler setup .
$ monotone add .
$ monotone commit
@end group
@end smallexample
@end multitable
The @command{setup} command turns an ordinary directory into a
monotone working copy. After that, you can add your files and commit
them as usual.
@heading Initializing a Repository
@multitable @columnfractions .4 .4
@item
@smallexample
@group
$ cvs init -d /path/to/repository
@end group
@end smallexample
@tab
@smallexample
@group
$ monotone db init --db=/path/to/database.db
@end group
@end smallexample
@end multitable
Monotone's ``repository'' is a single-file database, which is created
and initialized by this command. This file is only ever used by you,
and does not need to be in any special location, or readable by other
users.
@node Command Reference
@chapter Command Reference
Monotone has a large number of commands. To help navigate through them
all, commands are grouped into logical categories.
@menu
* Tree:: Operations on tree states in your database
* Working Copy:: Operations on your working copy
* Network:: Communication with the network
* Informative:: Production of descriptive reports
* Key and Cert:: General operations on keys or certificates
* Certificate:: Special operations on certificates
* Packet I/O:: Production or consumption of packets
* Database:: Manipulation of your database as a whole
* Automation:: Running monotone from other programs
* RCS:: Importing legacy version control files
@end menu
@page
@node Tree
@section Tree
@ftable @command
@item monotone cat file @var{id}
@itemx monotone cat file @var{rid} @var{path}
@itemx monotone cat manifest
@itemx monotone cat manifest @var{id}
@itemx monotone cat revision
@itemx