\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

@dircategory Programming
@direntry
* monotone: (monotone).         Monotone version control system
@end direntry

@titlepage
@title Monotone
@subtitle A distributed version control system
@author Graydon Hoare and others

@ifnotinfo
@page
@vskip 0pt plus 1filll
@end ifnotinfo

This manual is for the ``monotone'' distributed version control system.
This edition documents version @value{VERSION}.

Copyright @copyright{} 2003, 2004 Graydon Hoare @*
Copyright @copyright{} 2004, 2005, 2006 Nathaniel Smith @*
Copyright @copyright{} 2005 Derek Scherger @*
Copyright @copyright{} 2005, 2006 Daniel Carosone @*
Copyright @copyright{} 2006 Jeronimo Pellegrini @*
Copyright @copyright{} 2006 Alex Queiroz @*
Copyright @copyright{} 2006 William Uther @*
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 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 similar --- but subtly or 
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
* Default hooks::       The standard hook definitions
* General Index::       Index of concepts and functions
@end menu

@ifnottex
Complete table of contents
@end ifnottex

@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 @code{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 @code{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, in a
structured but human-readable format used by several parts of monotone.
Each file entry of a manifest binds a specific name, as a full path from
the root of the workspace, to a specific file ID, as the hash of its
content.  In this way, the manifest collects together the snapshot of
the file names and contents you have at this point in time; other
snapshots with other manifests can use different names for the same
file, or different contents for the same name. 

Other entries in the manifest format name directories or store file
attrs, which we will cover later.

@ifinfo
@smallexample
@group

+------------------------------------------------------+
|                                                      |
|  format_version "1"                                  |
|                                                      |
|  dir ""                                              |
|                                                      |
|  dir "fs"                                            |
|                                                      |
|     file "fs/readdir.c"                              |
|  content [f2e5719b975e319c2371c98ed2c7231313fac9b5]  |
|                                                      |
|     file "fs/read_write.c"                           |
|  content [81f0c9a0df254bc8d51bb785713a9f6d0b020b22]  |
|                                                      |
|     file "fs/pipe.c"                                 |
|  content [943851e7da46014cb07473b90d55dd5145f24de0]  |
|                                                      |
|     file "fs/inode.c"                                |
|  content [8ddcfcc568f33db6205316d072825d2e5c123275]  |
|                                                      |
+------------------------------------------------------+

\_________________________  ___________________________/
                          \/
                      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
                                 ||
+--------------------------------||--------------------+
|                       . . .    ||                    |
|                                ||                    |
|     file "fs/readdir.c"        \/                    |
|  content [f2e5719b975e319c2371c98ed2c7231313fac9b5]  |
|                                                      |
|                       . . .
+------------------------------------------------------+

\_________________________  ___________________________/
                          \/
                         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
+-----------------------------------------------------------+
|                                                           |
|  format_version "1"                                       |
|                                                           |
|  new_manifest [83bc0a52da351cac950ac1c12d85be494fc21199]  |
|                                                           |
|  old_revision [75c9ffcab50c46e77e642751314b34a16fba36ff]  |
|                                                           |
|  add_file "include/foo.h"                                 |
|   content [8ca6a9862bdeddfdb4b12248c075fa9570f45f6d]      |
|                                                           |
|  patch "include/bar.h"                                    |
|   from [d624672a03e42d2172e56c4d54924af10ff8518d]         |
|     to [2f58cfc4791aa1695b76c31c9cd1139b3d79ee1b]         |
|                                                           |
+-----------------------------------------------------------+

\____________________________  _____________________________/
                             \/
                            SHA1
                             ||
                             \/
                        revision ID:
          1c83997e7ab40c0df47554c81b7d4e7ee691eb0d
@end group
@end smallexample
@end ifinfo
@ifnotinfo
@image{figures/revision}
@end ifnotinfo

The content of a revision includes one or more changesets.  These
changesets make reference to file IDs, to describe how the tree changed.
The revision also contains manifest IDs, as another way of describing
the tree ``before and after'' the changeset --- storing this information
in two forms allows monotone to detect any bugs or corrupted data before
they can enter your history.  Finally and 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 preceding 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
+-----------------------------------------------------------+
|                                                           |
|  format_version "1"                                       |
|                                                           |
|  new_manifest [dbd022dc423fd7f473e0fa79842cd9901cc2dd69] <-- manifest id
|                                                           |
|  old_revision: []                                         |
|                                                           |
|  ...                                                      |
|                                                           |
+-----------------------------------------------------------+

\____________________________________  _____________________/
                                     \/
                                    SHA1
                                     ||
+------------------------------------||---------------------+
|                                    ||                     |
|  format_version "1"                ||                     |
|                                    ||                     |
|  new_manifest [8a05c60422770bbf49a3||2c2367ddaa066538ca] <-- manifest id
|                                    \/                     |
|  old_revision [f45add3bfb21cb459d99b6a9c0111df75f6d9f85]  |
|                                                           |
|  ...                                                      |
|                                                           |
+-----------------------------------------------------------+

\____________________________________  _____________________/
                                     \/
                                    SHA1
                                     ||
+------------------------------------||---------------------+
|                                    ||                     |
|  format_version "1"                ||                     |
|                                    ||                     |
|  new_manifest [2027b4ab2febf98bd9a0||c000a69a8227cdaaf7] <-- manifest id
|                                    \/                     |
|  old_revision [1c83997e7ab40c0df47554c81b7d4e7ee691eb0d]  |
|                                                           |
|  ...                                                      |
|                                                           |
+-----------------------------------------------------------+

\____________________________  _____________________________/
                             \/
                            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.

@page
@node    Storage and workflow
@section Storage and workflow

Monotone moves information in and out of four different types of
storage:

@itemize
@item
a @i{keystore} in your home directory
@item
a @i{workspace} 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

The @dfn{keystore} is a directory @file{.monotone/keys} in your home directory
which contains copies of all your private keys. Each key is stored in a file
whose name is the key identifier with some characters converted to underscores.
When you use a key to sign a cert, the public half of that key is copied into
your local database along with the cert.

All information passes @emph{through} your local database, en route to
some other destination. For example, when changes are made in a
workspace, 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 workspace and a remote
database, or between workspaces. Your local database is always
the ``switching point'' for communication.

@ifinfo
@smallexample
@group
             pull, push, sync
       (untrusted network exchanges)
            _________/\________
           /                   \

    +-------------+      +------------+      +-------------+
    |             |      |            |      |             |
    |  remote db  | <==> |  local db  | <==> |  workspace  |
    |             |      |            |      |             |
    +-------------+      +------------+      +-------------+

                                \________  _______/
                                         \/
                                  commit, update
                            (certified local exchanges)
@end group
@end smallexample
@end ifinfo
@ifnotinfo
@image{figures/general-workflow}
@end ifnotinfo

A @dfn{workspace} 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{_MTN} exists in the root of
any workspace. Monotone keeps some special files in the @file{_MTN}
directory, in order to track changes you make to your workspace.  If
you ever want to know if a directory is a monotone workspace, just
look for this @file{_MTN} directory.

Aside from the special @file{_MTN} directory, a workspace is just a
normal tree of files. You can directly edit the files in a workspace
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 workspace, you must
tell monotone explicitly what you are doing, as these actions cannot
be deduced.

If you do not yet have a workspace, you can @dfn{check out} a
workspace 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 workspace to a database,
and @dfn{update} a workspace to receive changes that have arrived
in a database. Committing and updating take place purely between a
database and a workspace; the network is not involved.

@ifinfo
@smallexample
@group
   -----------------     check out,      workspace
  (                 )    or update      +----------------
   -----------------     ---------->    |
  |                 |                   |  src/func.c
  |      local      |   <----------     |  src/func.h
  |     database    |    add,           |  src/main.c
  |                 |    or commit      |  Makefile
  \_________________/                   |  _MTN/
                                        |
@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, workspaces, and other
databases. You can inspect and modify your databases without affecting
your workspaces, 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 workspace 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
workspace will not. In fact, you do not need a workspace at all
when exchanging work.

@item
When you @i{update} your workspace, some (but not all) of the
changes which your database received from the network are applied to
your workspace. 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 workspace.  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 workspace.

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 workspace. 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 workspace.

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 @command{mtn 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}.)

@page
@node    Tutorial
@chapter Tutorial

This chapter illustrates the basic uses of monotone by means of an
example, fictional software project.

@section Issues
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 workspace, 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::
* Basic Network Service::
* Synchronising Databases::
* Making Changes::
* Dealing with a Fork::
* Branching and Merging::
* Network Service Revisited::
@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 @command{mtn 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.mtn}, 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
$ mtn db init --db=~/jim.mtn
@end group
@end smallexample

Abe issues the command:

@smallexample
@group
$ mtn db init --db=~/abe.mtn
@end group
@end smallexample

And Beth issues the command:

@smallexample
@group
$ mtn db init --db=~/beth.mtn
@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
$ mtn genkey jim@@juicebot.co.jp
mtn: generating key-pair 'jim@@juicebot.co.jp'
enter passphrase for key ID [jim@@juicebot.co.jp] : @i{<Jim enters his passphrase>}
confirm passphrase for key ID [jim@@juicebot.co.jp]: @i{<Jim confirms his passphrase>}
mtn: storing key-pair 'jim@@juicebot.co.jp' in /home/jim/.monotone/keys
@end group
@end smallexample

Abe does something similar:

@smallexample
@group
$ mtn genkey abe@@juicebot.co.jp
mtn: generating key-pair 'abe@@juicebot.co.jp'
enter passphrase for key ID [abe@@juicebot.co.jp] : @i{<Abe enters his passphrase>}
confirm passphrase for key ID [abe@@juicebot.co.jp]: @i{<Abe confirms his passphrase>}
mtn: storing key-pair 'abe@@juicebot.co.jp' in /home/abe/.monotone/keys
@end group
@end smallexample

as does Beth:

@smallexample
@group
$ mtn genkey beth@@juicebot.co.jp
mtn: generating key-pair 'beth@@juicebot.co.jp'
enter passphrase for key ID [beth@@juicebot.co.jp] : @i{<Beth enters her passphrase>}
confirm passphrase for key ID [beth@@juicebot.co.jp]: @i{<Beth confirms her passphrase>}
mtn: storing key-pair 'beth@@juicebot.co.jp' in /home/beth/.monotone/keys
@end group
@end smallexample

Each programmer has now generated a key pair and placed it in their
keystore. Each can list the keys in their keystore, to ensure
the correct key was generated. For example, Jim might see this:

@smallexample
@group
$ mtn list keys

[public keys]
9e9e9ef1d515ad58bfaa5cf282b4a872d8fda00c jim@@juicebot.co.jp   (*)
(*) - only in /home/jim/.monotone/keys/


[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 keystore 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 his passphrase in order to perform security-sensitive
tasks.

Pretty soon Jim gets annoyed when he has to enter his passphrase every
time he invokes @code{mtn} (and, more importantly, it simplifies the
tutorial text to skip the passphrase prompts) so he decides to use
@emph{ssh-agent} to store his key. He does this by using the
@code{ssh_agent_export} command to export his key into a format that
ssh-agent can understand and adding it with @code{ssh-add}.

@smallexample
@group
$ mtn ssh_agent_export ~/.ssh/id_monotone
enter passphrase for key ID [user@@example.com]:
enter new passphrase for key ID [user@@example.com]:
confirm passphrase for key ID [user@@example.com]:
$ chmod 600 ~/.ssh/id_monotone
@end group
@end smallexample

From now on, Jim just needs to add his key to ssh-agent when he logs in
and he will not need to enter his passphrase every time he uses monotone.

@smallexample
@group
$ ssh-agent /bin/bash
$ ssh-add ~/.ssh/id_monotone
Enter passphrase for /home/user/.ssh/id_monotone:
Identity added: /home/user/.ssh/id_monotone (/home/user/.ssh/id_monotone)
$ mtn ci -m"Changed foo to bar"
$ mtn push
@end group
@end smallexample

The following procedure is deprecated and not suggested for general use
as it is very insecure.

Jim isn't very worried about security so he
decides to store his passphrase in his @file{monotonerc} file.  He does
this by writing a @emph{hook function} which returns the passphrase:

@smallexample
@group
$ mkdir ~/.monotone
$ cat >>~/.monotone/monotonerc
function get_passphrase(keypair_id)
  return "jimsekret"
end
^D
@end group
@end smallexample

Now whenever monotone needs his passphrase, it will call this function
instead of prompting him to type it.  Note that we are appending the new
hook to the (possibly existing) file.  We do this to avoid losing 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{workspace} --- a directory whose contents monotone will keep track
of.  Often, one works on projects that someone else has started, and
creates workspaces with the @command{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 @command{mtn setup}
command to create a new workspace.

This command creates the named directory (if it doesn't already exist),
and creates the @file{_MTN} directory within it.  The @file{_MTN} directory
is how monotone recognizes that a directory is a workspace, 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 @command{setup} command will be cached in a file called
@file{_MTN/options}, so you don't have to keep passing them to monotone
all the time.

He chooses @code{jp.co.juicebot.jb7} as a branch name. (See
@ref{Naming Conventions} for more information about appropriate branch
names.)  Jim then creates his workspace:

@smallexample
@group
/home/jim$ mtn --db=jim.mtn --branch=jp.co.juicebot.jb7 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
workspace. For the rest of this example we will assume that everyone
issues all further monotone commands from their workspace 
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
workspace.  He specifies one filename and one directory; monotone
recursively scans the directory and adds all its files.

@smallexample
@group
$ mtn add include/jb.h src
mtn: adding include/jb.h to workspace manifest
mtn: adding src/apple.c to workspace manifest
mtn: adding src/banana.c to workspace manifest
@end group
@end smallexample

This command produces a record of Jim's intentions in a special file
called @file{_MTN/revision}, stored in the workspace. The file is plain
text:

@smallexample
@group
$ cat _MTN/revision

format_version "1"

new_manifest [2098eddbe833046174de28172a813150a6cbda7b]

old_revision []

add_file "include/jb.h"
 content [3b12b2d0b31439bd50976633db1895cff8b19da0]

add_file "src/apple.c"
 content [2650ffc660dd00a08b659b883b65a060cac7e560]

add_file "src/banana.c"
 content [e8f147e5b4d5667f3228b7bba1c5c1e639f5db9f]
@end group
@end smallexample

You will never have to look at this file, but it is nice to know that
it is there.

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
$ mtn status
Current branch: jp.co.juicebot.jb7
Changes against parent :
  added   include/jb.h
  added   src/apple.c
  added   src/banana.c
@end group
@end smallexample

The output of this command tells Jim that his edits, so far,
constitute only the addition of some files.

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
$ mtn diff
# 
# old_revision []
# 
# add_file "include/jb.h"
#  content [3b12b2d0b31439bd50976633db1895cff8b19da0]
# 
# add_file "src/apple.c"
#  content [2650ffc660dd00a08b659b883b65a060cac7e560]
# 
# add_file "src/banana.c"
#  content [e8f147e5b4d5667f3228b7bba1c5c1e639f5db9f]
# 
============================================================================
--- include/jb.h
+++ include/jb.h 3b12b2d0b31439bd50976633db1895cff8b19da0
@@ -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 2650ffc660dd00a08b659b883b65a060cac7e560
@@ -0,0 +1,7 @@
+#include "jb.h"
+
+void 
+dispense_apple_juice()
+@{
+  /* Fill this in please, Abe. */
+@}
============================================================================
--- src/banana.c
+++ src/banana.c e8f147e5b4d5667f3228b7bba1c5c1e639f5db9f
@@ -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
then commits his workspace, which causes monotone to process the
@file{_MTN/revision} file and record the file contents, manifest, and
revision into the database. Since he provided a branch name when he
ran @command{setup}, monotone will use this as the default branch name
when he commits.


@smallexample
@group
$ mtn commit --message="initial checkin of project"
mtn: beginning commit on branch 'jp.co.juicebot.jb7'
mtn: committed revision 2e24d49a48adf9acf3a1b6391a080008cbef9c21
@end group
@end smallexample

When monotone committed Jim's revision, it updated @file{_MTN/revision}
to record the workspace'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
$ mtn automate get_base_revision_id
2e24d49a48adf9acf3a1b6391a080008cbef9c21
@end group
@end smallexample

Monotone also generated a number of certificates attached to
the new revision, and made sure that the database contained a copy of Jim's
public key. These certs store metadata about the commit. Jim can
ask monotone for a list of certs on this revision.

@smallexample
@group
$ mtn 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
$ mtn 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
descendants. Since Jim has not committed any changes to this revision
yet, it has no descendants.

@page
@node    Basic Network Service
@section Basic Network Service

Jim now decides he will make his base revision available to his
employees.  To do this, he arranges for Abe and Beth to synchronise
their databases with his, over the network.  There are two
pre-requisites for 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. Finally, with these
pre-requisites in place, he needs to tell monotone to provide network
access to his database.

First, Abe exports his public key:

@smallexample
@group
$ mtn --db=~/abe.mtn 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
$ mtn --db=~/beth.mtn 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 exchanging
keys with the person they intend to trust, 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 in a way that he can be sure
of.

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
$ cat ~/abe.pubkey ~/beth.pubkey | mtn --db=~/jim.mtn read
mtn: read 2 packets
@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 editing a
pair of small files in his @file{~/.monotone} directory:

@smallexample
@group
$ cat >>~/.monotone/read-permissions
pattern "*"
allow "abe@@juicebot.co.jp"
allow "beth@@juicebot.co.jp"
^D

$ cat >>~/.monotone/write-permissions
abe@@juicebot.co.jp
beth@@juicebot.co.jp
^D
@end group
@end smallexample

These files are read by the default monotone hooks that will decide
whether remote monotone users will be allowed access to Jim's database,
identified by the named keys.

Jim then makes sure that his TCP port 4691 is open to incoming
connections, adjusting his firewall settings as necessary, and runs
the monotone @command{serve} command:

@smallexample
@group
$ mtn --db=jim.mtn serve
@end group
@end smallexample

This command starts monotone listening on all network interfaces of 
his laptop on the default port 4691, serving everything in his database.

@page
@node    Synchronising Databases
@section Synchronising Databases

With Jim's server preparations done, now Abe is ready to fetch Jim's
code. To do this he issues the monotone @command{sync} command:

@smallexample
@group
$ mtn --db=abe.mtn sync jim-laptop.juicebot.co.jp "jp.co.juicebot.jb7*"
mtn: setting default server to jim-laptop.juicebot.co.jp
mtn: setting default branch include pattern to 'jp.co.juicebot.jb7*'
mtn: setting default branch exclude pattern to ''
mtn: connecting to jim-laptop.juicebot.co.jp
mtn: first time connecting to server jim-laptop.juicebot.co.jp:4691
mtn: I'll assume it's really them, but you might want to double-check
mtn: their key's fingerprint: 9e9e9ef1d515ad58bfaa5cf282b4a872d8fda00c
mtn: warning: saving public key for jim@@juicebot.co.jp to database
mtn: finding items to synchronize:
mtn: bytes in | bytes out | revs in | revs out | revs written
mtn:     2587 |      1025 |       1 |        0 |            1
mtn: 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. Remember that, in
monotone, work is done between workspaces in the filesystem and
the local database; network connectivity is necessary only when that
work is to be shared with others.

As we follow the juicebot team through the next several steps, we'll see
them run the @command{sync} command again with Jim, and work will flow
both ways. The first time you @command{sync} a new database, monotone
remembers the server and branch patterns you use, and makes them the
default for future operations.

At the end of each exchange, information about all changes in the branch
known to each database have been sent to the other party - including the
work of the third team member that had previously been exchanged. As
well as allowing each team member to learn about the others' work, this
also means that each party's laptop contains a @emph{backup} of the
others' work too.

Jim, Abe and Beth will continue working like this while they're getting
started, and we'll revisit the issue of network service with them a
little later as the project grows.

@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 workspace, so he can edit
it:

@smallexample
@group
$ mtn --db=abe.mtn --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
$ mtn diff
# 
# old_revision [2e24d49a48adf9acf3a1b6391a080008cbef9c21]
# 
# patch "src/apple.c"
#  from [2650ffc660dd00a08b659b883b65a060cac7e560]
#    to [e2c418703c863eabe70f9bde988765406f885fd0]
# 
============================================================================
--- src/apple.c 2650ffc660dd00a08b659b883b65a060cac7e560
+++ src/apple.c e2c418703c863eabe70f9bde988765406f885fd0
@@ -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
$ mtn commit 
mtn: beginning commit on branch 'jp.co.juicebot.jb7'
@end group
@end smallexample

Abe neglected to provide a @option{--message} option specifying the
change log on the command line and the file @file{_MTN/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
MTN:
MTN: ----------------------------------------------------------------------
MTN: Enter Log.  Lines beginning with `MTN:' are removed automatically
MTN:
MTN: format_version "1"
MTN:
MTN: new_manifest [b33cb337dccf21d6673f462d677a6010b60699d1]
MTN:
MTN: old_revision [2e24d49a48adf9acf3a1b6391a080008cbef9c21]
MTN: 
MTN: patch "src/apple.c"
MTN: from [2650ffc660dd00a08b659b883b65a060cac7e560]
MTN:   to [e2c418703c863eabe70f9bde988765406f885fd0]
MTN:
MTN: ----------------------------------------------------------------------
MTN:
@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
``MTN:'' and leaves only Abe's short message. Returning to the shell,
Abe's commit completes:

@smallexample
@group
mtn: committed revision 70decb4b31a8227a629c0e364495286c5c75f979
@end group
@end smallexample

Abe then sends his new revision back to Jim:

@smallexample
@group
$ mtn sync
mtn: connecting to jim-laptop.juicebot.co.jp
mtn: finding items to synchronize:
mtn:   certs |    keys | revisions
mtn:       8 |       2 |         2
mtn: bytes in | bytes out | revs in | revs out | revs written
mtn:      615 |      2822 |       0 |        1 |            0
mtn: 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
$ mtn --db=beth.mtn sync jim-laptop.juicebot.co.jp "jp.co.juicebot.jb7*"
mtn: setting default server to jim-laptop.juicebot.co.jp
mtn: setting default branch include pattern to 'jp.co.juicebot.jb7*'
mtn: setting default branch exclude pattern to ''
mtn: connecting to jim-laptop.juicebot.co.jp
mtn: first time connecting to server jim-laptop.juicebot.co.jp:4691
mtn: I'll assume it's really them, but you might want to double-check
mtn: their key's fingerprint: 9e9e9ef1d515ad58bfaa5cf282b4a872d8fda00c
mtn: warning: saving public key for jim@@juicebot.co.jp to database
mtn: finding items to synchronize:
mtn: bytes in | bytes out | revs in | revs out | revs written
mtn:     4601 |      1239 |       2 |        0 |            1
mtn: verifying new revisions (this may take a while)
mtn: bytes in | bytes out | revs in | revs out | revs written
mtn:     4601 |      1285 |       2 |        0 |            2
mtn: 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
$ mtn --db=beth.mtn --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{_MTN/log} right away so she does not
forget what she has done like Abe.

@smallexample
@group
$ vi _MTN/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
$ mtn commit
mtn: beginning commit on branch 'jp.co.juicebot.jb7'
mtn: committed revision 80ef9c9d251d39074d37e72abf4897e0bbae1cfb
@end group
@end smallexample

And she syncs with Jim again:

@smallexample
@group
$ mtn sync
mtn: connecting to jim-laptop.juicebot.co.jp
mtn: finding items to synchronize:
mtn:   certs |    keys | revisions
mtn:      12 |       3 |         3
mtn: bytes in | bytes out | revs in | revs out | revs written
mtn:      709 |      2879 |       0 |        1 |            0
mtn: 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 preceded
Abe's work, which entirely preceded 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
workspace:

@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
$ mtn diff
# 
# old_revision [80ef9c9d251d39074d37e72abf4897e0bbae1cfb]
#
# patch "src/banana.c"
#  from [7381d6b3adfddaf16dc0fdb05e0f2d1873e3132a]
#    to [5e6622cf5c8805bcbd50921ce7db86dad40f2ec6]
# 
============================================================================
--- src/banana.c 7381d6b3adfddaf16dc0fdb05e0f2d1873e3132a
+++ src/banana.c 5e6622cf5c8805bcbd50921ce7db86dad40f2ec6
@@ -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
$ mtn commit --message="interrupt implementation of src/banana.c"
mtn: beginning commit on branch 'jp.co.juicebot.jb7'
mtn: committed revision 8b41b5399a564494993063287a737d26ede3dee4
@end group
@end smallexample

And she syncs with Jim:

@smallexample
@group
$ mtn sync
@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 workspace 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
$ mtn 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
$ mtn sync
@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
$ mtn heads
mtn: 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
$ mtn merge
mtn: starting with revision 1 / 2
mtn: merging with revision 2 / 2
mtn: [source] 39969614e5a14316c7ffefc588771f491c709152
mtn: [source] 8b41b5399a564494993063287a737d26ede3dee4
mtn: common ancestor 70decb4b31a8227a629c0e364495286c5c75f979 abe@@juicebot.co.jp  2004-10-26T:02:50:01 found
mtn: trying 3-way merge
mtn: [merged] da499b9d9465a0e003a4c6b2909102ef98bf4e6d
mtn: your workspaces 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 workspace. 

@smallexample
@group
$ mtn update
mtn: selected update target da499b9d9465a0e003a4c6b2909102ef98bf4e6d
mtn: updating src/apple.c to f088e24beb43ab1468d7243e36ce214a559bdc96
mtn: updating src/banana.c to 5e6622cf5c8805bcbd50921ce7db86dad40f2ec6
mtn: 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 workspace
and the chosen target. The result was then written to Jim's workspace. If
Jim's workspace 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 workspace, 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 workspaces 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{mtn 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
$ mtn commit --branch=jp.co.juicebot.jb7.muffins --message='autobake framework'
mtn: beginning commit on branch 'jp.co.juicebot.jb7.muffins'
mtn: 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 workspace, and they
will automatically go to the muffins branch; if anyone else wants to
help her work on muffins, they can check out that branch as usual.

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

@smallexample
@group
$ mtn propagate jp.co.juicebot.jb7 jp.co.juicebot.jb7.muffins
mtn: propagating jp.co.juicebot.jb7 -> jp.co.juicebot.jb7.muffins
mtn: [source] da003f115752ac6e4750b89aaca9dbba178ac80c
mtn: [target] d0e5c93bb61e5fd25a0dadf41426f209b73f40af
mtn: common ancestor 853b8c7ac5689181d4b958504adfb5d07fd959ab jim@@juicebot.co.jp 2004-10-26T:12:44:23 found
mtn: trying 3-way merge
mtn: [merged] 89585b3c5e51a5a75f5d1a05dda859c5b7dde52f
@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 simply propagates the other way:

@smallexample
@group
$ mtn propagate jp.co.juicebot.jb7.muffins jp.co.juicebot.jb7
mtn: propagating jp.co.juicebot.jb7.muffins -> jp.co.juicebot.jb7
mtn: [source] 4e48e2c9a3d2ca8a708cb0cc545700544efb5021
mtn: [target] bd29b2bfd07644ab370f50e0d68f26dcfd3bb4af
mtn: common ancestor 652b1035343281a0d2a5de79919f9a31a30c9028 jim@@juicebot.co.jp 2004-10-26T:15:25:05 found
mtn: [merged] 03f7495b51cc70b76872ed019d19dee1b73e89b6
@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.

@page
@node    Network Service Revisited
@section Network Service Revisited

Up until now, Jim has been using his laptop and database as a sort of
``central server'' for the company; Abe and Beth have been syncing with
Jim, and learning of each other's work via Jim's database.  This has
worked fine while the product has been in early development; Jim has
good network connectivity in Japan, and has been staying home
concentrating on programming.  He has been able to leave his laptop
connected and running all the time, while his employees in different
time-zones work and sync their databases.  This is now starting to
change, and two problems are starting to cause occasional difficulties.

@itemize
@item
First, Jim is finding that he has to spend more of his time
travelling, demonstrating the new juicebot features to customers; thus
his laptop is spending more time disconnected from the network, or
connected at dynamic addresses where it's not convenient for Abe and
Beth to find him and sync.

This doesn't prevent them doing any work, but it does have some
uncomfortable consequences: they're more likely to have to manually
merge conflicting changes when they finally sync up and discover they've
both come up with slightly different fixes for the same bug in the
meantime, and they're more exposed to loss of work if one of them
suffers a disk failure before they've had a chance to sync that work
with another database.

@item
Second, because Jim has been using the one database file both for his
own local work, and for serving to the others in the team, he
occasionally finds that the monotone serve process (busy syncing with
Abe or Beth) has a lock on the database, while he's trying to do local
work like updates or commits.

The level of project activity is picking up, and there are more and more
changes to be synced in the narrower window of time while Jim is
connected. He finds he sometimes needs to take down the server process
to do this local work, further exacerbating the first problem.
@end itemize

The juicebot team are resourceful, and by now quite used to working
independently.  While Jim has been away travelling, Abe and Beth have
come up with their own solution to the first problem: they'll run
servers from their databases, setting them up just like Jim did
previously.  That way, if Jim's database is offline, either Beth or Abe
can run the @command{serve} command and provide access for the other to
@command{sync} with.  Beth also has the idea to create a second database
for the @command{serve} process, and to @command{sync} her development
database with that server locally, avoiding locking contention between
multiple monotone processes on the one database file.

When Jim reappears, the next person to @command{sync} with him will
often pass him information about both employees' work that they've
sync'ed with each other in the meantime, just as he used to do. In fact,
Jim now finds it more convenient to initiate the sync with one of the
other servers when he has a spare moment and dynamic connectivity from a
hotel room or airport.  Changes will flow between servers automatically
as clients access them and trade with one another.

This gets them by for a while, but there are still occasional
inconveniences.  Abe and Beth live in very different time-zones, and
don't always have reliable network connectivity, so sometimes Jim finds
that neither of them is online to sync with when he has the chance.  Jim
now also has several customers interested in beta-testing the new code,
and following changes as the bugs and issues they report are addressed.

Jim decides it's time for a permanent server they can all sync with;
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.  

Jim has rented some web server space on a service provider's shared
system for the JuiceBot Inc. public website, @code{www.juicebot.co.jp};
he thinks this server will be a good place to host the central monotone
server too. He sets up a new monotone database on the server,
generates a new key specially for the server (so he doesn't have to
expose his own development private key on the shared system), and loads
in the team-members' keys:  

@smallexample
@group
$ mtn --db=server.mtn db init
$ mtn genkey monotone-server@@www.juicebot.co.jp
mtn: generating key-pair 'monotone-server@@www.juicebot.co.jp'
enter passphrase for key ID [monotone-server@@www.juicebot.co.jp] : @i{<Jim enters a new passphrase>}
confirm passphrase for key ID [monotone-server@@www.juicebot.co.jp]: @i{<Jim confirms the passphrase>}
mtn: storing key-pair 'monotone-server@@www.juicebot.co.jp' in /home/jim/.monotone/keys
$ cat abe.pubkey beth.pubkey jim.pubkey | mtn --db=server.mtn read
mtn: read 3 packets
@end group
@end smallexample

For the team members, he sets up the permissions files on the server
much like before --- except that of course he needs to also grant his
@code{jim@@juicebot.co.jp} key permission to access the new server.  For
the beta-testers, Jim wants to allow them read-only access just to the
main JuiceBot 7 development line, but not to any of the sub-branches
where other experimental development is going on. He adds some lines at
the top of the @file{~/.monotone/read-permissions} on the server, above
the broader permissions given to team-members. See the @ref{Hook
Reference} for @code{get_netsync_read_permitted} for more details; the
resulting file looks like this:

@smallexample
@group
comment "Provide beta-testers with specific read-only access"
pattern "jp.co.juicebot.jb7"
allow "beta1@@juicebot.co.jp"
allow "beta2@@juicebot.co.jp"
continue "true"

comment "Fall-through, and allow staff access to all branches"
pattern "*"
allow "abe@@juicebot.co.jp"
allow "beth@@juicebot.co.jp"
allow "jim@@juicebot.co.jp"
@end group
@end smallexample


Jim could log in and start the monotone process manually from his shell
account on the server, perhaps under a program like screen to let it
stay running while he's away. This would be one way of giving it the
server-key's passphrase each startup, but he wants to make sure that the
server is up all the time; if the host reboots while he's travelling and
the monotone server is down until he next logs in, things aren't much
better than before.  For the server to start automatically each time,
he'll need to use the @code{get_passphrase} hook in the server's
@file{.monotonerc} file again.

Because he's running on a shared server, Jim needs to be a little more
restrictive about which interfaces and addresses his new server process
will listen on. He should only accept connections at the address used
for his website, because some of the provider's other customers might
also want to publish their own monotone projects on this host.  Jim uses
the @option{--bind=@var{address}:@var{port}} argument like so:

@smallexample
@group
$ mtn --db=server.mtn --bind=www.juicebot.co.jp serve
@end group
@end smallexample

This will start monotone listening on the default port (4691), but only
on the IP address associated with @code{www.juicebot.co.jp}.  Jim can do
this because his hosting provider has given him a dedicated IP address
for his website.  If the hosting provider offered only a single shared
IP address belonging to the server, each customer could bind a different
port number on that address.

While he's first testing the setup, Jim uses
@option{--bind=localhost:1234}. This causes the monotone process to listen
only to port 1234 on the loopback interface 127.0.0.1, which is not
accessible from the network, so Jim doesn't expose an open port to the
rest of the world until he's satisfied with the permissions
configuration.  You can cause monotone to listen on all interfaces on
port 1234 by leaving out the address part like @option{--bind=:1234}.

When he's satisfied the server is set up correctly, Jim does an initial
@command{sync} with the new database, filling it with all the revision
history currently on his laptop. While Jim has been busy setting up the
server, Abe and Beth have kept working; the server will catch up with
their latest changes when they next sync, too.

All of the team members now want to sync with the new monotone server by
default.  Previously, they had been syncing with Jim's laptop by
default, even if they occasionally specified another team-member's
server on the command line when Jim was away, because monotone had
remembered the first server and branch patterns used in database
@ref{Vars}.  These vars can be seen as follows:

@smallexample
@group
$ mtn list vars
database: default-exclude-pattern 
database: default-include-pattern jp.co.juicebot.jb7*
database: default-server jim-laptop.juicebot.co.jp
known-servers: jim-laptop.juicebot.co.jp 9e9e9ef1d515ad58bfaa5cf282b4a872d8fda00c
known-servers: abe-laptop.juicebot.co.jp a2bb16a183247af4133621f7f5aefb21a9d13855
known-servers: www.juicebot.co.jp 120a99ch93b4f174432c13d3e3e9f2234aa92612
@end group
@end smallexample

The team members can reset their local database vars accordingly:

@smallexample
@group
$ mtn set database default-server www.juicebot.co.jp
@end group
@end smallexample

With their new server, the juicebot team have gained the convenience of
a readily available common point of reference for syncs.  However, they
also know that this is there only as a convenience, and doesn't prevent
them working as they did before:
@itemize
@item
The team members can still sync with each other if needed. 

Hopefully, their new server won't ever be down, but sometimes they might
be working together while away from ready network access --- fixing up
the last few issues and finalising presentation materials while
travelling to a sales conference, for example.  The server will learn of
these changes on the next sync.
@item
The team members continue to discover multiple heads and changes that
need merging, as before. Each team member can merge the heads, and will
produce the same revision id if they merge to the same result. 

They now develop a new habit out of courtesy, though --- they try not to
leave multiple heads and unmerged changes on the server, at least not
for long. This saves them from repeating work, and also helps prevent
confusion for the beta-testers.  When each team member is ready to
@command{sync}, they develop the habit of doing a @command{pull} from
the server first.  If new revisions were received from the server, they
first @command{merge} their new revisions with the head(s) from the
server, and finally @command{sync} to publish their merged changes as
one.  If the last @command{sync} happens to pull in new revisions again
from the server, it means someone else has deposited new work at the
same time, and another @command{merge} and @command{sync} would probably
be polite.
@item
Jim knows he doesn't have to keep a special backup of the new server's
contents; if the server should fail, all the contents of its database
can be found amongst the other team members (especially because no
commits are done on the server itself).

He does, however, take a copy of the server's private key, so he can
restore that if necessary.
@item
In fact, Jim realises that he can now commit a copy of the web site's
current contents into monotone on a new branch,
@code{jp.co.juicebot.www}, and keep a backup of that content too. 

Now he can use monotone to work on the website offline, and let other
team members add and edit the content; he can also preview changes
locally before updating the production content.  He keeps a workspace
checkout of this content in the webroot on the server, and runs a
monotone @command{update} in there when he wants to bring the public web
site up to date. Later, he'll think about using monotone's @ref{Quality
Assurance} mechanisms and Event Notification @ref{Hooks}, so that the
web server can update itself automatically when appropriate new
revisions are received.
@item
Jim also knows that even if someone should break into the shared hosting
server and tamper with the database, they won't be able to inject
malicious code into the project, because all revisions are signed by the
team members, and he has set his @ref{Trust Evaluation Hooks} so he
doesn't trust the server key for signing revisions.  

In monotone, the important trust consideration is on the @emph{signed
content}, rather than on the @emph{replication path} by which that
content arrived in your database.
@end itemize

@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
* Other Transports::       Using netsync over SSH, or other transports.
* Selectors::              Selecting revisions by certificate.
* Restrictions::           Limit workspace changes to specified files.
* Scripting::              Running monotone from other programs.
* Inodeprints::            Trading off safety for speed in your workspace.
* Workspace Collisions::   Workspace files that collide with new versioned files.
* 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.
* Using packets::          Transferring data ``by hand''.
@end menu

@page
@node    Other Transports
@section Other Transports

Monotone's database synchronization system is based on a protocol
called netsync. By default, monotone transports this protocol over a
plain TCP connection, but this is not the only transport monotone can
use. It can also transport netsync through SSH, or any program which
can provide a full-duplex connection over @code{stdio}.

When a monotone client initiates a push, pull, or sync operation, it
parses the first command-line argument as a URI and calls a Lua hook
to convert that URI into a @dfn{connection command}. If the Lua hook
returns a connection command, monotone spawns the command locally and
speaks netsync over a pipe connected to the command's standard I/O
handles. 

If the Lua hook does not return a connection command, monotone
attempts to parse the command-line argument as a TCP address -- a
hostname with an optional port number -- connects a TCP socket the
host and port, and speaks netsync over the socket.

By default, monotone understands two URI schemes:

@enumerate
@item SSH URIs, of the form 
  @code{ssh://[@var{user}@@]@var{hostname}[:@var{port}]/@var{path/to/db.mtn}},
  to synchronize between private databases on hosts accessible only
  through SSH.  (These paths are absolute; to refer to a path relative
  to a home directory, use
  @code{ssh://@var{host-part}/~/@var{relative/path.mtn}} or 
  @code{ssh://@var{host-part}/~@var{user}/@var{relative/path.mtn}}.)
@item File URIs, of the form
  @code{file:@var{/path/to/db.mtn}}, to synchronize between local databases.
@end enumerate

In the case of SSH URIs, the @command{ssh} program must be in your
command execution path, either @var{$PATH} on Unix-like systems or
@var{%PATH%} on Windows systems. Monotone will execute @command{ssh}
as a subprocess, running @command{mtn serve} on the other end of the
SSH connection. You will need @command{mtn} to be in the command
execution path of the remote shell environment.

In the case of File URIs, @command{mtn} is run locally, so must be 
in your command execution path. 

In both cases, the database specified in the URI needs to exist
already, and will be locked for the duration of the synchronization
operation. Also note that monotone's default transport authentication
is @emph{disabled} over these transports, to reduce the complexity of
configuration and eliminate redundant protocol cost.

Additional URI schemes can be supported by customization of the Lua
hooks @code{get_netsync_connect_command} and
@code{use_transport_auth}. For details on these hooks, see
@ref{Netsync Transport Hooks}.

@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 shell wildcards.  For
example, @code{c:tag} matches all revisions that have a tag, and
@code{c:tag=monotone-0.25} will match the revision tagged
@code{monotone-0.25}.  (See also the @code{t} selector below.)
@item Author selection
Uses selector type @code{a}. For example, @code{a:graydon} matches
@code{author} certs where the cert value contains @code{graydon}.
@item Branch selection
Uses selector type @code{b}. For example, @code{b:net.venge.monotone} matches
@code{branch} certs where the cert value is @code{net.venge.monotone}.
Values to match for can have shell wildcards.  If you give a bare @code{b:}
monotone will require you to be in a workspace, and will use the branch
value recorded in your _MTN/options file.
@item Heads selection
Uses selector type @code{h}. For example, @code{h:net.venge.monotone} matches
@code{branch} certs where the cert value is @code{net.venge.monotone} and 
the associated revision is a head revision on that branch.  Values to match
for can have shell wildcards like the branch selector.  If you give a bare 
@code{h:} monotone will require you to be in a workspace, and use the branch
recorded in your _MTN/options file.
@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 greater 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}.
Values to match for can have shell wildcards.
@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}. The
@code{/} character can be escaped using the @code{\} character if necessary.

@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 workspace 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}
@item @command{list changed}
@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.

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 workspace 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 workspace.  By default, the @i{entire workspace} 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 workspace 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 workspace all
paths specified to monotone commands must be relative to the current
subdirectory.

@heading Finding a workspace

Monotone only stores a single @file{_MTN} directory at the root of a
workspace. Because of this, a search is done to find the @file{_MTN}
directory in case a command is executed from within a subdirectory of a
workspace. Before a command is executed, the search for a workspace
directory is done by traversing parent directories until an
@file{_MTN} directory is found or the filesystem root is reached. Upon
finding an @file{_MTN} directory, the @file{_MTN/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 workspace and will simply
proceed with no default options if no @file{_MTN} directory is found.
However, some monotone commands do require a workspace and will fail
if no @file{_MTN} directory can be found.

The @command{checkout}, @command{clone} and @command{setup} commands
create a @i{new workspace} and initialize a new @file{_MTN/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
@command{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 workspace 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
workspace, 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 workspace; 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{mtn
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{_MTN/inodeprints}.  You can at any time delete or truncate
the @file{_MTN/inodeprints} file; monotone uses it only as a cache and
will continue to operate correctly.

Normally, instead of enabling this up on a per-workspace 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
workspaces you create.  See @ref{Hook Reference} for details.

@page
@node    Workspace Collisions
@section Workspace Collisions

Sometimes when you work on a project, several people make similar
changes in parallel.  When these changes occur in an existing file that
is known to both sides, monotone can merge the edits when the two
revisions meet (possibly after getting help to resolve content
conflicts).  Other kinds of changes cannot be merged so readily,
especially ones that involve files in your workspace that are not
tracked by monotone.

Workspace collisions can happen for many reasons; some examples include:
@itemize
@item
You have a file in your workspace that is unknown to monotone (you
have not @command{add}ed it).  Someone else has @command{add}ed and
@command{commit}ed a different file with the same name.  If you try to
@command{update} your workspace to their revision, the added file in the
incoming revision will collide with your file over use of the name.
@item
There is a directory which contains both versioned and unversioned files
(perhaps versioned sources, and unversioned object files built from the
sources).  Someone else @command{commit}s a revision that
@command{drop}s the versioned files @emph{and} the containing
directory.  If you try to @command{update} to this revision, your
directory will still contain the untracked files, and therefore cannot
be deleted.
@item
You have an unversioned file in your workspace, and you're trying to
@command{update} to a revision that @command{add}s a directory with the
same name.
@end itemize

These examples describe collisions on @command{update}; the same kinds
of things can happen with other commands that can bring changes into
your workspace, such as @command{checkout} or @command{pluck} too.

Monotone is careful to avoid hitting such collisions. Before changing
the workspace, it will try and detect the possibility of collisions, and
the command will fail, warning you about the names that collide.  The
file content in the database is safe and can be recovered at any time,
so monotone is conservative and will refuse to destroy the information
in your workspace contents.

However, monotone cannot detect all kinds of failures and collisions in
your workspace. For example:
@itemize
@item
On some systems with case-insensitive and/or internationalised
filesystems, names that look distinct to monotone may in fact be
considered the same by the underlying platform.
@item
If some other program is creating files in the workspace at the same
time as monotone, the colliding file might be created after the
collision check at the start.
@item 
Other kinds of unpredictable system errors, like permissions problems or
disk full conditions, might cause failures when monotone is rearranging
the workspace content.
@end itemize

These are all hopefully very rare occurrences. If such a filesystem
error @emph{does} cause a failure part-way during a workspace
alteration, monotone will stop immediately rather than risk potentially
doing further damage, and your workspace may be left in an incomplete
state.  If this happens, you will need to resolve the issue and clean up
the workspace manually.  If you need to do so, understanding how
monotone manipulates the workspace is helpful.

When monotone applies renaming changes to the workspace, each file is
first @dfn{detached} from the workspace under its old name, then
@dfn{attached} under the new name. This is done by moving it to the
@file{_MTN/detached} directory. Newly added files are created here
before being moved into place, too.  While inside @file{_MTN/detached},
the file or directory is named as a simple integer (these numbers come
from monotone's internal identification of the node).  If the detached
node is a directory, the directory is moved with all of its contents
(including unversioned files); this can help identify which directory
has been detached.

If a previous workspace alteration failed part-way, the
@file{_MTN/detached} directory will still exist, and monotone will
refuse to attempt another alteration while the workspace is in this
inconsistent state. This also acts as a lock against multiple monotone
processes performing workspace alterations (but not other programs).

The best way to avoid a messy recovery from such a failure is simply to
ensure that you always @command{commit} before trying to
@command{update} (or @command{pluck}, etc) other changes from the
database into your workspace. This ensures that your current workspace
contents are safely stored, and can be retrieved later (such as with
@command{revert}).

@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 descendants of a particular revision, or extracting
the ``heads'' of a subgraph, which is the subgraph's set of nodes with
no descendants. For example, when you run the @command{update} command,
monotone searches the subgraph consisting of descendants of the base
revision of the current workspace, 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 workspace. 

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-workspace, 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-exclude-pattern
The default branch exclusion glob pattern for netsync operations to
use. Automatically set by first use of netsync, and by any netsync
that uses the @option{--set-default} option.
@item default-include-pattern
The default branch glob pattern for netsync operations to use.
Automatically set by first use of netsync, and by any netsync that
uses the @option{--set-default} option.
@item default-server
The default server for netsync operations to use.  Automatically set
by first use of netsync, and by any netsync that uses the
@option{--set-default} option.
@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{mtn unset known-servers @var{server-name}}.

@end table

@page
@node    Reserved Files
@section Reserved Files

A monotone workspace 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 workspace, 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 workspace, 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 workspace 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{.mtn-}
@item Non-versioned control files
Any file in the directory @file{_MTN/}
@end table

The general intention is that versioned control files are things that
you may want to edit directly.  In comparison, you should never have
to edit non-versioned control files directly; monotone should do that
for you whenever it is appropriate.  However, both are documented
here, just in case a situation arises where you need to go ``under the
hood''.

@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 .mtn-ignore
Contains a list of regular expression patterns, one per line. If it exists,
any file with a name matching one of these patterns is ignored.
@item _MTN/wanted-testresults
Contains a list of testresult key names, one per line. If it exists, update
will only select revisions that do not have regressions according to the given
testresult keys.
@item _MTN/revision
Contains the identity of the ``base'' revision of the workspace, and a
list of additions, deletions, and renames which have occurred in the
current workspace, relative to that version.

Every workspace has a base revision, which is the revision that was
originally checked out to create that workspace.  When the workspace
is committed, the base revision is considered to be the ancestor of
the committed revision.
@item _MTN/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 workspace.
@item _MTN/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 _MTN/inodeprints
If this file exists, monotone considers the directory to be in
@ref{Inodeprints} mode, and uses this file to cache the inodeprints.
@item _MTN/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} many of these certs
as part of normal operation, such as during a @command{commit}. Others
will be added explicitly via other commands, like @command{tag} or
@command{approve}.

As well as carrying other information, certs (and combinations of certs)
are useful for identifying revisions with @ref{Selectors}; in
particular, this is the primary purpose of the @code{tag} cert.

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 @command{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 @command{commit} command or
indirectly with the @command{merge} or @command{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 @command{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} will be
shown together with @code{changelog} certs by the @command{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 @command{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 as a way of selecting the revision by name for later commands like
@command{checkout}, @command{log} or @command{diff}.  

@item testresult
This cert's value is interpreted as a boolean string, either @code{0}
or @code{1}. It is generated by the @command{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 support for storing @dfn{persistent attributes} on
files and directories, generally known as @dfn{attrs} for short.  An
attr associates a simple name/value pair with a file or directory, and
is stored in the manifest.  Attrs are first-class versioned data; they
can be changed in a workspace, and those changes will be saved when
the workspace is committed.  The merger knows how to intelligently
merge attrs.

The attribute mechanism was originally 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
workspace.  For example, the @command{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.

Monotone comes with support for some attrs built-in; for instance, if
an executable file is given to @command{mtn add}, then it will
automatically mark the new file with a @code{mtn:execute} attr, and
when the file is checked out later, the executable bit will be set
automatically.  (Of course, if it is checked out on Windows, which
does not support the executable bit, then the executable bit will not
be set.  However, monotone will still know that the attr is set, and
Windows users can view and modify the attr like anyone else.)

Attrs in the current workspace can be seen and modified using the
@command{mtn attr} command; see @ref{Workspace}.  Attrs can also be found
by examining any manifest directly.

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 workspace is written to,
monotone will run the corresponding hooks registered for each attr in
your workspace.  This way, you can extend the vocabulary of attrs
understood by monotone simply by writing new hooks.

You can make up your own attrs for anything you find useful; the
mechanism is fully general.  (If you make up some particularly useful
ones, we may even be interested in adding support to monotone proper.)
We only ask that if you do use custom attrs, you use some prefix for
them besides @code{mtn:}; attrs beginning with @code{mtn:} are
reserved for monotone's own use.

@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 @code{merge3} hook
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 which 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{mtn 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{mtn 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{mtn 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.mtn} 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 workspace:

@smallexample
@group
$ mtn --db=test.mtn db init
$ mtn --db=test.mtn genkey import@@example.net
$ mtn --db=test.mtn --branch=net.example.wobbler cvs_import /usr/local/cvsroot/wobbler
$ mtn --db=test.mtn --branch=net.example.wobbler checkout wobber-checkout
@end group
@end smallexample

@page
@node    Using packets
@section Using packets

Suppose you made changes to your database, and want to send those
changes to someone else but for some reason you cannot use netsync.  Or
maybe you want to extract and inject individual revisions automatically
via an external program. In this case, you can convert the information
into packets. Packets are a convenient way to represent revisions and
other database contents as plain text with wrapped lines -- just what
you need if you want to send them in the body of an email.

This is a tutorial on how to transfer single revisions between
databases by dumping them from one database to a text file and then
reading the dump into a second database.

We will create two databases, A and B, then create a few revisions in
A, and transfer part of them to B.

First we initialize the databases:

@smallexample
@group
$ mtn -d A db init
$ mtn -d B db init
@end group
@end smallexample

Now set up a branch in A:

@smallexample
@group
$ mtn -d A setup -b test test
@end group
@end smallexample

And let's put some revisions in that branch:

@smallexample
@group
$ cd test/
$ cat > file
xyz
^D
$ mtn add file
$ mtn ci -m "One"    @i{You may need to select a key and type a passphrase here}
$ cat > file2
file 2 getting in
^D
$ cat > file
ERASE
^D
$ mtn add file2
$ mtn ci -m "Two"
$ cat > file
THIRD
^D
$ mtn ci -m "Three"
@end group
@end smallexample

OK, that's enough.  Let's see what we have:

@smallexample
@group
$ cd ..
$ mtn -d A automate select i: | mtn -d A automate toposort -@-
a423db0ad651c74e41ab2529eca6f17513ccf714
d14e89582ad9030e1eb62f563c8721be02ca0b65
151f1fb125f19ebe11eb8bfe3a5798fcbea4e736
@end group
@end smallexample

Three revisions! Let's transfer the first one to the database B. First we
get the meta-information on that revision:

@smallexample
@group
$ mtn -d A automate get_revision a423db0ad651c74e41ab2529eca6f17513ccf714
format_version "1"

new_manifest [b6dbdbbe0e7f41e44d9b72f9fe29b1f1a4f47f18]

old_revision []

add_dir ""

add_file "file"
 content [8714e0ef31edb00e33683f575274379955b3526c]
@end group
@end smallexample

OK, one file was added in this revision. We'll transfer it. Now, @emph{ORDER MATTERS}!
We should transfer:

@enumerate
@item The file data (fdata) and file deltas (fdeltas), if any
@item The release data (rdata)
@item The certs
@end enumerate

In that order. This is because certs make reference to release data, and release data
makes reference to file data and file deltas.

@smallexample
@group
mtn -d A automate packet_for_fdata 8714e0ef31edb00e33683f575274379955b3526c > PACKETS
mtn -d A automate packet_for_rdata a423db0ad651c74e41ab2529eca6f17513ccf714 >> PACKETS
mtn -d A automate packets_for_certs a423db0ad651c74e41ab2529eca6f17513ccf714 >> PACKETS
mtn -d B read < PACKETS
@end group
@end smallexample

This revision (a423db0ad651c74e41ab2529eca6f17513ccf714) was already sent to database
B. You may want to check the PACKETS file to see what the packets look like.

Now let's transfer one more revision:

@smallexample
@group
mtn -d A automate get_revision d14e89582ad9030e1eb62f563c8721be02ca0b65
format_version "1"

new_manifest [48a03530005d46ed9c31c8f83ad96c4fa22b8b28]

old_revision [a423db0ad651c74e41ab2529eca6f17513ccf714]

add_file "file2"
 content [d2178687226560032947c1deacb39d16a16ea5c6]

patch "file"
 from [8714e0ef31edb00e33683f575274379955b3526c]
   to [8b52d96d4fab6c1e56d6364b0a2673f4111b228e]
@end group
@end smallexample

From what we see, in this revision we have one new file and one patch, so we do the
same we did before for them:

@smallexample
@group
mtn -d A automate packet_for_fdata d2178687226560032947c1deacb39d16a16ea5c6 > PACKETS2
mtn -d A automate packet_for_fdelta 8714e0ef31edb00e33683f575274379955b3526c 8b52d96d4fab6c1e56d6364b0a2673f4111b228e >> PACKETS2
mtn -d A automate packet_for_rdata d14e89582ad9030e1eb62f563c8721be02ca0b65 >> PACKETS2
mtn -d A automate packets_for_certs d14e89582ad9030e1eb62f563c8721be02ca0b65 >> PACKETS2
mtn -d B read < PACKETS2
@end group
@end smallexample

Fine. The two revisions should be in the second database now.
Let's take a look at what's in each database:

@smallexample
@group
$ mtn -d A automate select i: | mtn -d A automate toposort -@-
a423db0ad651c74e41ab2529eca6f17513ccf714
d14e89582ad9030e1eb62f563c8721be02ca0b65
151f1fb125f19ebe11eb8bfe3a5798fcbea4e736

$ mtn -d B automate select i: | mtn -d B automate toposort -@-
a423db0ad651c74e41ab2529eca6f17513ccf714
d14e89582ad9030e1eb62f563c8721be02ca0b65
@end group
@end smallexample

Good! B has the two first revisions (as expected), and A has all three. However, a checkout
of that branch on B will not work, because the certificate signatures cannot be verified.
We need to transfer the signatures too (suppose the key used had the ID @code{"johndoe@@domain.com"}):

@smallexample
@group
mtn -d A pubkey johndoe@@domain.com > KEY_PACKETS
mtn -d B read < KEY_PACKETS
@end group
@end smallexample

Done.

@smallexample
@group
$ mtn -d B co -b test test-B
$ ls test-B
file2  _MTN  x
$ more test-B/file2
file 2 getting in
@end group
@end smallexample

And that's it! The revisions were successfully transferred.


@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
$ mtn pull www.foo.com com.foo.wobbler*
$ mtn 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 workspace. There are two cosmetic differences
with the monotone command: remote databases are specified by hostnames
and globs, 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
$ mtn commit --message="log message"
$ mtn 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 Undoing Changes

@multitable @columnfractions .4 .4
@item
@smallexample
@group
$ cvs update -C file
@end group
@end smallexample
@tab
@smallexample
@group
$ mtn revert file
@end group
@end smallexample
@end multitable

Unlike CVS, monotone includes a separate @command{revert} command for
undoing local changes and restoring the workspace to the original
contents of the base revision. Because this can be dangerous,
@command{revert} insists on an explicit argument to name the files or
directories to be reverted; use the current directory "@file{.}" at the
top of the workspace to revert everything.  The @command{revert} command
is also used to restore deleted files (with a convenient
@option{--missing} option for naming these files).

In CVS, you would need to use @command{update} to restore missing or
changed files, and you might get back a newer version of the file than
you started with. In monotone, @command{revert} always takes you back to
where you started, and the @command{update} command is only used to move
the workspace to a different (usually newer) base revision.


@heading Incorporating New Changes

@multitable @columnfractions .4 .4
@item
@smallexample
@group
$ cvs update -d
@end group
@end smallexample
@tab
@smallexample
@group
$ mtn pull www.foo.com com.foo.wobbler*
$ mtn merge
$ mtn 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 descendants of your base revision, and ignore other heads on
your branch.


@heading Tagging Revisions

@multitable @columnfractions .4 .4
@item
@smallexample
@group
$ cvs tag FOO_TAG .
@end group
@end smallexample
@tab
@smallexample
@group
$ mtn tag h: FOO_TAG
@end group
@end smallexample
@end multitable

With CVS, tags are placed on individual files, and the closest thing to
identifying a consistent repository-wide revision is a set of files with
the same tag.  In monotone, all changes are part of a repository-wide
revision, and some of those revisions may be tagged.  Monotone has no
partial tags that apply only to a subset of files.


@heading Moving Workspace to Another Revision

@multitable @columnfractions .4 .4
@item
@smallexample
@group
$ cvs update -r FOO_TAG -d
@end group
@end smallexample
@tab
@smallexample
@group
$ mtn update -r 830ac1a5f033825ab364f911608ec294fe37f7bc
$ mtn update -r 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
$ mtn diff
@end group
@end smallexample
@item
@smallexample
@group
$ cvs diff -r 1.2 -r 1.4 myfile
@end group
@end smallexample
@tab
@smallexample
@group
$ mtn diff -r 3e7db -r 278df myfile
@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 workspace 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}, rather than file IDs.  If one leaves off the file
argument, then diff can print the difference between two entire trees.

@heading Showing Workspace Status

@multitable @columnfractions .4 .4
@item
@smallexample
@group
$ cvs status
@end group
@end smallexample
@tab
@smallexample
@group
$ mtn 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 Workspace

@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
$ mtn 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 Workspace

@multitable @columnfractions .4 .4
@item
@smallexample
@group
$ rm file.txt
$ cvs remove file.txt
@end group
@end smallexample
@tab
@smallexample
@group
$ mtn drop file.txt
@end group
@end smallexample
@end multitable

Monotone does not require that you erase a file from the workspace
before you drop it. Dropping a file both removes its entry in the
manifest of the current revision and removes it from the filesystem.


@heading Viewing History

@multitable @columnfractions .4 .4
@item
@smallexample
@group
$ cvs log [file]
@end group
@end smallexample
@tab
@smallexample
@group
$ mtn log [file]
@end group
@end smallexample
@end multitable

Unlike CVS log, monotone log can also be used without a workspace; but
in this case you must pass a @option{--from} revision argument to tell
monotone where to start displaying the log from.

@heading Importing a New Project

@multitable @columnfractions .4 .4
@item
@smallexample
@group
$ cvs import wobbler vendor start
@end group
@end smallexample
@tab
@smallexample
@group
$ mtn --db=/path/to/database.mtn --branch=com.foo.wobbler setup .
$ mtn add .
$ mtn commit
@end group
@end smallexample
@end multitable

The @command{setup} command turns an ordinary directory into a
monotone workspace.  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
$ mtn db init --db=/path/to/database.mtn 
@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
* Workspace::        Operations on your workspace
* Network::          Communication with the network
* Informative::      Production of descriptive reports
* Key and Cert Trust::     Keys and Trust Evaluations based on them
* Certificate::      Creation of 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
@itemx mtn cat @var{path}
@itemx mtn cat --revision=@var{id} @var{path}

Write the contents of a specific file @var{path} to standard output.

Without a @option{--revision} argument, the command outputs the 
contents of @var{path} as found in the current revision. This requires 
the command be executed from within a workspace.

With an explicit @option{--revision} argument, the command outputs
contents of @var{path} at that revision.

@item mtn checkout --revision=@var{id} @var{directory}
@itemx mtn co --revision=@var{id} @var{directory}
@itemx mtn --branch=@var{branchname} checkout @var{directory}
@itemx mtn --branch=@var{branchname} co @var{directory}

These commands copy a revision @var{id} out of your database,
recording the chosen revision (the @dfn{base revision}) in the file
@file{@var{directory}/_MTN/revision}. These commands then copy every
file version listed in the revision's manifest to paths under
@var{directory}. For example, if the revision's manifest contains
these entries:

@smallexample
@group
dir ""

   file "Makefile"
content [84e2c30a2571bd627918deee1e6613d34e64a29e]

   file "include/hello.h"
content [c61af2e67eb9b81e46357bb3c409a9a53a7cdfc6]

   file "src/hello.c
content [97dfc6fd4f486df95868d85b4b81197014ae2a84]
@end group
@end smallexample

Then the following files are created:
@smallexample
@group
@var{directory}/
@var{directory}/Makefile
@var{directory}/include/hello.h
@var{directory}/src/hello.c
@end group
@end smallexample

If you wish to @command{checkout} in the current directory, you can
supply the special name @file{.} (a single period) for
@var{directory}. When running @command{checkout} into an existing
directory, it is sometimes possible for @ref{Workspace Collisions} to
occur.

If no @var{id} is provided, as in the latter two commands, you
@emph{must} provide a @var{branchname}; monotone will attempt to infer
@var{id} as the unique head of @var{branchname} if it exists.

@item mtn clone --branch=@var{branchname} @var{address} @var{directory}

The clone command is a helper command that performs the roles of a
number of other commands all at once.  Firstly, it constructs a new
database.  It then populates this database by @command{pull}ing any data
in the branch @var{branchname} from the remote database, @var{address}.
Finally, it copies the files out of the newly created database into a
local directory, just as @command{checkout} would.  The created
database is placed in the new workspace as @file{@var{directory}/_MTN/mtn.db}.

@item mtn disapprove @var{id}

This command records a disapproval of the changes between @var{id}'s
ancestor and @var{id}. It does this by committing the @i{inverse}
changes as a new revision descending from @var{id}. The new revision
will show up as a new head and thus a subsequent @command{merge} will
incorporate the inverse of the disapproved changes in the other head(s).

Conceptually, @command{disapprove}s contract is that disapprove(A) gives a 
revision B such that whenever B is merged with a descendant D of A the merge 
will result in what D ``would have looked like'' if A had never happened.

Note that as a consequence of this contract the @command{disapprove} command 
only works if @var{id} has exactly one ancestor, since it hasn't been 
worked out how to generate such a descendant in the multi-ancestor case.


@item mtn heads --branch=@var{branchname}
This command lists the ``heads'' of @var{branchname}. 

The ``heads'' of a branch is the set of revisions which are members of
the branch, but which have no descendants. These revisions are
generally the ``newest'' revisions committed by you or your
colleagues, at least in terms of ancestry. The heads of a branch may
not be the newest revisions, in terms of time, but synchronization of
computer clocks is not reliable, so monotone usually ignores time.


@item mtn merge [--branch=@var{branchname}]
This command merges the ``heads'' of @var{branchname}, if there are
multiple heads, and commits the results to the database, marking the
resulting merged revision as a member of @var{branchname}. The merged
revision will contain each of the head revision IDs as ancestors.

Merging is performed by repeated pairwise merges: two heads are
selected, then their least common ancestor is located in the ancestry
graph and these 3 revisions are provided to the built-in 3-way merge
algorithm. The process then repeats for each additional head, using
the result of each previous merge as an input to the next.

@item mtn propagate @var{sourcebranch} @var{destbranch}
This command takes a unique head from @var{sourcebranch} and merges it
with a unique head of @var{destbranch}, using the least common
ancestor of the two heads for a 3-way merge. The resulting revision is
committed to @var{destbranch}. If
either @var{sourcebranch} or @var{destbranch} has multiple heads,
@command{propagate} aborts, doing nothing.

The purpose of @command{propagate} is to copy all the changes on
@var{sourcebranch}, since the last @command{propagate}, to
@var{destbranch}. This command supports the idea of making separate
branches for medium-length development activities, such as
maintenance branches for stable software releases, trivial bug fix
branches, public contribution branches, or branches devoted to the
development of a single module within a larger project.

@item mtn explicit_merge @var{id} @var{id} @var{destbranch}
This command merges exactly the two @var{id}s you give it, and places
the result in branch @var{destbranch}.  It is useful when you need more
control over the merging process than @command{propagate} or @command{merge}
give you.  For instance, if you have a branch with three heads, and you
only want to merge two of them, you can use this command.  Or if you
have a branch with two heads, and you want to propagate one of them to
another branch, again, you can use this command.

@item mtn merge_into_dir @var{sourcebranch} @var{destbranch} @var{dir}
This command takes a unique head from @var{sourcebranch} and merges it
into a unique head of @var{destbranch}, as a directory. The resulting
revision is committed to @var{destbranch}. If either @var{sourcebranch} or
@var{destbranch} has multiple heads, @command{merge_into_dir} aborts, doing
nothing.

The purpose of @command{merge_into_dir} is to permit a project to contain
another project in such a way that @command{propagate} can be used to keep
the contained project up-to-date. It is meant to replace the use of nested
checkouts in many circumstances.

Note that @command{merge_into_dir} @emph{does not} permit changes made to the
contained project in @var{destbranch} to be propagated back to
@var{sourcebranch}. Attempting this would lead to @var{sourcebranch} containing
both projects nested as in @var{destbranch} instead of only the project
originally in @var{sourcebranch}, which is almost certainly not what would be
intended.

@item mtn import --branch=@var{branch} [--message=@var{message}] [--dry-run] @var{dir}
@item mtn import --revision=@var{revision} [--message=@var{message}] [--dry-run] @var{dir}
This command imports the contents of the given directory and commits it
to the head of the given branch or as a child of the given revision (and
consequently into the branch that revision resides in).

If the given branch doesn't exist, it is created automatically.  If the
branch already exists, any missing files are dropped and any unknown
files are added before committing.

If @command{--dry-run} is given, no commit is done.
@end ftable



@page
@node    Workspace
@section Workspace

@ftable @command
@item mtn setup [@var{directory}]
This command prepares @var{directory} as a monotone workspace,
by creating and populating the @file{_MTN} directory with basic
information.  This information must include at least the branch and the
database to be used, both of which will be placed in the
@file{_MTN/options} file.

This can be used with an empty directory to start a new blank project,
or within an existing directory full of files, prior to using
@command{mtn commit}. If no directory is specified, the current
directory is used.


@item mtn add @var{pathname...}
@item mtn add --unknown
This command places ``add'' entries for the paths specified in
@var{pathname...} in the workspace's ``work list''. The work list of
your workspace is stored in @file{_MTN/revision}, and is a list of
explicit pathname changes you wish to commit at some future time, such
as addition, removal or renaming of files.

As a convenience, the @option{--unknown} option can be used; this
option will cause all of the files listed by @command{mtn list
unknown} to be added.

While this command places an ``add'' entry on your work list, it does
not immediately affect your database. When you @command{commit} your
workspace, monotone will use the work list to build a new revision,
which it will then commit to the database. The new revision will have
any added entries inserted in its manifest.

@item mtn [--no-respect-ignore] mkdir @var{directory...}
This command creates a directory in the filesystem relative to your
current location and adds it to your workspace's ``work list''.  The
changes are not reflected in your database until such time as you
perform a commit.  If you use the @option{--no-respect-ignore} flag,
entries in .mtn-ignore will not be honored.

@item mtn [--bookkeep-only] drop @var{pathname...}
@itemx mtn drop --missing
This command places ``drop'' entries for the paths specified in
@var{pathname...} in the workspace's ``work list'' and deletes
the file from the workspace. The work list of
your workspace is stored in @file{_MTN/revision}, and is a list of
explicit pathname changes you wish to commit at some future time, such
as addition, removal, or renaming of files.  This command also removes
any attributes on @var{pathname}; see @ref{File Attributes} for more
details.  If you use the @option{--missing} flag it will add drop
entries for any paths that monotone is tracking for which you have
already removed the files from the filesystem, in addition to all those
specified in @var{pathname...}.

While this command places a ``drop'' entry on your work list, it does
not immediately affect your database. When you @command{commit} your
workspace, monotone will use the work list to build a new revision,
which it will then commit to the database. The new revision will have
any dropped entries removed from its manifest.

There are situations in which @command{drop} will tell monotone
to remove the file from the revision at commit time, but where it will
@emph{not} to remove the file from the workspace immediately.  One
is if the @option{--bookkeep-only} option is supplied.  Another is
if a file has un-committed changes or if a directory is not empty.

@item mtn [--bookkeep-only] rename @var{src} @var{dst}
@item mtn [--bookkeep-only] mv @var{src} @var{dst}
@itemx mtn [--bookkeep-only] rename @var{src1} @var{...} @var{dst/}
@itemx mtn [--bookkeep-only] mv @var{src1} @var{...} @var{dst/}
This command places ``rename'' entries for the paths specified in
@var{src} and @var{dst} in the workspace's ``work list''. The second form
renames a number of source paths to the given destination. The work
list of your workspace is stored in @file{_MTN/revision}, and is a list of
explicit pathname changes you wish to commit at some future time, such
as addition, removal, or renaming of files.  This command also moves any
attributes on @var{src} to @var{dst}; see @ref{File Attributes} for more
details, and, unless the @option{--bookkeep-only} option is supplied, it
will rename the files immediately in the filesystem.

@item mtn commit
@item mtn ci
@itemx mtn commit --message=@var{logmsg} [--message=@var{logmsg}...]
@itemx mtn ci --message=@var{logmsg} [--message=@var{logmsg}...]
@itemx mtn commit --message-file=@var{logfile}
@itemx mtn ci --message-file=@var{logfile}
@itemx mtn commit @var{pathname...}
@itemx mtn ci @var{pathname...}
@itemx mtn commit --message=@var{logmsg} [--message=@var{logmsg}...] @var{pathname...} 
@itemx mtn ci --message=@var{logmsg} [--message=@var{logmsg}...] @var{pathname...} 
@itemx mtn commit --message-file=@var{logfile} @var{pathname...} 
@itemx mtn ci --message-file=@var{logfile} @var{pathname...} 

This command looks at your workspace, decides which files have
changed, and saves the changes to your database. It does this by
loading the revision named in @file{_MTN/revision}, locating the base
manifest for your workspace, applying any pathname changes described
in @file{_MTN/revision}, and then comparing the updated base manifest
to the files it finds in your workspace, to determine which files have
been edited.

For each edited file, a delta is copied into the database. Then the
newly constructed manifest is recorded (as a delta) and finally the
new revision.  Once all these objects are recorded in you database,
@command{commit} updates @file{_MTN/revision} to indicate that the base
revision is now the newly created revision, and that there are no
pathname changes to apply.

Specifying pathnames to @command{commit} restricts the set of changes
that are visible and results in only a partial commit of the workspace.
Changes to files not included in the specified set of pathnames will be
ignored and will remain in the workspace until they are included in a
future commit. With a partial commit, only the relevant entries in
@file{_MTN/revision} will be removed and other entries will remain for
future commits.

From within a subdirectory of the workspace the @command{commit} command
will, by default, include @emph{all changes} in the workspace.
Specifying only the pathname "." will restrict @command{commit} to files
changed within the current subdirectory of the workspace.

The @option{--message} and @option{--message-file} options are mutually
exclusive.  Both provide a @var{logmsg} describing the commit. 
@option{--message-file} actually specifies the name of the file containing
the log message, while @option{--message} provides it directly.

Multiple @option{--message} options may be provided on the command line.
The log message will be formed by concatenating the @option{--message}
options provided, with each one starting at the beginning of a new line.

The @file{_MTN/log} file can be edited by the user during their daily
work to record the changes made to the workspace. When running the
@command{commit} command without a @var{logmsg} supplied, the contents of
the @file{_MTN/log} file will be read and passed to the Lua hook
@code{edit_comment} as a second parameter named @var{user_log_content}.
The log message will be prepended with a 'magic' string that must be
removed to confirm the commit.  This allows the user to easily cancel a
commit, without emptying the entire log message.  If the commit is
successful, the @file{_MTN/log} file is cleared of all content making it
ready for another edit/commit cycle.

If a @option{--branch} option is specified, the @command{commit} command
commits to this branch (creating it if necessary).  The branch becomes
the new default branch of the workspace.

The @command{commit} command also synthesizes a number of
certificates, which it attaches to the new manifest version and copies
into your database:
@itemize
@item 
An @code{author} cert, indicating the person responsible for the changes
leading to the new revision.  Normally this defaults to your signing key
or the return value of the @code{get_author} hook; you may override this
by passing the @option{--author} option to commit.  This is useful when
committing a patch on behalf of someone else, or when importing ``by
hand'' from another version control system.
@item 
A @code{branch} cert, indicating the branch the committed revision
belongs to.
@item
A @code{date} cert, indicating when the new revision was created.
Normally this defaults to the current time; you may override this by
passing the @option{--date} option to commit.  This is useful when
importing ``by hand'' from another version control system.
@item
A @code{changelog} cert, containing the ``log message'' for these
changes.  If you provided @var{logmsg} on the command line, this text
will be used, otherwise @command{commit} will run the Lua hook
@code{edit_comment (@var{commentary}, @var{user_log_content})}, which
typically invokes an external editor program, in which you can compose
and/or review your log message for the change.
@end itemize

@item mtn revert @var{pathname...}
@itemx mtn revert --missing @var{pathname...}
This command changes your workspace, so that changes you have made
since the last checkout or update are discarded. The command is
restricted the set of files or directories given as arguments.  To
revert the entire workspace, use @command{revert} "." in the
top-level directory. Specifying "." in a subdirectory will restrict
@command{revert} to files changed within the current subdirectory.

If the flag @option{--missing} is given it reverts (ie, restores) any
files which monotone has listed in its manifest, but which have been
deleted from the workspace.  Only missing files matching the given
file or directory arguments are reverted.

@item mtn update
@itemx mtn update --revision=@var{revision}
Without a @option{--revision} argument, this command incorporates
``recent'' changes found in your database into your workspace. It
does this by performing 3 separate stages. If any of these stages
fails, the update aborts, doing nothing. The stages are:

@itemize
@item
Examine the ancestry graph of revisions in your database, and (subject
to trust evaluation) select the set of all descendants of your
workspace's base revision. Call this set the ``candidates'' of the
update.
@item
Remove any candidates which lack acceptable testresult
certificates. From the remaining candidates, select the deepest child
by ancestry and call it the ``target'' of the update.
@item 
Merge the target of the update with the workspace, in memory, and
if the merge is successful, write the result over top of the workspace.
@end itemize

With an explicit @option{--revision} argument, the command uses that revision
as the update target instead of finding an acceptable candidate.

The effect is always to take whatever changes you have made in the
workspace, and to ``transpose'' them onto a new revision, using
monotone's 3-way merge algorithm to achieve good results.  Note that
with the explicit @option{--revision} argument, it is possible to update
``backwards'' or ``sideways'' in history --- for example, reverting to
an earlier revision, or if your branch has two heads, updating to the
other.  In all cases, the end result will be whatever revision you
specified, with your local changes (and only your local changes)
applied.

If a @option{--branch} option is specified, the @command{update} command
tries to select the revision to update to from this branch.  The branch
becomes the new default branch of the workspace (even if you also
specify an explicit @option{--revision} argument).

When running @command{update}, it is sometimes possible for
@ref{Workspace Collisions} to occur.

@item mtn pluck --revision=@var{to}
@itemx mtn pluck --revision=@var{from} --revision=@var{to}

This command takes changes made at any point in history, and attempts to
edit your current workspace to include those changes.  The end result is
identical to running @command{mtn diff @option{-r} @var{from}
@option{-r} @var{to} | patch @option{-p0}}, except that this command
uses monotone's merger, and thus intelligently handles renames,
conflicts, and so on.

If only one revision is given, applies the changes made in @var{to} as
compared with @var{to}'s parent.  If two revisions are given, applies
the changes made to get from @var{from} to @var{to}.

Note that this is not a true cherrypick operation.  A true cherrypick,
as that word is used in version control theory, involves applying some
changes out of context, and then recording the identity between the
original changes and the newly applied changes for the use of later
merges.  This command does the first part, not the second.  As far as
monotone is concerned, the changes made by @command{mtn pluck} are
exactly like those made in an editor; the command is simply a
convenient way to make certain edits quickly.  In practice, this is
rarely a problem.  @command{mtn pluck} should almost always be used
between branches that will never be merged --- for instance,
backporting fixes from a development branch to a stable branch.

When you use @command{pluck} you are going behind monotone's back, and
reducing its ability to help you keep track of what has happened in
your history.  Never use @command{pluck} where a true merging command
like @command{merge}, @command{propagate}, or @command{explicit_merge}
will do.  If you find yourself using @command{pluck} often, you should
consider carefully whether there is any way to change your workflow to
reduce your need for @command{pluck}ing.

When running @command{pluck}, it is sometimes possible for
@ref{Workspace Collisions} to occur.

@item mtn refresh_inodeprints
This command puts the current workspace into @ref{Inodeprints} mode,
if it was not already, and forces a full inodeprints cache refresh.
After running this command, you are guaranteed that your workspace is
in inodeprints mode, and that the inodeprints cache is accurate and up
to date.

@item mtn pivot_root [--bookkeep-only] pivot_root @var{new_root} @var{put_old}
Most users will never need this command.  It is primarily useful in
certain tricky cases where one wishes to combine several projects
into one, or split one project into several. See also @command{merge_into_dir}.

Its effect is to rename the directory whose name is currently
@var{new_root} to become the root directory of the versioned tree, and
to at the same time rename the directory that is currently the root of
the versioned tree to have the name @var{put_old}.  Conceptually, it
is equivalent to executing the following commands in the root of the
workspace:

@smallexample
@group
$ mtn rename . @var{new_root}/@var{put_old}
$ mtn rename @var{new_root} .
@end group
@end smallexample

Except, of course, that these @command{rename} commands are illegal,
because after the first command the tree has no root at all, and there
is a directory loop.  This illegality is the only reason for
@command{pivot_root}'s existence; internally, the result is treated
exactly like two renames, including with respect to merges and
updates.

The use of @option{--bookkeep-only} with this command is not
recommended.  It causes the changes to be made in monotone's
records, but not in the filesystem itself.

When running @command{pivot_root}, it is sometimes possible for
@ref{Workspace Collisions} to occur.

@end ftable

@page
@node    Network
@section Network

@ftable @command
@item mtn serve [--bind=[@var{address}][:@var{port}]]
@item mtn serve --stdio [--no-transport-auth]
@itemx mtn pull [--set-default] [@var{uri-or-address}] [@var{glob} [...] [--exclude=@var{exclude-glob}]]]
@itemx mtn push [--set-default] [@var{uri-or-address}] [@var{glob} [...] [--exclude=@var{exclude-glob}]]]
@itemx mtn sync [--set-default] [@var{uri-or-address}] [@var{glob} [...] [--exclude=@var{exclude-glob}]]]

These commands operate the ``netsync'' protocol built into
monotone. This is a custom protocol for rapidly synchronizing two
monotone databases using a hash tree index. The protocol is ``peer to
peer'', but requires one peer to listen for incoming connections (the
server) and the other peer (the client) to connect to the server. When
run with @option{--stdio}, the server listens for a single connection
then terminates. When run with @option{--bind}, or with neither
option, the server listens for TCP connections and serves them
continuously, until it is shut down.

The network @var{address} given to @command{serve} as an argument to
@option{--bind} should be a host name to listen on, optionally
followed by a colon and a port number. The default port number is
4691. If no @option{--bind} option is given, the server listens on
port 4691 of every network interface.

If @command{serve} is run with @option{--stdio}, a single netsync
session is served over the @code{stdin} and @code{stdout} file
descriptors. If @option{--no-transport-auth} is provided along with
@option{--stdio}, transport authentication and access control mechanisms
are disabled. Only use @option{--no-transport-auth} if you are certain 
that the transport channel in use already provides sufficient 
authentication and authorization facilities. 

The @var{uri-or-address} arguments given to @command{push},
@command{pull}, and @command{sync} can be of two possible forms. If
the argument is a URI, a Lua hook may transform the URI into a
connection command, and execute the command as a transport channel for
netsync. If the argument is a simple hostname (with optional port
number), monotone will use a TCP socket to the specified host and port
as a transport channel for netsync.

The @var{glob} parameters indicate a set of branches to exchange.
Multiple @var{glob} and @option{--exclude} options can be specified;
every branch which matches a @var{glob} exactly, and does not match an
@var{exclude-glob}, will be indexed and made available for
synchronization.

For example, perhaps Bob and Alice wish to synchronize their
@code{net.venge.monotone.win32} and @code{net.venge.monotone.i18n}
branches. Supposing Alice's computer has hostname
@code{alice.someisp.com}, then Alice might run:

@smallexample
@group
$ mtn --bind=alice.someisp.com serve
@end group
@end smallexample

And Bob might run

@smallexample
@group
$ mtn sync alice.someisp.com "net.venge.monotone*"
@end group
@end smallexample

When the operation completes, all branches matching
@code{net.venge.monotone*} will be synchronized between Alice and Bob's
databases.

The @command{pull}, @command{push}, and @command{sync} commands only
require you pass @var{address} and @var{glob} the first time you use one
of them; monotone will memorize this use and in the future default to
the same server and glob.  For instance, if Bob wants to @command{sync}
with Alice again, he can simply run:

@smallexample
@group
$ mtn sync
@end group
@end smallexample

Of course, he can still @command{sync} with other people and other
branches by passing an address or address plus globs on the command
line; this will not affect his default affinity for Alice.  If you ever
do want to change your defaults, simply pass the @option{--set-default}
option when connecting to the server and branch pattern that you want to
make the new default.

In the server, different permissions can be applied to each branch; see
the hooks @code{get_netsync_read_permitted} and
@code{get_netsync_write_permitted} (see @ref{Hook Reference}).

If a @option{--pid-file} option is specified, the command
@command{serve} will create the specified file and record the process
identifier of the server in the file.  This file can then be read to
identify specific monotone server processes.

The syntax for patterns is very simple.  @code{*} matches 0 or more
arbitrary characters.  @code{?} matches exactly 1 arbitrary character.
@code{@{foo,bar,baz@}} matches ``foo'', or ``bar'', or ``baz''.  These
can be combined arbitrarily.  A backslash, @code{\}, can be prefixed to
any character, to match exactly that character --- this might be useful
in case someone, for some odd reason, decides to put a ``*'' into their
branch name.

@end ftable



@page
@node    Informative
@section Informative

@ftable @command
@item mtn status
@itemx mtn status @var{pathname...}

This command prints a description of the ``status'' of your workspace.
In particular, it prints:
@itemize
@item 
The branch currently selected in @file{_MTN/options} for the
workspace.
@item
The revision id of the ``parent'' revision of the workspace, on which
your in-progress changes are based.
@item
A list of logical changes between the base and current manifest
versions, such as adds, drops, renames, and patches.
@end itemize

Specifying optional @var{pathname...} arguments to the @command{status}
command restricts the set of changes that are visible and results in
only a partial status of the workspace. Changes to files not included
in the specified set of pathnames will be ignored.

From within a subdirectory of the workspace the @command{status} command
will, by default, include @emph{all changes} in the workspace.
Specifying only the pathname "." will restrict @command{status} to files
changed within the current subdirectory of the workspace.

@item mtn log
@itemx mtn log [--last=@var{n}] [--next=@var{n}] [--from=@var{id} [...]] [--to=@var{id} [...]] [--brief] [--no-merges] [--no-files] [--diffs] [@var{file} [...]]

This command prints out a log, in reverse-ancestry order, of small
history summaries.  Each summary contains author, date, changelog and
comment information associated with a revision.

If @option{--brief} is given, the output consists of one line per revision
with the revision ID, the author, the date and the branches (separated
with commas).

If @option{--last=}@var{n} is given, at most @var{n} log entries will be
given.

If @option{--next=}@var{n} is given, at most @var{n} log entries towards
the current head revision will be given from the workspace's base
revision in forward-ancestry order.  This is useful to review changes
that will be applied to the workspace when @command{update} is run.

If @option{--from=}@var{id} is given, the command starts tracing back through 
history from these revisions, otherwise it starts from the base revision of 
your workspace.

If @option{--to=}@var{id} is given, log will only print entries for revisions
that would not also be printed when logging from the revisions specified in
@option{--to}. This is useful for reviewing changes between two points
in history.

By default, the log entries for merge nodes are shown.  If
@option{--no-merges} is given, the log entries for these nodes will be
excluded.

If @option{--no-files} is given, the log output excludes the list of
files changed in each revision.

Specifying @option{--diffs} causes the log output to include a unified
diff of the changes in each revision.

If one or more files are given, the command will only log the revisions
where those files are changed.

@item mtn annotate @var{file}
@itemx mtn annotate [--revision=@var{id}] [--brief] @var{file}

Dumps an annotated copy of the file to stdout.  In the absence of the 
@option{--brief} flag, each line of the file
is translated to <revision id>: <line> in the output, where <revision id>
is the revision in which that line of the file was last edited.

If @option{--brief} is specified, the output is in the form
<short revision id>.. by <author> <date>: <line>
Only the first 8 characters of the revision id are displayed, the  
author cert value is truncated at the first @code{@@} or space
character and the date field is truncated to remove the time of day.

@item mtn complete file @var{partial-id}
@itemx mtn complete [--brief] key @var{partial-id}
@itemx mtn complete [--brief] revision @var{partial-id}

These commands print out all known completions of a partial @sc{sha1}
value, listing completions which are @code{file}, @code{manifest} or
@code{revision} IDs depending on which variant is used. For
example, suppose you enter this command and get this result:

@smallexample
@group
$ mtn complete revision fa36
fa36deead87811b0e15208da2853c39d2f6ebe90
fa36b76dd0139177b28b379fe1d56b22342e5306
fa36965ec190bee14c5afcac235f1b8e2239bb2a
@end group
@end smallexample

Then monotone is telling you that there are 3 revisions it knows
about, in its database, which begin with the 4 hex digits
@code{fa36}. This command is intended to be used by programmable
completion systems, such as those in @command{bash} and @command{zsh}.

The complete command for keys and revisions have a @option{--verbose} option.
Programmable completion systems can use @option{--verbose} output to 
present users with additional information about each completion option.

For example, verbose output for @code{revision} looks like this:
@smallexample
@group
$ mt complete revision 01f
01f5da490941bee1f0000f0561fc62eabfb2fa23 graydon@@dub.net 2003-12-03T03:14:35
01f992577bd8bcdcade0f89e724fd5dc2d2bbe8a kinetik@@orcon.nz 2005-05-11T05:19:29
01faad191d8d0474777c70b4d606782942333a78 kinetik@@orcon.nz 2005-04-11T04:24:01
@end group
@end smallexample

@item mtn diff [--unified] [--show-encloser]
@itemx mtn diff --context [--show-encloser]
@itemx mtn diff --external [--diff-args=@var{argstring}]
@itemx mtn diff @var{pathname...}
@itemx mtn diff --revision=@var{id}
@itemx mtn diff --revision=@var{id} @var{pathname...}
@itemx mtn diff --revision=@var{id1} --revision=@var{id2}
@itemx mtn diff --revision=@var{id1} --revision=@var{id2} @var{pathname...}

These commands print out GNU ``unified diff format'' textual difference
listings between various manifest versions. With no @option{--revision}
options, @command{diff} will print the differences between the
base revision and the current revision in the workspace.

With one @option{--revision} option, @command{diff} will print the
differences between the revision @var{id} and the current revision in
the workspace.  With two @option{--revision} options @command{diff}
will print the differences between revisions @var{id1} and @var{id2},
ignoring any workspace.

In all cases, monotone will print a textual summary -- identical to
the summary presented by @command{mtn status} -- of the logical
differences between revisions in lines proceeding the diff. These
lines begin with a single hash mark @code{#}, and should be ignored by
a program processing the diff, such as @command{patch}.

Specifying pathnames to the @command{diff} command restricts the set of
changes that are visible and results in only a partial diff between
two revisions. Changes to files not included in the specified set of
pathnames will be ignored.

From within a subdirectory of the workspace the @command{diff} command
will, by default, include @emph{all changes} in the workspace.
Specifying only the pathname "." will restrict @command{diff} to files
changed within the current subdirectory of the workspace.

The output format of @command{diff} is controlled by the options
@option{--unified}, @option{--context}, @option{--show-encloser}, and
@option{--external}.  By default, monotone uses its built-in diff
algorithm to produce a listing in ``unified diff'' format (analogous
to running the program @command{diff @option{-u}}); you can also explicitly
request this with @option{--unified}.  The built-in diff algorithm can
also produce ``context diff'' format (analogous to @command{diff @option{-c}}),
which you request by specifying @option{--context}.  The short options
that @command{diff} accepts for these modes, @option{-u} and
@option{-c}, also work.

In either of these modes, you can request that monotone print the name
of the top-level code construct that encloses each ``hunk'' of
changes, with @option{--show-encloser}.  The options that
@command{diff} accepts for this mode, @option{-p} and
@option{--show-c-function}, also work.  Monotone finds the enclosing
construct by scanning backward from the first changed line in each
hunk for a line that matches a regular expression.  The default
regular expression is correct for many programming languages.  You can
adjust the expression used with the Lua hook
@code{get_encloser_pattern}; @ref{Hooks}.


@option{--unified} requests the ``unified diff'' format, the default.
@option{--context} requests the ``context diff'' format (analogous to
running the program @command{diff @option{-c}}).  Both of these formats are
generated directly by monotone, using its built-in diff algorithm.

Sometimes, you may want more flexibility in output formats; for these
cases, you can use @option{--external}, which causes monotone to invoke
an external program to generate the actual output.  By default, the
external program is @code{diff}, and you can use the option
@option{--diff-args} to pass additional arguments controlling
formatting.  The actual invocation of @command{diff}, default arguments
passed to it, and so on, are controlled by the hook
@code{external_diff}; see @ref{Hooks} for more details.

@item mtn list certs @var{id}
@item mtn ls certs @var{id}

These commands will print out a list of certificates associated with
a particular revision @var{id}. Each line of the print out will
indicate:
@itemize
@item
Whether the signature on the certificate is @code{ok} or @code{bad}
@item
The key ID of the signer of the certificate
@item 
The name of the certificate
@item 
The value of the certificate
@end itemize

For example, this command lists the certificates associated with a
particular version of monotone itself, in the monotone development
branch:

@smallexample
@group
$ mtn list certs 4a96
mtn: expanding partial id '4a96'
mtn: expanded to '4a96a230293456baa9c6e7167cafb3c5b52a8e7f'
-----------------------------------------------------------------
Key   : graydon@@pobox.com
Sig   : ok
Name  : author
Value : graydon@@dub.venge.net
-----------------------------------------------------------------
Key   : graydon@@pobox.com
Sig   : ok
Name  : branch
Value : monotone
-----------------------------------------------------------------
Key   : graydon@@pobox.com
Sig   : ok
Name  : date
Value : 2003-10-17T03:20:27
-----------------------------------------------------------------
Key   : graydon@@pobox.com
Sig   : ok
Name  : changelog
Value : 2003-10-16  graydon hoare  <graydon@@pobox.com>
      :
      :         * sanity.hh: Add a const version of idx().
      :         * diff_patch.cc: Change to using idx() everywhere.
      :         * cert.cc (find_common_ancestor): Rewrite to recursive
      :         form, stepping over historic merges.
      :         * tests/t_cross.at: New test for merging merges.
      :         * testsuite.at: Call t_cross.at.
      :
@end group
@end smallexample

@item mtn list keys
@item mtn ls keys
@itemx mtn list keys @var{pattern}
@itemx mtn ls keys @var{pattern}
These commands list @sc{rsa} keys held in your keystore and current database.
They do not print out any cryptographic information; they simply list the
names of public and private keys you have on hand.

If @var{pattern} is provided, it is used as a glob to limit the keys
listed. Otherwise all keys in your database are listed.

@item mtn list branches
@item mtn ls branches

This command lists all known branches in your database.

@item mtn list tags
@item mtn ls tags

This command lists all known tags in your database.

@item mtn list vars
@item mtn ls vars
@item mtn list vars @var{domain}
@item mtn ls vars @var{domain}

This command lists all vars in your database, or all vars within a given
@var{domain}.  See @ref{Vars} for more information.

@item mtn list known
@item mtn ls known
@itemx mtn list known @var{pathname...}
@itemx mtn ls known @var{pathname...}

This command lists all files which would become part of the manifest of
the next revision if you committed your workspace at this point.

Specifying pathnames to the @command{list known} command restricts
the set of paths that are searched for manifest files. Files not
included in the specified set of pathnames will not be listed.

From within a subdirectory of the workspace the @command{list
known} command will, by default, search the entire workspace.
Specifying only the pathname "." will restrict the search for known
files to the current subdirectory of the workspace.

@item mtn list unknown
@item mtn ls unknown
@itemx mtn list unknown @var{pathname...}
@itemx mtn ls unknown @var{pathname...}

This command lists all files in your workspace that monotone is 
either ignoring or knows nothing about.

Specifying pathnames to the @command{list unknown} command restricts the
set of paths that are searched for unknown files. Unknown files not
included in the specified set of pathnames will not be listed.

From within a subdirectory of the workspace the @command{list
unknown} command will, by default, search the entire workspace.
Specifying only the pathname "." will restrict the search for unknown
files to the current subdirectory of the workspace.

@item mtn list ignored
@item mtn ls ignored
@itemx mtn list ignored @var{pathname...}
@itemx mtn ls ignored @var{pathname...}

This command lists all files in your workspace that monotone is
intentionally ignoring, due to the results of the @code{ignore_file
(@var{filename})} hook.

Specifying pathnames to the @command{list ignored} command restricts the
set of paths that are searched for ignored files. Ignored files not
included in the specified set of pathnames will not be listed.

From within a subdirectory of the workspace the @command{list
ignored} command will, by default, search the entire workspace.
Specifying only the pathname "." will restrict the search for ignored
files to the current subdirectory of the workspace.

@item mtn list missing
@item mtn ls missing
@itemx mtn list missing @var{pathname...}
@itemx mtn ls missing @var{pathname...}

This command lists all files in your workspace's base manifest,
which are not present in the workspace.

Specifying pathnames to the @command{list missing} command restricts the
set of paths that are searched for missing files. Missing files not
included in the specified set of pathnames will not be listed.

From within a subdirectory of the workspace the @command{list
missing} command will, by default, search the entire workspace.
Specifying only the pathname "." will restrict the search for missing
files to the current subdirectory of the workspace.

@item mtn list changed
@item mtn ls changed
@itemx mtn list changed @var{pathname...}
@itemx mtn ls changed @var{pathname...}

This command lists all files in your workspace that have changed
compared to the base revision, including files that are dropped, added
or renamed.

Specifying pathnames to the @command{list changed} command restricts
the set of paths that are checked for changes. Files not included in the
specified set of pathnames will not be listed.

From within a subdirectory of the workspace the @command{list
changed} command will, by default, search the entire workspace.
Specifying only the pathname "." will restrict the search for known
files to the current subdirectory of the workspace.

@item mtn show_conflicts @var{rev} @var{rev}

This command shows what conflicts would need to be resolved in order to merge
the given revisions.
@end ftable


@page
@node    Key and Cert Trust
@section Key and Cert Trust

@ftable @command
@item mtn genkey @var{keyid}

This command generates an @sc{rsa} public/private key pair, using a
system random number generator, and stores it in your keystore under
the key name @var{keyid}.

The private half of the key is stored in an encrypted form, so that anyone
who can read your keystore cannot extract your private key and use it.
You must provide a passphrase for your key when it is generated, which is used
to determine the encryption key. In the future you will need to enter this
passphrase again each time you sign a certificate, which happens every
time you @command{commit} to your database. You can tell monotone to
automatically use a certain passphrase for a given key using the
@code{get_passphrase(@var{keypair_id})}, but this significantly
increases the risk of a key compromise on your local computer. Be
careful using this hook.

@item mtn dropkey @var{keyid}

This command drops the public and/or private key. If both exist, both
are dropped, if only one exists, it is dropped. This command should
be used with caution as changes are irreversible without a backup of
the key(s) that were dropped.

@item mtn passphrase @var{id}

This command lets you change the passphrase of the private half of the
key @var{id}.

@item mtn trusted @var{id} @var{certname} @var{certval} @var{signers}

This command lets you test your revision trust hook
@code{get_revision_cert_trust} (see @ref{Hook Reference}).  You pass it
a revision ID, a certificate name, a certificate value, and one or more
key IDs, and it will tell you whether, under your current settings,
Monotone would trust a cert on that revision with that value signed by
those keys.

@item mtn ssh_agent_export @var{filename}

This command will export your private key in a format that ssh-agent
can read (PKCS8, PEM). You will be asked for your current key's password
and a new password to encrypt the key with. The key will be printed to
stdout. Once you have put this key in a file simply add it to ssh-agent
and you will only have to enter your key password once as ssh-agent
will cache the key for you.

@smallexample
@group
$ mtn ssh_agent_export ~/.ssh/id_monotone
enter passphrase for key ID [user@@example.com]:
enter new passphrase for key ID [user@@example.com]:
confirm passphrase for key ID [user@@example.com]:
$ chmod 600 ~/.ssh/id_monotone
$ ssh-agent /bin/bash
$ ssh-add ~/.ssh/id_monotone
Enter passphrase for /home/user/.ssh/id_monotone:
Identity added: /home/user/.ssh/id_monotone (/home/user/.ssh/id_monotone)
$ mtn ci -m"Changed foo to bar"
$ mtn push
@end group
@end smallexample

You can also use the @option{--ssh-sign} option to control whether ssh-agent will
be used for signing. If set to @emph{yes}, ssh-agent will be used to sign. If your
key has not been added to ssh-agent monotone will fall back to its internal signing
code and ask you for your password. If set to @emph{only}, monotone will sign only
with ssh-agent. If set to @emph{no}, monotone will always use its internal signing
code even if ssh-agent is running and has your monotone key loaded. If set to
@emph{check}, monotone will sign with both ssh-agent (if your key is loaded into
it) and monotone's internal signing code, then compare the results. @emph{check}
will be removed at some future time as it is meant only for testing and will not
work with all signing algorithms.


@end ftable



@page
@node    Certificate
@section Certificate

@ftable @command
@item mtn cert @var{id} @var{certname} 
@itemx mtn cert @var{id} @var{certname} @var{certval}

These commands create a new certificate with name @var{certname}, for a
revision with version @var{id}.  The @var{id} argument can be a selector
using certs already on the revision, such as @code{h:@var{branchname}}.

If @var{certval} is provided, it is the value of the certificate.
Otherwise the certificate value is read from @code{stdin}.

@item mtn approve @var{id}

This command is a synonym for @command{mtn cert @var{id} branch
@var{branchname}} where @var{branchname} is the current branch name
(either deduced from the workspace or from the @option{--branch}
option).


@item mtn comment @var{id}
@itemx mtn comment @var{id} @var{comment}

These commands are synonyms for @command{mtn cert @var{id}
comment @var{comment}}. If @var{comment} is not provided, it is read
from @code{stdin}.


@item mtn tag @var{id} @var{tagname}

This command associates the symbolic name @var{tagname} with the
revision @var{id}, so that symbolic name can later be used in
@ref{Selectors} for specifying revisions for commands like
@command{update} or @command{diff}.  

This command is a synonym for @command{mtn cert @var{id} tag
@var{tagname}}.

@item mtn testresult @var{id} 0
@itemx mtn testresult @var{id} 1

These commands are synonyms for @command{mtn cert @var{id}
testresult 0} or @command{mtn cert @var{id} testresult 1}.

@end ftable



@page
@node    Packet I/O
@section Packet I/O

Monotone can produce and consume data in a convenient, portable form
called @dfn{packets}. A packet is a sequence of ASCII text, wrapped at
70-columns and easily sent through email or other transports. If you
wish to manually transmit a piece of information -- for example a
public key -- from one monotone database to another, it is often
convenient to read and write packets.

@emph{Note:} earlier versions of monotone queued and replayed packet
streams for their networking system. This older networking system has
been removed, as the netsync protocol has several properties which
make it a superior communication system. However, the packet I/O
facility will remain in monotone as a utility for moving individual
data items around manually.

@ftable @command
@itemx mtn automate packets_for_certs @var{id}

This command prints out an @code{rcert} packet for each cert in your
database associated with @var{id}. These can be used to transport
certificates safely between monotone databases.  See @ref{Automation}
for details of this command.

@item mtn automate packet_for_fdata @var{id}
@itemx mtn automate packet_for_rdata @var{id}

These commands print out an @code{fdata} or @code{rdata} packet for
the file, manifest or revision @var{id} in your database.  These can
be used to transport files or revisions, in their entirety, safely
between monotone databases.  See @ref{Automation} for details of these
commands.

@item mtn automate packet_for_fdelta @var{id1} @var{id2}

This command prints out an @code{fdelta} packet for the differences
between file versions @var{id1} and @var{id2}, in your database.
These can be used to transport file differences safely between
monotone databases.  See @ref{Automation} for details of this
command.

@item mtn privkey @var{keyid}
@itemx mtn pubkey @var{keyid}

These commands print out an @code{keypair} or @code{pubkey} packet for
the @sc{rsa} key @var{keyid}. These can be used to transport public or
private keys safely between monotone databases.


@item mtn read
@item mtn read @var{file1} @var{file2...}

This command reads packets from files or @code{stdin} and stores them
in your database.

@end ftable


@page
@node    Database
@section Database

@ftable @command
@item mtn set @var{domain} @var{name} @var{value}

Associates the value @var{value} to @var{name} in domain @var{domain}.
See @ref{Vars} for more information.

@item mtn unset @var{domain} @var{name}

Deletes any value associated with @var{name} in @var{domain}.  See
@ref{Vars} for more information.

@item mtn db init --db=@var{dbfile} 

This command initializes a new monotone database at @var{dbfile}.

@item mtn db info --db=@var{dbfile} 

This command prints information about the monotone database @var{dbfile},
including its schema version and various table size statistics.

@item mtn db version --db=@var{dbfile} 

This command prints out just the schema version of the monotone
database @var{dbfile}.

@item mtn db dump --db=@var{dbfile} 

This command dumps an SQL statement representing the entire state of
@var{dbfile} to the standard output stream. It is a very low-level
command, and produces the most ``recoverable'' dumps of your database
possible. It is sometimes also useful when migrating databases between
variants of the underlying SQLite database format.

@item mtn db load --db=@var{dbfile} 

This command applies a raw SQL statement, read from the standard input
stream, to the database @var{dbfile}. It is most useful when loading
a database dumped with the @command{dump} 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}.

@item mtn db migrate --db=@var{dbfile} 

This command attempts to migrate the database @var{dbfile} to the
newest schema known by the version of monotone you are currently
running.  If the migration fails, no changes should be made to the
database.

If you have important information in your database, you should back up
a copy of it before migrating, in case there is an untrapped error
during migration.

@item mtn db check --db=@var{dbfile} 

Monotone always works hard to verify the data it creates and accesses.
For instance, if you have hard drive problems that corrupt data in
monotone's database, and you attempt to retrieve this data, then
monotone will notice the problem and stop, instead of silently giving
you garbage data.

However, it's also nice to notice such problems early, and in rarely
used parts of history, while you still have backups.  That's what this
command is for.  It systematically checks the database @var{dbfile} to
ensure that it is complete and consistent. The following problems are
detected:

@itemize

@item missing files 
that are referenced by their @sc{sha1} hash from some manifest but do not
exist in the database.  This is a serious problem; it means that your
history is not fully reconstructible.  You can fix it by finding the
file with the given hash, and loading it into your database with
@command{fload}.

@item unreferenced files
that exist in the database but are not referenced by their @sc{sha1}
hash from any existing manifest.  In itself, this only indicates some
wasted space, and is not a problem; it's possible it could arise under
normal use (for instance, in some strange corner cases following an
incomplete netsync).  It could also arise, though, as a symptom of some
other more serious problem.

@item missing manifests
that are referenced by their @sc{sha1} hash from some revision but do
not exist in the database.  This is a serious problem; it means that
your history is not fully reconstructible.  You can fix it by finding a
database containing the manifest, and using @command{mdata} on that
database to create a manifest data packet, which can be loaded into your
database with @command{read}.

@item unreferenced manifests
that exist in the database but are not referenced by their @sc{sha1}
hash from any existing revision.  In itself, this only indicates some
wasted space, and is not a problem; it's possible it could arise under
normal use (for instance, if you have run @command{db kill_rev_locally},
or in some strange-but-harmless corner cases following an incomplete
netsync).  It could also arise, though, as a symptom of some other more
serious problem.

@item incomplete manifests
that exist in the database but contain references to files that do not
exist in the database.  For diagnosis and solution, see ``missing
files'' above.

@item missing revisions
that are referenced by their @sc{sha1} hash from some other revision or
revision cert but do not exist in the database.  This may be a serious
problem; it may indicate that your history is not fully reconstructible
(if the reference is from another revision) or that someone is creating
bogus certs (if the reference is from a cert).  You can fix it by
finding a database containing the revision, and using @command{rdata} on
that database to create a revision data packet, which can be loaded into
your database with @command{read}.

@item incomplete revisions
that exist in the database but contain references to missing manifests,
incomplete manifests or missing revisions.  This always occurs with some
more detailed error; see above.

@item revisions with mismatched parents
that disagree with the cached revision ancestry on their parent
revisions.  This may cause problems in using the database, and suggests
the presence of a bug in monotone's caching system, but does not involve
data loss.

@item revisions with mismatched children
that disagree with the cached revision ancestry on their child
revisions.  This may cause problems in using the database, and suggests
the presence of a bug in monotone's caching system, but does not involve
data loss.

@item revisions with bad history
that exist in the database but fail monotone's normal sanity checks for
consistent and correct history.  This is a serious problem; it indicates
that your history record is somehow malformed.  This should not be
possible, since monotone carefully checks every revision before storing
it into the database, but if it does, then please request assistance on
the monotone mailing list.  Fixing this generally means you may lose
some history --- for instance, renames may be degraded into delete/add
pairs --- but the actual contents of every revision will still be
reproducible.

@item revisions with missing certs
that exist in the database lacking at least one author, branch,
changelog or date cert. All revisions are expected to have at least one
of each of these certs.  In itself, this is not necessarily a problem,
but it is peculiar, and some operations such as netsync may behave
strangely.

@item revisions with mismatched certs
that exist in the database with differing numbers of author, changelog
and date certs. These certs are expected to appear together, as each
revision committed should have an author, changelog and date associated
with it.  In itself, this is not a problem, but it is peculiar.  All
operations should behave normally.

@item missing keys
that have been used to sign certs but do not exist in the database.  In
itself, this is not a problem, except that monotone will ignore any
certs signed by the missing key.  You can fix it by finding a database
containing the key in question, and using @command{pubkey} on that
database to create a public key packet, which can be loaded into your
database with @command{read}.

@item certs with bad signatures
that exist in the database with signatures that are invalid.  In itself,
this is not a problem, except that monotone will ignore any such certs.
You may also wish to find out who is creating certs with bad
signatures; it may indicate some kind of security attack.

@item certs with unchecked signatures
that exist in the database but cannot have their signatures checked
because the signing key is missing.  In itself, this is not a problem,
except that monotone will ignore any certs signed by the missing key.
You can fix it by finding a database containing the key in question, and
using @command{pubkey} on that database to create a public key packet,
which can be loaded into your database with @command{read}.

@end itemize

This command also verifies that the @sc{sha1} hash of every file, manifest,
and revision is correct.

@item mtn db kill_rev_locally @var{id}

This command ``kills'', i.e., deletes, a given revision, as well as any
certs attached to it.  It has an ugly name because it is a dangerous
command; it permanently and irrevocably deletes historical information
from your database.  There are a number of caveats:
@itemize
@item
It can only be applied to revisions that have no descendants.  If you
want to kill a revision that has descendants, you must kill all of the
descendants first.
@item
It only removes the revision from your local database (hence the
``locally'' in the command name).  If you have already pushed this
revision out to another database, then the next time you pull from that
database it may come back again.  There is no way to delete a revision
from somebody else's database except to ask them to delete it for you.
@item
It does not actually delete the revision's files or manifest from your
database.  If you run this command, and then run @command{db check}, it
will note that you have an ``unreferenced manifest''.  If you wish to
eliminate this data for good (and thus free up the space), you may use
netsync to @command{pull} from your current database into a new
database; this creates a copy of your old database, without the
unreferenced data.  However, having this data in your database will not
cause any problems, and acts as a safety net; if you later realize that
you do, after all, need to retrieve the data in @var{id}, then
@command{db check} will let you see which manifest it was, and with some
work you can extract @var{id}'s data.
@end itemize

@item mtn db kill_branch_certs_locally @var{branch}

This command ``kills'' a branch by deleting all branch certs with that
branch name. You should consider carefully whether you want to use it,
because it can irrevocably delete important information. It does not
modify or delete any revisions or any of the other certificates on
revisions in the branch; it simply removes the branch certificates
matching the given branch name. Because of this, it can leave
revisions without any branch certificate at all. As with @command{db
kill_rev_locally}, it only deletes the information from your local
database; if there are other databases that you sync with which have
revisions in this branch, the branch certificates will reappear when
you sync, unless the owners of those databases also delete those
certificates locally.

@item mtn db kill_tag_locally @var{tag}

This command ``kills'' a tag by deleting all tag certs with that tag
name. You should consider carefully whether you want to use it, because
it can irrevocably delete important information. It does not modify or
delete any revisions, or any of the other certificates on tagged
revisions; it simply removes all tag certificates with the given name.
As with @command{db kill_rev_locally}, it only deletes the information
from your local database; if there are other databases that you sync
with which have this tag, the tag certificates will reappear when you
sync, unless the owners of those databases also delete those
certificates locally.

@item mtn db execute @var{sql-statement}

This is a debugging command which executes @var{sql-statement} against
your database, and prints any results of the expression in a tabular
form.  It can be used to investigate the state of your database, or
help diagnose failures.

@end ftable


@page
@node    Automation
@section Automation

This section contains subcommands of the @command{mtn automate} command,
used for scripting monotone.  All give output on @code{stdout}; they may
also give useful chatter on @code{stderr}, including warnings and error
messages.


@ftable @command
@item mtn automate interface_version

@table @strong
@item Arguments:

None.

@item Added in:

0.0

@item Purpose:

Prints version of the automation interface.  Major number increments
whenever a backwards incompatible change is made to the @command{automate}
command; minor number increments whenever any change is made (but is
reset when major number increments).

@item Sample output:

@verbatim
1.2
@end verbatim

@item Output format:

A decimal number, followed by ``.'' (full stop/period), followed by a
decimal number, followed by a newline, followed by end-of-file.  The
first decimal number is the major version, the second is the minor version.

@item Error conditions:

None.

@end table


@item mtn automate heads [@var{branch}]

@table @strong
@item Arguments:

One branch name,  @var{branch}. If none is given, the current default branch is used.

@item Added in:

0.0

@item Purpose:

Prints the heads of branch @var{branch}.

@item Sample output:

@verbatim
28ce076c69eadb9b1ca7bdf9d40ce95fe2f29b61
75156724e0e2e3245838f356ec373c50fa469f1f
@end verbatim

@item Output format:

Zero or more lines, each giving the ID of one head of the given branch.
Each line consists of a revision ID, in hexadecimal, followed by a
newline.  The lines are printed in alphabetically sorted order.

@item Error conditions:

If the given branch contains no members or does not exist, then no lines are printed.

@end table


@item mtn automate ancestors @var{rev1} [@var{rev2} [...]]

@table @strong
@item Arguments:

One or more revision IDs, @var{rev1}, @var{rev2}, etc.

@item Added in:

0.2

@item Purpose:

Prints the ancestors of one or more revisions.

@item Sample output:

@verbatim
28ce076c69eadb9b1ca7bdf9d40ce95fe2f29b61
75156724e0e2e3245838f356ec373c50fa469f1f
@end verbatim

@item Output format:

Zero or more lines, each giving the ID of one ancestor of the given
revisions.  Each line consists of a revision ID, in hexadecimal,
followed by a newline.  The lines are printed in alphabetically sorted
order.

The output does not include @var{rev1}, @var{rev2}, etc., except if
@var{rev2} is itself an ancestor of @var{rev1}, then @var{rev2} will be
included in the output.

@item Error conditions:

If any of the revisions do not exist, prints nothing to stdout, prints
an error message to stderr, and exits with status 1.

@end table


@item mtn automate common_ancestors @var{rev1} [@var{rev2} [...]]

@table @strong
@item Arguments:

One or more revision IDs, @var{rev1}, @var{rev2}, etc.

@item Added in:

2.1

@item Purpose:

Prints all revisions which are ancestors of all of the revisions given as
arguments.

@item Sample output:

@verbatim
28ce076c69eadb9b1ca7bdf9d40ce95fe2f29b61
75156724e0e2e3245838f356ec373c50fa469f1f
@end verbatim

@item Output format:

Zero or more lines, each giving the ID of one common ancestor of all the given
revisions.  Each line consists of a revision ID, in hexadecimal,
followed by a newline.  The lines are printed in alphabetically sorted
order.

The output will include one of the argument revisions only if that revision is
an ancestor of all other revisions given as arguments.

@item Error conditions:

If any of the revisions do not exist, prints nothing to stdout, prints
an error message to stderr, and exits with status 1.

@end table


@item mtn automate parents @var{rev}

@table @strong
@item Arguments:

One revision ID, @var{rev}.

@item Added in:

0.2

@item Purpose:

Prints the immediate parents of a revision.  This is like a
non-recursive version of @command{automate ancestors}.

@item Sample output:

@verbatim
28ce076c69eadb9b1ca7bdf9d40ce95fe2f29b61
75156724e0e2e3245838f356ec373c50fa469f1f
@end verbatim

@item Output format:

Zero or more lines, each giving the ID of one parent of the given
revision.  Each line consists of a revision ID, in hexadecimal,
followed by a newline.  The lines are printed in alphabetically sorted
order.

@item Error conditions:

If the given revision @var{rev} does not exist, prints nothing to
stdout, prints an error message to stderr, and exits with status 1.

@end table


@item mtn automate descendents @var{rev1} [@var{rev2} [...]]

@table @strong
@item Arguments:

One or more revision IDs, @var{rev1}, @var{rev2}, etc.

@item Added in:

0.1

@item Purpose:

Prints the descendants of one or more revisions.

@item Sample output:

@verbatim
28ce076c69eadb9b1ca7bdf9d40ce95fe2f29b61
75156724e0e2e3245838f356ec373c50fa469f1f
@end verbatim

@item Output format:

Zero or more lines, each giving the ID of one descendant of the given
revisions.  Each line consists of a revision ID, in hexadecimal,
followed by a newline.  The lines are printed in alphabetically sorted
order.

The output does not include @var{rev1}, @var{rev2}, etc., except that if
@var{rev2} is itself a descendant of @var{rev1}, then @var{rev2} will be
included in the output.

@item Error conditions:

If any of the revisions do not exist, prints nothing to stdout, prints
an error message to stderr, and exits with status 1.

@end table


@item mtn automate children @var{rev}

@table @strong
@item Arguments:

One revision ID, @var{rev}.

@item Added in:

0.2

@item Purpose:

Prints the immediate children of a revision.  This is like a
non-recursive version of @command{automate descendents}.

@item Sample output:

@verbatim
28ce076c69eadb9b1ca7bdf9d40ce95fe2f29b61
75156724e0e2e3245838f356ec373c50fa469f1f
@end verbatim

@item Output format:

Zero or more lines, each giving the ID of one child of the given
revision.  Each line consists of a revision ID, in hexadecimal,
followed by a newline.  The lines are printed in alphabetically sorted
order.

@item Error conditions:

If the given revision @var{rev} does not exist, prints nothing to
stdout, prints an error message to stderr, and exits with status 1.

@end table


@item mtn automate graph

@table @strong
@item Arguments:

None.

@item Added in:

0.2

@item Purpose:

Prints out the complete ancestry graph of this database.

@item Sample output:

@verbatim
0c05e8ec9c6af4224672c7cc4c9ef05ae8bdb794
27ebcae50e1814e35274cb89b5031a423c29f95a 5830984dec5c41d994bcadfeab4bf1bf67747b89
4e284617c80bec7da03925062a84f715c1b042bd 27ebcae50e1814e35274cb89b5031a423c29f95a 657c756d24fb65213d59f4ae07e117d830dcc95b
@end verbatim

@item Output format:

Zero or more lines, each giving ancestry information for one revision.
Each line begins with a revision ID.  Following this are zero or more
space-prefixed revision IDs.  Each revision ID after the first is a
parent (in the sense of @command{automate parents}) of the first.  For
instance, in the above sample output,
0c05e8ec9c6af4224672c7cc4c9ef05ae8bdb794 is a root node,
27ebcae50e1814e35274cb89b5031a423c29f95a has one parent, and
4e284617c80bec7da03925062a84f715c1b042bd has two parents, i.e., is a
merge node.

The output as a whole is alphabetically sorted by line; additionally,
the parents within each line are alphabetically sorted.

@item Error conditions:

None.

@end table


@item mtn automate erase_ancestors [@var{rev1} [@var{rev2} [...]]]

@table @strong
@item Arguments:

One or more revision IDs, @var{rev1}, @var{rev2}, etc.

@item Added in:

0.1

@item Purpose:

Prints all arguments, except those that are an ancestor of some other
argument.  One way to think about this is that it prints the minimal
elements of the given set, under the ordering imposed by the ``child
of'' relation.  Another way to think of it is if the arguments formed a
branch, then we would print the heads of that branch.  If there
are no arguments, prints nothing.

@item Sample output:

@verbatim
28ce076c69eadb9b1ca7bdf9d40ce95fe2f29b61
75156724e0e2e3245838f356ec373c50fa469f1f
@end verbatim

@item Output format:

Zero or more lines, each giving the ID of one descendant of the given
revisions.  Each line consists of a revision ID, in hexadecimal,
followed by a newline.  The lines are printed in alphabetically sorted
order.

@item Error conditions:

If any of the revisions do not exist, prints nothing to stdout, prints
an error message to stderr, and exits with status 1.

@end table


@item mtn automate toposort [@var{rev1} [@var{rev2} [...]]]

@table @strong
@item Arguments:

One or more revision IDs, @var{rev1}, @var{rev2}, etc.

@item Added in:

0.1

@item Purpose:

Prints all arguments, topologically sorted.  I.e., if @var{rev1} is an
ancestor of @var{rev2}, then @var{rev1} will appear before @var{rev2} in
the output; if @var{rev2} is an ancestor of @var{rev1}, then @var{rev2}
will appear before @var{rev1} in the output; and if neither is an
ancestor of the other, then they may appear in either order.  If there
are no arguments, prints nothing.

@item Sample output:

@verbatim
28ce076c69eadb9b1ca7bdf9d40ce95fe2f29b61
75156724e0e2e3245838f356ec373c50fa469f1f
@end verbatim

@item Output format:

A list of revision IDs, in hexadecimal, each followed by a newline.
Revisions are printed in topologically sorted order.

@item Error conditions:

If any of the revisions do not exist, prints nothing to stdout, prints
an error message to stderr, and exits with status 1.

@end table


@item mtn automate ancestry_difference @var{new} [@var{old1} [@var{old2} [...]]]

@table @strong
@item Arguments:

A ``new'' revision ID @var{new}, followed by zero or more ``old''
revision IDs @var{old1}, @var{old2}, etc.

@item Added in:

0.1

@item Purpose:

Prints all ancestors of the revision @var{new}, that are not also
ancestors of one of the old revisions.  For purposes of this command,
``ancestor'' is an inclusive term; for example, if @var{new} is an
ancestor of @var{old1}, it will not be printed; but if @var{new} is not
an ancestor of any of the ``old'' revisions, then it will be.
Similarly, @var{old1} will never be printed, because it is considered to
be an ancestor of itself.  The reason for the names is that if @var{new}
a new revision, and @var{old1}, @var{old2}, etc. are revisions that you
have processed before, then this command tells you which revisions are
new since then.

@item Sample output:

@verbatim
28ce076c69eadb9b1ca7bdf9d40ce95fe2f29b61
75156724e0e2e3245838f356ec373c50fa469f1f
@end verbatim

@item Output format:

A list of revision IDs, in hexadecimal, each followed by a newline.
Revisions are printed in topologically sorted order.

@item Error conditions:

If any of the revisions do not exist, prints nothing to stdout, prints
an error message to stderr, and exits with status 1.

@end table


@item mtn automate leaves

@table @strong
@item Arguments:

None.

@item Added in:

0.1

@item Purpose:

Prints the leaves of the revision graph, i.e. all revision that have no
children.  This is similar, but not identical to the functionality of
@command{heads}, which prints every revision in a branch, that has no
descendants in that branch.  If every revision in the database was in
the same branch, then they would be identical.  Generally, every leaf is
the head of some branch, but not every branch head is a leaf.

@item Sample output:

@verbatim
28ce076c69eadb9b1ca7bdf9d40ce95fe2f29b61
75156724e0e2e3245838f356ec373c50fa469f1f
@end verbatim

@item Output format:

Zero or more lines, each a leaf of the revision graph.  Each line
consists of a revision ID, in hexadecimal, followed by a newline.  The
lines are printed in alphabetically sorted order.

@item Error conditions:

None.

@end table


@item mtn automate roots

@table @strong
@item Arguments:

None.

@item Added in:

4.3

@item Purpose:

Prints the roots of the revision graph, i.e. all revisions that have
no parents.

@item Sample output:

@verbatim
276264b0b3f1e70fc1835a700e6e61bdbe4c3f2f
@end verbatim

@item Output format:

Zero or more lines, each a root of the revision graph.  Each line
consists of a revision ID, in hexadecimal, followed by a newline.  The
lines are printed in alphabetically sorted order.

@item Error conditions:

None.

@end table


@item mtn automate branches

@table @strong
@item Arguments:

None.

@item Added in:

2.2

@item Purpose:

Prints all branch certs present in the revision graph, that are not
excluded by the Lua hook @code{ignore_branch}.

@item Sample output:

@verbatim
net.venge.monotone
net.venge.monotone.win32
@end verbatim

@item Output format:

Zero or more lines, each the name of a branch. The lines are printed
in alphabetically sorted order.

@item Error conditions:

None.

@end table


@item mtn automate tags [@var{branch_pattern}]

@table @strong
@item Arguments:

A branch pattern (optional).

@item Added in:

2.2

@item Purpose:

If a branch pattern is given, prints all tags that are attached to
revisions on branches matched by the pattern; otherwise prints all
tags of the revision graph.

If a branch name is ignored by means of the Lua hook
@code{ignore_branch}, it is neither printed, nor can it be matched by
a pattern.

@item Sample output:

@verbatim
format_version "1"

     tag "monotree-0.3"
revision [35cff8e8ba14155f5f7ddf7965073f514fd60f61]
  signer "njs@pobox.com"
branches "net.venge.monotone.contrib.monotree"

     tag "monotree-0.2"
revision [5d288b39b49613b0d9dca8ece6b9a42c3773f35b]
  signer "njs@pobox.com"
branches "net.venge.monotone.contrib.monotree"

     tag "monotree-0.1"
revision [8a121346ce2920b6f85df68b3b620de96bd14a8d]
  signer "njs@pobox.com"
branches "net.venge.monotone.contrib" "net.venge.monotone.contrib.monotree"

     tag "monotree-0.4"
revision [f1afc520474f83c58262896ede027ef77226046e]
  signer "njs@pobox.com"
branches "net.venge.monotone.contrib.monotree"
@end verbatim

@item Output format:

There is one basic_io stanza for each tag.

All stanzas are formatted by basic_io. Stanzas are separated by a
blank line. Values will be escaped, '\' to '\\' and '"' to '\"'.

Each stanza has exactly the following four entries:

@table @option
@item 'tag'
the value of the tag cert, i.e. the name of the tag

@item 'revision'
the hexadecimal id of the revision the tag is attached to

@item 'signer'
the name of the key used to sign the tag cert

@item 'branches'
a (possibly empty) list of all branches the tagged revision is on
@end table

Stanzas are printed in arbitrary order.

@item Error conditions:

A run-time exception occurs if an illegal branch pattern is
specified.

@end table


@item mtn automate select @var{selector}

@table @strong
@item Arguments:

One selector (or combined selector).

@item Added in:

0.2

@item Purpose:

Print all revisions that match the given selector.

@item Sample output:

@verbatim
28ce076c69eadb9b1ca7bdf9d40ce95fe2f29b61
75156724e0e2e3245838f356ec373c50fa469f1f
@end verbatim

@item Output format:

Zero or more lines, each giving the ID of one revision that matches the
given selector.  Each line consists of a revision ID, in hexadecimal,
followed by a newline.  Revision ids are printed in alphabetically
sorted order.

@item Error conditions:

None.

@end table

@item mtn automate identify @var{path}

@table @strong
@item Arguments:

A file path.

@item Added in:

4.2

@item Purpose:

Prints the file ID (aka hash) of the given file.

@item Sample output:

@verbatim
6265ab1312fbe38bdc3aafa92441139cb2b779b0
@end verbatim

@item Output format:

A single line with the file's ID, in hexadecimal, followed by a newline.

@item Error conditions:

If the file does not exists, is a special file or not readable, prints an
error message to stderr and exists with status 1. A single file path only
consisting of "-" is disallowed since it collides with the UNIX stdin
marker.

@end table

@item mtn automate inventory

@table @strong
@item Arguments:

None.

@item Added in:

1.0

@item Purpose:

Prints the inventory of every file found in the workspace or its
associated base manifest. Each unique path is listed on a line prefixed by
three status characters and two numeric values used for identifying
renames. 

@item Sample output:

All basic status codes:

@verbatim
  M 0 0 missing
 AP 0 0 added
D   0 0 dropped
R   1 0 renamed-from-this
 R  0 1 renamed-to-this
  P 0 0 patched
    0 0 unchanged
  U 0 0 unknown
  I 0 0 ignored
@end verbatim

Two files swapped:

@verbatim
RR  1 2 unchanged
RR  2 1 original
@end verbatim

Recorded with monotone that two files were swapped, but they were not
actually swapped in the filesystem.  Thus they both appear as patched:

@verbatim
RRP 1 2 unchanged
RRP 2 1 original
@end verbatim

Rename @file{foo} to @file{bar}; add new file @file{foo}:

@verbatim
RAP 1 0 foo
 R  0 1 bar
@end verbatim

Rotated files @file{foo} -> @file{bar} -> @file{baz} -> @file{foo}:

@verbatim
RR  1 3 foo
RR  2 1 bar
RR  3 2 baz
@end verbatim

Recorded the rotation of files @file{foo} -> @file{bar} -> @file{baz} ->
@file{foo}, but the actual files in the workspace were not
moved, so monotone interprets all files as having been patched:

@verbatim
RRP 1 3 foo
RRP 2 1 bar
RRP 3 2 baz
@end verbatim

Dropped but not removed and thus unknown:

@verbatim
D U 0 0 dropped
@end verbatim

Added a non-existent file which is thus missing:

@verbatim
 AM 0 0 added
@end verbatim

Recorded a rename, but not moved in the filesystem, and thus unknown
source and missing target:

@verbatim
R U 1 0 original
 RM 0 1 renamed
@end verbatim

Moved in the filesystem but no rename recorded, and thus missing source
and unknown target:

@verbatim
  M 0 0 original
  U 0 0 renamed
@end verbatim

Renamed and patched:

@verbatim
R   1 0 original
 RP 0 1 renamed
@end verbatim

@item Output format:

Each path is printed on its own line, prefixed by three status
characters described below. The status is followed by a single space and
two numbers, each separated by a single space, used for identifying renames.
The numbers are followed by a single space and then the pathname, which 
includes the rest of the line. Directory paths are identified as ending with
the "/" character, file paths do not end in this character.

The three status characters are as follows.

@verbatim
column 1 pre-state
      ' ' the path was unchanged in the pre-state
      'D' the path was deleted from the pre-state
      'R' the path was renamed from the pre-state name
column 2 post-state
      ' ' the path was unchanged in the post-state
      'R' the path was renamed to the post-state name
      'A' the path was added to the post-state
column 3 file-state
      ' ' the file is known and unchanged from the current manifest version
      'P' the file is patched to a new version
      'U' the file is unknown and not included in the current manifest
      'I' the file is ignored and not included in the current manifest
      'M' the file is missing but is included in the current manifest
@end verbatim

Note that out of the 45 possible status code combinations, only 26 are valid,
detailed below.

@verbatim
'   ' unchanged
'  P' patched (contents changed)
'  U' unknown (exists on the filesystem but not tracked)
'  I' ignored (exists on the filesystem but excluded by Lua hook)
'  M' missing (exists in the manifest but not on the filesystem)

' A ' added (invalid, add should have associated patch)
' AP' added and patched
' AU' added but unknown (invalid)
' AI' added but ignored (invalid, added files are no longer ignored)
' AM' added but missing from the filesystem

' R ' rename target
' RP' rename target and patched
' RU' rename target but unknown (invalid)
' RI' rename target but ignored (invalid)
' RM' rename target but missing from the filesystem

'D  ' dropped
'D P' dropped and patched (invalid)
'D U' dropped and unknown (still exists on the filesystem)
'D I' dropped and ignored
'D M' dropped and missing (invalid)

'DA ' dropped and added (invalid, add should have associated patch)
'DAP' dropped and added and patched
'DAU' dropped and added but unknown (invalid)
'DAI' dropped and added but ignored (invalid, added files are no longer ignored)
'DAM' dropped and added but missing from the filesystem

'DR ' dropped and rename target
'DRP' dropped and rename target and patched
'DRU' dropped and rename target but unknown (invalid)
'DRI' dropped and rename target but ignored (invalid)
'DRM' dropped and rename target but missing from the filesystem

'R  ' rename source
'R P' rename source and patched (invalid)
'R U' rename source and unknown (still exists on the filesystem)
'R I' rename source and ignored
'R M' rename source and missing (invalid)

'RA ' rename source and added (invalid, add should have associated patch)
'RAP' rename source and added and patched
'RAU' rename source and added but unknown (invalid)
'RAI' rename source and added but ignored (invalid, added files are no longer ignored)
'RAM' rename source and added but missing from the filesystem

'RR ' rename source and target
'RRP' rename source and target and target patched
'RRU' rename source and target and target unknown (invalid)
'RRI' rename source and target and target ignored (invalid)
'RRM' rename source and target and target missing
@end verbatim

The two numbers are used to match up the pre-state and post-state of a
rename.  Imagine a situation where there are two renames.
@command{automate inventory} will print something like:

@verbatim
R   1 0 a
R   2 0 b
 R  0 2 c
 R  0 1 d
@end verbatim

Here the status characters tell us that @file{a} and @file{b} were
renamed, and we can tell that one was renamed to @file{c} and one was
renamed to @file{d}, but we can't tell which was renamed to which.  To
do that, we have to refer to the numbers.  The numbers do not themselves
mean anything; their only purpose is to let you match up the two
``ends'' of a rename.  The 1 in the left column by @file{a} means that
@file{a} was the source of a rename, and the 1 in the right column by
@file{d} means that @file{d} was the target of that same rename.
Similarly, the two 2's tell us that @file{b} was renamed to @file{c}.

There are two columns of numbers because the same file can
simultaneously be the target and source of a rename.  The number '0' is
used as a meaningless placeholder in all cases where a file is not a
source or target of a rename.  Any non-zero number that occurs at all
will occur exactly once in the first column and exactly once in the
second column.

Full support for versioned directories is not yet complete and the
inventory will only list entries for renamed or dropped
directories. 

@item Error conditions:

When executed from outside of a workspace directory, prints an error
message to stderr, and exits with status 1.

@end table

@item mtn automate certs @var{id}

@table @strong
@item Arguments:

A revision ID @var{id}, for which any certificates will be printed.

@item Added in:

1.0

@item Purpose:

Prints all certificates associated with the given revision ID.
Each certificate is contained in a basic IO stanza. For each certificate, 
the following values are provided:

@verbatim
'key'
      a string indicating the key used to sign this certificate.
'signature'
      a string indicating the status of the signature. Possible 
      values of this string are:
            'ok'        : the signature is correct
            'bad'       : the signature is invalid
            'unknown'   : signature was made with an unknown key
'name'
      the name of this certificate
'value'
      the value of this certificate
'trust'
      is this certificate trusted by the defined trust metric?
      Possible values of this string are:
            'trusted'   : this certificate is trusted
            'untrusted' : this certificate is not trusted
@end verbatim
 
@item Sample output:

@verbatim
      key "emile@alumni.reed.edu"
signature "ok"
     name "author"
    value "emile@alumni.reed.edu"
    trust "trusted"

      key "emile@alumni.reed.edu"
signature "ok"
     name "branch"
    value "net.venge.monotone"
    trust "trusted"

      key "emile@alumni.reed.edu"
signature "ok"
     name "changelog"
    value "propagate from branch 'net.venge.monotone.annotate' (head 76a886ef7c8ae12a4bba5fc2bd252557bf863aff)
            to branch 'net.venge.monotone' (head 2490479a4e4e99243fead6d627d78291fde592f0)
"
    trust "trusted"

      key "emile@alumni.reed.edu"
signature "ok"
     name "date"
    value "2005-05-20T20:19:25"
    trust "trusted"
@end verbatim

@item Output format:

All stanzas are formatted by basic_io. Stanzas are separated 
by a blank line. Values will be escaped, '\' to '\\' and 
'"' to '\"'.

@item Error conditions:

If a certificate is signed with an unknown public key, a 
warning message is printed to stderr. If the revision specified is unknown 
or invalid prints an error message to stderr and exits with status 1.

@end table

@item mtn automate stdio

@table @strong
@item Arguments:

none

@item Added in:

1.0

@item Modifications:
@table @strong
@item 3.1

Added the 'o' item to the recognized input. This change should not
break anything.

@end table

@item Purpose:

Allow multiple automate commands to be run from one instance of monotone.

@item Sample input:

@verbatim
l6:leavese
l7:parents40:0e3171212f34839c2e3263e7282cdeea22fc5378e
o3:key11:foo@bar.come l4:cert40:0e3171212f34839c2e3263e7282cdeea22fc53783:foo3:bare
@end verbatim

@item Input format:

@verbatim
[ 'o' <string> <string> [ <string> <string> [ ... ] ] 'e' ]
'l' <string> [ <string> [ ... ] ] 'e'
@end verbatim

The input is a series of commands. The command name plus arguments are
provided as 'l' <string> [<string> ...] 'e', where <string> = <size> colon
<data> . This may optionally be preceded by a set of key=value pairs
(command options) as 'o' <string> <string> [<string> <string> ...] 'e', where
strings come in pairs, key followed by value.

The space between the ending 'e' of one group of strings and the beginning
'l' or 'o' of the next is reserved. Any characters other than whitespace
will cause an error.

@item Sample output:

@verbatim
0:0:l:205:0e3171212f34839c2e3263e7282cdeea22fc5378
1f4ef73c3e056883c6a5ff66728dd764557db5e6
2133c52680aa2492b18ed902bdef7e083464c0b8
23501f8afd1f9ee037019765309b0f8428567f8a
2c295fcf5fe20301557b9b3a5b4d437b5ab8ec8c
1:0:l:41:7706a422ccad41621c958affa999b1a1dd644e79
@end verbatim

@item Output format:

The output consists of one or more packets for each command.
A packet looks like:

<command number>:<err code>:<last?>:<size>:<output>

<command number> is a decimal number specifying which command this output
is from. It is 0 for the first command, and increases by one each time.

<err code> is 0 for success, 1 for a syntax error, and 2 for any other error.

<last?> is 'l' if this is the last piece of output for this command, and 'm'
if there is more output to come.

<size> is the number of bytes in the output.

<output> is a piece of the output of the command.

All but the last packet for a given command will have the
<last?> field set to 'm'. 

@item Error conditions:

If a badly formatted or invalid command is received, or a command is
given with invalid arguments or options, prints an error message to
standard error and exits with nonzero status. Errors in the commands run
through this interface do not affect the exit status. Instead, the <err code>
field in the output is set to 2, and the output of the command becomes
whatever error message would have been given.

@end table

@item mtn automate get_revision
@item mtn automate get_revision @var{id}

@table @strong
@item Arguments:

Specifying the option @var{id} argument outputs the changeset 
information for the specified @var{id}. Otherwise, @var{id} is 
determined from the workspace.

@item Added in:

1.0

@item Purpose:

Prints change information for the specified revision id.

@item Sample output:

@verbatim
format_version "1"

new_manifest [bfe2df785c07bebeb369e537116ab9bb7a4b5e19]

old_revision [429fea55e9e819a046843f618d90674486695745]

patch "ChangeLog"
 from [7dc21d3a46c6ecd94685ab21e67b131b32002f12]
   to [234513e3838d423b24d5d6c98f70ce995c8bab6e]

patch "std_hooks.lua"
 from [0408707bb6b97eae7f8da61af7b35364dbd5a189]
   to [d7bd0756c48ace573926197709e53eb24dae5f5f]
@end verbatim

@item Output format:

There are several changes that are described; each of these is described by 
a different basic_io stanza. The first string pair of each stanza indicates the 
type of change represented. 

All stanzas are formatted by basic_io. Stanzas are separated 
by a blank line. Values will be escaped, '\' to '\\' and 
'"' to '\"'.

Possible values of this first value are along with an ordered list of 
basic_io formatted stanzas that will be provided are:

@verbatim
'format_version'
      used in case this format ever needs to change.
      format: ('format_version', the string "1")
      occurs: exactly once
'new_manifest'
      represents the new manifest associated with the revision.
      format: ('new_manifest', manifest id)
      occurs: exactly one
'old_revision'
      represents a parent revision.
      format: ('old_revision', revision id)
      occurs: either one or two times
'delete
      represents a file or directory that was deleted.
      format: ('delete', path)
      occurs: zero or more times
'rename'
      represents a file or directory that was renamed.
      format: ('rename, old filename), ('to', new filename)
      occurs: zero or more times
'add_dir'
      represents a directory that was added.
      format: ('add_dir, path)
      occurs: zero or more times
'add_file'
      represents a file that was added.
      format: ('add_file', path), ('content', file id)
      occurs: zero or more times
'patch'
      represents a file that was modified.
      format: ('patch', filename), ('from', file id), ('to', file id)
      occurs: zero or more times
'clear'
      represents an attr that was removed.
      format: ('clear', filename), ('attr', attr name)
      occurs: zero or more times
'set'
      represents an attr whose value was changed.
      format: ('set', filename), ('attr', attr name), ('value', attr value)
      occurs: zero or more times
@end verbatim
 
These stanzas will always occur in the order listed here; stanzas of
the same type will be sorted by the filename they refer to. The 'delete'
and following stanzas will be grouped under the corresponding 'old_revision'
one.

@item Error conditions:

If the revision specified is unknown or invalid prints an error message
to stderr and exits with status 1.

@end table



@item mtn automate get_base_revision_id

@table @strong
@item Arguments:

None.

@item Added in:

2.0

@item Purpose:

Prints the revision id the current workspace is based on. This is the
``old_revision'' value stored in @file{_MTN/revision}.

@item Sample output:

@verbatim
28ce076c69eadb9b1ca7bdf9d40ce95fe2f29b61
@end verbatim

@item Output format:

One line containing the base revision ID of the current workspace.

@item Error conditions:

If no workspace book keeping _MTN directory is found, prints an error
message to stderr, and exits with status 1.

@end table



@item mtn automate get_current_revision_id

@table @strong
@item Arguments:

None.

@item Added in:

2.0

@item Purpose:

Prints the revision id of the current workspace. This is the id
of the revision that would be committed by an unrestricted commit
in the workspace.

@item Sample output:

@verbatim
28ce076c69eadb9b1ca7bdf9d40ce95fe2f29b61
@end verbatim

@item Output format:

One line containing the current revision id ID of the current workspace.

@item Error conditions:

If no workspace book keeping _MTN directory is found, prints an error
message to stderr, and exits with status 1.


@end table


@item mtn automate get_manifest_of
@item mtn automate get_manifest_of @var{revid}

@table @strong
@item Arguments:

Specifying the optional @var{revid} argument outputs the manifest for the
revision with the specified ID. Otherwise, outputs the manifest for the
current workspace.  (You can think of leaving the argument blank
as meaning ``give me the manifest of THIS''.)

@item Added in:

2.0

@item Purpose:

Prints the contents of the manifest associated with the given roster.

@item Sample output:

@verbatim
format_version "1"

dir ""

   file ".htaccess"
content [e3915658cb464d05f21332e03d30dca5d94fe776]

   file "AUTHORS"
content [80d8f3f75c9b517ec462233e155f7dfb93379f67]

   file "ChangeLog"
content [fc74a48c7f73eedcbe1ea709755fbe819b29736c]

   file "LICENSE"
content [dfac199a7539a404407098a2541b9482279f690d]

   file "README"
content [440eec971e7bb61ccbb61634deb2729bb25931cd]

   file "TODO"
content [e0ea26c666b37c5f98ccf80cb933d021ee55c593]

   file "branch.psp"
content [b28ece354969314ce996f3030569215d685973d6]

   file "common.py"
content [1fdb62e05fb2a9338d2c72ddc58de3ab2b3976fe]

   file "config.py.example"
content [64cb5898e3a026b4782c343ca4386585e0c3c275]

   file "error.psp"
content [7152c3ff110418aca5d23c374ea9fb92a0e98379]

   file "fileinbranch.psp"
content [5d8536100fdf51d505b6f20bc9c16aa78d4e86a8]

   file "headofbranch.psp"
content [981df124a0b5655a9f78c42504cfa8c6f02b267a]

   file "help.psp"
content [a43d0588a69e622b2afc681678c2a5c3b3b1f342]

   file "html.py"
content [18a8bffc8729d7bfd71d2e0cb35a1aed1854fa74]

   file "index.psp"
content [c621827db187839e1a7c6e51d5f1a7f6e0aa560c]

   file "monotone.py"
content [708b61436dce59f47bd07397ce96a1cfabe81970]

   file "revision.psp"
content [a02b1c161006840ea8685e461fd07f0e9bb145a3]

   file "rss_feed.gif"
content [027515fd4558abf317d54c437b83ec6bc76e3dd8]

   file "tags.psp"
content [638140d6823eee5844de37d985773be75707fa25]

   file "tarofbranch.psp"
content [be83f459a152ffd49d89d69555f870291bc85311]

   file "test.py"
content [e65aace9237833ec775253cfde97f59a0af5bc3d]
   attr "mtn:execute" "true"

   file "utility.py"
content [fb51955563d64e628e0e67e4acca1a1abc4cd989]

   file "viewmtn.css"
content [8d04b3fc352a860b0e3240dcb539c1193705398f]

   file "viewmtn.py"
content [7cb5c6b1b1710bf2c0fa41e9631ae43b03424a35]

   file "wrapper.py"
content [530290467a99ca65f87b74f653bf462b28c6cda9]
@end verbatim

@item Output format:

There is one basic_io stanza for each file or directory in the
manifest.

All stanzas are formatted by basic_io. Stanzas are separated 
by a blank line. Values will be escaped, '\' to '\\' and 
'"' to '\"'.

Possible values of this first value are along with an ordered list of 
basic_io formatted stanzas that will be provided are:

@verbatim
'format_version'
      used in case this format ever needs to change.
      format: ('format_version', the string "1")
      occurs: exactly once
'dir':
      represents a directory.  The path "" (the empty string) is used
      to represent the root of the tree.
      format: ('dir', pathname)
      occurs: one or more times
'file':
      represents a file.
      format: ('file', pathname), ('content', file id)
      occurs: zero or more times
@end verbatim
 
In addition, 'dir' and 'file' stanzas may have attr information
included.  These are appended to the stanza below the basic dir/file
information, with one line describing each attr.  These lines take the
form ('attr', attr name, attr value).

Stanzas are sorted by the path string.

@item Error conditions:

If the revision ID specified is unknown or invalid prints an error
message to stderr and exits with status 1.

@end table

@item mtn automate attributes @var{file}

@table @strong
@item Arguments:

The argument @var{file} determines which file's attributes should be printed.

@item Added in:

3.0

@item Purpose:

Prints all attributes of the given file and the attribute states.

@item Sample output:

@verbatim
format_version "1"

 attr "foo" "bar"
state "added"

 attr "baz" "bat"
state "dropped"

 attr "foobar" "foobat"
state "unchanged"
@end verbatim

@item Output format:

There is one basic_io stanza for each attribute of the given file.

All stanzas are formatted by basic_io. Stanzas are separated 
by a blank line and ordered by attribute name. Values will be 
escaped, '\' to '\\' and '"' to '\"'.

Each attribute stanza also contains another entry which tells the status
of attribute. This entry can have one of the following four values:

@itemize
@item
'added': the attribute has just been added to the file
@item
'dropped': the attribute has just been dropped from the file
@item
'unchanged': the attribute has not been changed since the last revision
@item
'changed': the attribute has been changed since the last revision
@end itemize

The status 'changed' can come up if an attribute foo has been dropped and
added afterwards with another value, like

@verbatim
$ mtn attr drop file.txt foo ; mtn attr set file.txt foo baz
@end verbatim

If an attribute has been dropped, the output will still return the previously
set value of the dropped attribute for convenience (obviously this is no longer
recorded in the current workspace).

The complete format:

@verbatim
'format_version'
      used in case this format ever needs to change.
      format: ('format_version', the string "1")
      occurs: exactly once
'attr':
      represents an attribute.
      format: ('attr', key, value), ('state', [unchanged|changed|added|dropped])
      occurs: zero or more times
@end verbatim

@item Error conditions:

If the file specified is unknown to the current workspace prints an error
message to stderr and exits with status 1.

@end table

@item mtn automate content_diff [--revision=@var{id1} [--revision=@var{id2}]] [@var{files} ...]

@table @strong
@item Arguments:

One or more @var{file} arguments restrict the diff output to these files,
otherwise all changed files in the given revision(s) and/or current workspace
are considered.

If zero or more revisions are given, the command behaves as follows:

@itemize
@item
no revision: the diff is done between the workspace revision and the 
parent (base) revision of this workspace
@item
one revision: the diff is done between the workspace revision and the
given revision @option{id1},
@item
two revisions: the diff is done between @option{id1} and @option{id2}; no
workspace is needed in this case.
@end itemize

@item Added in:

4.0

@item Purpose:

Prints the content changes between two revisions or a revision and the current
workspace. This command differs from @command{mtn diff} in that way that it only
outputs content changes and keeps quite on renames or drops, as the header of
@command{mtn diff} is omitted (this is what @command{mtn automate get_revision} 
already provides).

@item Sample output:

@verbatim
============================================================
--- guitone/res/i18n/guitone_de.ts      9857927823e1d6a0339b531c120dcaadd22d25e9
+++ guitone/res/i18n/guitone_de.ts      0b4715dc296b1955b0707923d45d79ca7769dd3f
@@ -1,6 +1,14 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!DOCTYPE TS><TS version="1.1">
 <context>
+    <name>AncestryGraph</name>
+    <message>
[...]
@end verbatim

@item Output format:

The GNU unified diff format. If there have been no content changes, the output
is empty.

@item Error conditions:

If more than two revisions are given or a workspace is required, but
not found, prints to stderr and exits with status 1. If one or more file 
restrictions can't be applied, the command prints to stderr and exits as well.

@end table

@item mtn automate get_file @var{id}

@table @strong
@item Arguments:

The  @var{id} argument specifies the file hash of the file to be output.

@item Added in:

1.0

@item Purpose:

Prints the contents of the specified file.

@item Sample output:

@verbatim
If you've downloaded a release, see INSTALL for installation
instructions.  If you've checked this out, the generated files are not
included, and you must use "autoreconf --install" to create them.

"make html" for docs, or read the .info file and / or man page.
@end verbatim

@item Output format:

The file contents are output without modification.

@item Error conditions:

If the file id specified is unknown or invalid prints an error message
to stderr and exits with status 1.

@end table

@item mtn automate get_file_of @var{filename} [--revision=@var{id}]

@table @strong
@item Arguments:

The  @var{filename} argument specifies the filename of the file to be output.

If a revision @var{id} is given, the file's contents in that specific revision
are printed. If no revision is given, the workspace's revision is used.

@item Added in:

4.0

@item Purpose:

Prints the contents of the specified file.

@item Sample output:

@verbatim
If you've downloaded a release, see INSTALL for installation
instructions.  If you've checked this out, the generated files are not
included, and you must use "autoreconf --install" to create them.

"make html" for docs, or read the .info file and / or man page.
@end verbatim

@item Output format:

The file contents are output without modification.

@item Error conditions:

If the filename specified is unknown in the given revision or invalid, or
if the given revision is unknown, prints an error message to stderr and exits
with status 1.

@end table

@item mtn automate get_option @var{option}

@table @strong
@item Arguments:

The @var{option} argument specifies the option name of the option to be output.

@item Added in:

3.1

@item Purpose:

Prints an option from _MTN/option of the current workspace.

@item Sample output:

@verbatim
net.venge.monotone
@end verbatim

@item Output format:

The option value is written out without modification.

@item Error conditions:

If the option is unknown, prints an error message to stderr and exits
with status 1.

@end table


@item mtn automate keys

@table @strong
@item Arguments:

None.

@item Added in:

1.1

@item Purpose:

Print all keys in basic_io format.

@item Sample output:

@verbatim
            name "tbrownaw@gmail.com"
     public_hash [475055ec71ad48f5dfaf875b0fea597b5cbbee64]
    private_hash [7f76dae3f91bb48f80f1871856d9d519770b7f8a]
 public_location "database" "keystore"
private_location "keystore"

           name "tomfa@debian.org"
    public_hash [3ac4afcd86af28413b0a23b7d22b9401e15027fc]
public_location "database"

            name "underwater@fishtank.net"
     public_hash [115fdc73d87a5e9901d018462b21a1f53eca33a1]
    private_hash [b520d2cfe7d30e4ea1725fc4f34646fc5469b13d]
 public_location "keystore"
private_location "keystore"

@end verbatim

@item Output format:

For each key, a basic_io stanza is printed. The public_location and
private_location items may have multiple values as shown above for public_location, one value for each place that the key is stored. If the
private key does not exist, then the private_hash and private_location
items will be absent. The keys are ordered alphabetically by name.

@item Error conditions:

None.

@end table

@item mtn automate packet_for_rdata @var{id}

@table @strong
@item Arguments:

The @var{id} specifies the revision to output an rdata packet for.

@item Added in:

2.0

@item Purpose:

Prints the revision data in packet format

@item Sample output:

@verbatim
[rdata bdf3b10b5df0f17cc6c1b4b3351d84701bda59ed]
H4sIAAAAAAAA/0XQS27DMAwE0L1PIfgArb4kte62NzACg5SoJEBsF7aRurev0UVzgJl5mLas
E+/jU9ftvsymd33Xzfo9Tjzfm267GSgGwVarz6Valx0KtFYwii9VqUFCqJQ5X7puedRx1ef9
r2rwHlSbi+BUSrF4xn1p0RInkmxTbmwREp/BL97LzfQfN56v+rlc+860dZnMED01jhILkURJ
Ul0KPpGN1ueUwDHyiXF66Ywx+2IGD+0Uqg8aCzikAEzZNRXPmJKlkhMxSHuNzrofx/uq2/J4
6njV/bZsu/zMPOlbOY4XJSD5KOrwXGdwpDGdfotZayQHKTAi5fRPqUWKcAMMIQfAjOK0nkfm
6tFacjYgBPV46X4BtlpiNYUBAAA=
[end]
@end verbatim

@item Output format:

Revision data in @command{monotone read} compatible packet format.

@item Error conditions:

If @var{id} is unknown or invalid prints an error message to stderr
and exits with status 1.

@end table

@item mtn automate packet_for_certs @var{id}

@table @strong
@item Arguments:

The @var{id} specifies the revision to output cert packets for.

@item Added in:

2.0

@item Purpose:

Prints the certs associated with a revision in packet format

@item Sample output:

@verbatim
[rcert bdf3b10b5df0f17cc6c1b4b3351d84701bda59ed
       branch
       njs@pobox.com
       bmV0LnZlbmdlLm1vbm90b25l]
K90i1XHHmaMEMuwbPifFweLThJl0m7jigh2Qq6Z7TBwNJ6IMOjXWCizv73cacZ1CtzxFDVwQ
SlqhNWiPQWxdcMp+Uuo+V8IFMKmvxVSTuVDukLMuNAQqpGL5S+a+tEj68NMq+KLKuL8kAAPc
RoFD7GQlTS35S3RHWA4cnvqn+8U=
[end]
[rcert bdf3b10b5df0f17cc6c1b4b3351d84701bda59ed
       date
       njs@pobox.com
       MjAwNi0wNC0wOFQxMTo1MDowMA==]
araz9A8x6AlK6m6UhwnhUhk7cdyxeE2nvzj2gwaDvkaBxOq4SN23/wnaPqUXx1Ddn8smzyRY
HN08xloYc0yNChp3wjbqx20REcsTg3XE4rN/sgCbqqw5hVT22a5ZhqkfkDeoeJvan0R0UBax
ngKYo9eLuABNlmFX2onca75JW1E=
[end]
[rcert bdf3b10b5df0f17cc6c1b4b3351d84701bda59ed
       author
       njs@pobox.com
       bmpzQHBvYm94LmNvbQ==]
BLPOYhgLsAN+w7CwOsv9GfXnG3u7RNF1DTrWdn0AnYE1e+ptgTeMVWUI18H4OGL0B7wm08rv
Pxk/hvsb8fBn1Kf5HDDO2pbjJ0xVzI9+p+TR0y5jJNZlVSTj+nvtPgvK9NzsdooYWnwlWmJv
bOkAzQcZb8NMh8pbQkdHbR5uzMo=
[end]
[rcert bdf3b10b5df0f17cc6c1b4b3351d84701bda59ed
       changelog
       njs@pobox.com
       MjAwNi0wNC0wOCAgTmF0aGFuaWVsIFNtaXRoICA8bmpzQHBvYm94LmNvbT4KCgkqIG5ldHh4
L3Jlc29sdmVfZ2V0aG9zdGJ5bmFtZS5jeHggKHJlc29sdmVfaG9zdG5hbWUpOiAjaWZkZWYg
b3V0CglXaW4zMi1pbmNvbXBhdGlibGUgZXJyb3IgcmVwb3J0aW5nIGNhbGwuCg==]
Ncl4L/oEPctzVQixTKA6FrLceeHnLiXfeyeFDNmtUFYg9BMUcjWkeyKmaWknLvOcHortxjto
K6pQ9E8S7zI+TpzFAhssg5a///rFL0+2GJU3t6pcHs6LC0Q4tbqzwKd/5+8GwT1gphbM1wm7
KuzKthwqD3pp49GbgTrp8iWMTr0=
[end]
@end verbatim

@item Output format:

Cert data in @command{monotone read} compatible packet format.

@item Error conditions:

If @var{id} is unknown or invalid prints an error message to stderr
and exits with status 1.

@end table

@item mtn automate packet_for_fdata @var{id}

@table @strong
@item Arguments:

The @var{id} specifies the file to output an fdata packet for.

@item Added in:

2.0

@item Purpose:

Prints the file data in packet format

@item Sample output:

@verbatim
[fdata 229c7f621b65f7e4970ae5aaec993812b9daa1d4]
H4sIAAAAAAAA/z2OO27DMBBEe51ioMaNrJzBpQAjTXKBBTW0CJPcgFw6yO1DCkG62Q/em83j
R9vlRez6naPKzh2CwkipXFBJbO8fn7f7HV4LQq4mMYoFzdMYSnMj1xXY/lnuoHt2kB2hQpst
PREPZhaxvvchskIKkdU6xsXWvQsk76MOUquGVolZmmmh0+xxvf7JZ5jCFXbU4KZ1muYkT+Kw
FOez5q6uLuh9+9eoQawhez3Fp+VtHJNkfMmDHfALzWYfcAgBAAA=
[end]
@end verbatim

@item Output format:

File data in @command{monotone read} compatible packet format.

@item Error conditions:

If @var{id} is unknown or invalid prints an error message to stderr
and exits with status 1.

@end table

@item mtn automate packet_for_fdelta @var{from-id} @var{to-id}

@table @strong
@item Arguments:

The @var{from-id} specifies the file to use as the base of the delta,
and @var{to-id} specifies the file to use as the target of the delta.

@item Added in:

2.0

@item Purpose:

Prints the file delta in packet format

@item Sample output:

@verbatim
[fdelta 597049a62d0a2e6af7df0b19f4945ec7d6458727
        229c7f621b65f7e4970ae5aaec993812b9daa1d4]
H4sIAAAAAAAA/0WOy0oEMRBF9/mKS2/c9LQg4t5lw+BGf6BIKtNhkpSkKop/b9II7m49OOfu
eHp5dnvEj/SHL0aQ75qFAgcQGmcm5RXKjP3t/eP1ekWUhlTVKGeyJNXNoXU/s27AP8sf7O8D
ZEdSSLd1JMaNKzeysY8ps4Iao4oNjM99eFdQDbMOSldDV8ZC3aSxlxpxufzJF5jANx6oyS2b
c0uhO+OwkpezZhCvK0bf8TVrMLZUo5zi0/I4j4UqPunGA+B+AfHvKEIPAQAA
[end]
@end verbatim

@item Output format:

File delta data in @command{monotone read} compatible packet format.

@item Error conditions:

If @var{from-id} or @var{to-id} is unknown or invalid prints an error
message to stderr and exits with status 1.

@end table

@item mtn automate get_content_changed @var{id} @var{file}

@table @strong
@item Arguments:

The @var{id} specifies a revision ID, from which content change calculations will be based.
and @var{file} specifies the file for which to calculate revisions in which it was last changed.

@item Added in:

3.2

@item Purpose:

Returns a list of revision IDs in which the content  was most recently changed, relative to the revision ID specified as @var{id}. This equates to a content mark following the *-merge algorithm.

@item Sample output:

@verbatim
  content_mark [276264b0b3f1e70fc1835a700e6e61bdbe4c3f2f]
@end verbatim

@item Output format:

Zero or more basic_io stanzas, each specifying a revision ID in which a content mark is set.

The complete format:
@verbatim
'content_mark'
         the hexadecimal id of the revision the content mark is attached to
@end verbatim

@item Error conditions:

If @var{id} or @var{file} is unknown or invalid prints an error
message to stderr and exits with status 1.

@end table

@item mtn automate get_corresponding_path @var{source_id} @var{file} @var{target_id}

@table @strong
@item Arguments:

The @var{source_id} specifies a revision ID in which @var{file} is current extant.
and @var{file} specifies the file whose name in @var{target_id} is to be determined; 
@var{target_id} specifies a revision ID.

@item Added in:

3.2

@item Purpose:

Given a the file name @var{file} in the source revision @var{source_id}, a filename 
will if possible be returned naming the file in the target revision @var{target_id}. 
This allows the same file to be matched between revisions, accounting 
for renames and other changes.

@item Sample output:

@verbatim
file "foo"
@end verbatim

@item Output format:

Zero or one basic_io stanzas. Zero stanzas will be output if the file does not exist within the target revision; this is not considered an error. If the file does exist in the target revision, a single stanza with the  following details is output.

The complete format:
@verbatim
   'file'
         the file name corresponding to "file name" (arg 2) in the target revision
@end verbatim

@item Error conditions:

If the revision IDs @var{source_id} or @var{target_id} are unknown or invalid prints an error
message to stderr and exits with status 1. If the file path @var{file} does not exist in the 
revision @var{source_id} or is invalid, prints an error message to stderr and exits with status 
1. Note that @var{file} not existing in the revision @var{target_id} is not an error.

@end table

@item mtn automate db_get @var{domain} @var{name}

@table @strong 
@item Arguments:

The @var{domain} and @var{name} specify the database variable 
which is returned.

@item Added in:

4.1

@item Purpose:

Read a database variable, see also @ref{Vars}.

@item Sample output:

@verbatim 
off.net 
@end verbatim

@item Output format:

Exactly the variable's content. Since this command is mainly intended for 
@command{automate stdio} it will not add a trailing newline.

@item Error conditions:

If the variable is unknown prints an error message to stderr and exits with
status 1.

@end table

@item mtn automate db_put @var{domain} @var{name} @var{value}

@table @strong
@item Arguments:

The @var{domain} and @var{name} specify the database variable 
which is changed to @var{value}.

@item Added in:

4.1

@item Purpose:

Change a database variable, see also @ref{Vars}.

@item Sample usage:

@verbatim 
mtn automate db_set database default-server off.net 
@end verbatim

@item Output format:

No output.

@item Error conditions:

None.

@end table

@item mtn automate put_file [@var{base-id}] @var{contents}

@table @strong 
@item Arguments:

The optional @var{base-id} specifies a file-id on which the contents are
based on. This is used for delta encoding. @var{contents} are the contents of
the new file.

@item Added in:

4.1

@item Purpose:

Preparation of a workspace-less commit. 
See also @command{automate put_revision}. Normally used via 
@command{automate stdio}.

@item Sample output:

@verbatim 
70a0f283898a18815a83df37c902e5f1492e9aa2 
@end verbatim

@item Output format:

The sha1 sum of the contents, hex encoded.

@item Error conditions:

If the optional base id is unknown prints an error message to stderr and 
exits with status 1.

@end table

@item mtn automate put_revision @var{revision-data}

@table @strong 
@item Arguments:

@var{revision-data} is the new revision. See example below.  Note that
the new_manifest entry is ignored -- @command{put_revision} will
ignore whatever you put here and calculate the correct manifest id
itself.  (However, for now, you must put 40 hex digits here -- it's
just that which particular digits you put are entirely irrelevant.
All zeros is a good choice.)  Monotone will also canonicalize your
whitespace automatically.  You do not need to worry about getting just
the right amount of indentation in front of each line.  However,
everything else about your revision must be valid.

@item Added in:

4.1

@item Purpose:

Workspace-less commit. Normally used via @command{automate stdio}.

@item Sample argument:

@smallexample
@group
format_version "1"

new_manifest [0000000000000000000000000000000000000004]

old_revision []

add_dir ""

add_file "foo"
content [5bf1fd927dfb8679496a2e6cf00cbe50c1c87145]
@end group
@end smallexample

@item Sample output:

@verbatim 
4c2c1d846fa561601254200918fba1fd71e6795d 
@end verbatim

@item Output format:

The new revision id, hex encoded.

@item Error conditions:

If the changeset is invalid prints an error message to stderr and 
exits with status 1. May abort on invalid formats.  If the revision is
already present in the database, prints a message to stderr noting
this fact, but otherwise works as normal.

@end table

@item mtn automate cert @var{revision} @var{name} @var{value}

@table @strong 
@item Arguments:

@var{revision} is an existing revision, @var{name} is the certificate name
and @var{value} its value.

@item Added in:

4.1

@item Purpose:

@command{automate stdio} capable variant of @command{mtn cert}. To sign the
cert with a specific private key, use @option{--key}.

@item Sample usage:

@verbatim 
mtn automate cert 4c2c1d846fa561601254200918fba1fd71e6795d author tester@test.net 
@end verbatim

@item Output format:

No output.

@item Error conditions:

If the revision is invalid prints an error message to stderr and 
exits with status 1.

@end table

@end ftable

@page
@node    RCS
@section RCS

@ftable @command
@item mtn rcs_import @var{filename...}

This command imports all the file versions in each RCS file listed in
@var{filename...}.  These files should be raw RCS files, ending in
@code{,v}. Monotone parses them directly and inserts them into your
database.  Note that this does not do any revision reconstruction, and
is only useful for debugging.

@item mtn cvs_import @var{pathname}

This command imports all the file versions in each RCS file found in the
tree of files starting at @var{pathname}, then reconstructs the
tree-wide history of logical changes by comparing RCS time stamps and
change log entries. For each logical tree-wide change, monotone
synthesizes a manifest and revision, and commits them (along with all
associated file deltas) to your database. It also copies all change log
entries, author identifiers, and date stamps to manifest certificates.

In normal use, @var{pathname} will be a CVS module, though it is
possible to point it at a directory within a module as well.  Whatever
directory you point it at will become the root of monotone's version of
the tree.

@end ftable


@node    Hook Reference
@chapter Hook Reference

Monotone's behavior can be customized and extended by writing
@dfn{hook functions}, which are written in the
@uref{http://www.lua.org, Lua} programming language. At certain points
in time, when monotone is running, it will call a hook function to
help it make a decision or perform some action.  If you provide a hook
function definition which suits your preferences, monotone will
execute it. This way you can modify how monotone behaves.

You can put new definitions for any of these hook functions in a file
@file{$HOME/.monotone/monotonerc}, or in your workspace in
@file{_MTN/monotonerc}, both of which will be read every time monotone
runs. Definitions in @file{_MTN/monotonerc} shadow (override)
definitions made in your @file{$HOME/.monotone/monotonerc}. You can also tell
monotone to interpret extra hook functions from any other @var{file}
using the @option{--rcfile=@var{file}} option; hooks defined in files
specified on the command-line will shadow hooks from the the automatic
files.
By specifying @option{--rcfile=@var{directory}} you can automatically
load all the files contained into @var{directory}.

Monotone provides some default hooks, see @ref{Default hooks} for their
complete source. When writing new hooks, it may be helpful to reuse some code
from the default ones. Since Lua is a lexically scoped language with closures,
this can be achieved with the following code:

@smallexample
@group
do
	local old_hook = default_hook
	function default_hook(arg)
		if not old_hook(arg) then
			-- do other stuff
		end
	end
end
@end group
@end smallexample

Now the default hook is trapped in a variable local to this block, and can
only be seen by the new hook. Since in Lua variables default to the global
scope, the new hook is seen from inside monotone.

Monotone also makes available to hook writers a number of helper
functions exposing functionality not available with standard Lua.

@menu
* Hooks::                     All hooks called by monotone.
* Additional Lua Functions::  Extra functionality available to hook writers.
@end menu

@page
@node   Hooks
@section Hooks

This section documents the existing hook functions and their default
definitions. 

@subsection Event Notifications and Triggers

There are a number of hooks that are called when noteworthy events
occur, such as commits or new revisions arriving over the network. These
hooks can be used to feed the events into external notification systems,
such as generating email.

By default, these hooks are undefined, so no special external actions
are taken.

@ftable @code
@item note_commit (@var{new_id}, @var{revision}, @var{certs})

Called by monotone after the version @var{new_id} is committed. The
second parameter, @var{revision} is the text of the revision, what would
be given by @command{mtn automate get_revision @var{new_id}}. The third
parameter, @var{certs}, is a Lua table containing the set of certificate
names and values committed along with this version. There is no default
definition for this hook. 

Note that since the @var{certs} table does not contain cryptographic
or trust information, and only contains one entry per cert name, it is
an incomplete source of information about the committed version. This
hook is only intended as an aid for integrating monotone with informal
commit-notification systems such as mailing lists or news services. It
should not perform any security-critical operations.

@item note_netsync_start (@var{session_id}, @var{my_role}, @var{sync_type},
@var{remote_host}, @var{remote_keyname}, @var{includes}, @var{excludes})

Called by monotone before any other of the netsync notification hooks
are called.  The @var{session_id} helps keep track of the current netsync
session in case several are happening at the same time, and is used
throughout all netsync notification hooks.

The other arguments are:

@table @strong

@item @var{my_role}

This will be either "client" or "server".

@item @var{sync_type}

This will be one of "sync", "push", or "pull".

@item @var{remote_host}

The network address of the remote host. At the client, this will be the name
it was told to connect to; at the server, this will use the numerical IP address
the connection was received from.

@item @var{remote_keyname}

The name of the key being used by the other end of the connection. This may be
set to "-unknown-" at the server if the key used by the client is not present
at the server.

@item @var{includes} and @var{excludes}

The include and exclude patterns used by the client.

@end table

@item note_netsync_revision_received (@var{new_id}, @var{revision}, @var{certs}, @var{session_id})

Called by monotone after the revision @var{new_id} is received through
netsync. @var{revision} is the text of the revision, what would be given
by @command{mtn automate get_revision @var{new_id}}. @var{certs} is a
Lua table containing one subtable for each cert attached to the revision
@var{new_id}. These subtables have fields named "key", "name", and
"value", containing the signing key for the cert, the name of the cert,
and the value of the cert. There is no default definition for this hook.
@var{session_id} is used together with @code{note_netsync_start} and
@code{note_netsync_end}.  If you're not interested in that type of
tracking, you can ignore that variable entirely.

@item note_netsync_cert_received (@var{rev_id}, @var{key}, @var{name}, @var{value}, @var{session_id})

Called by monotone after a cert is received through netsync, if the revision
that the cert is attached to was not also received in the same netsync
operation. @var{rev_id} is the revision id that the cert is attached to,
@var{key} is the key that the cert is signed with, @var{name} is the name
of the cert, and @var{value} is the cert value. There is no default
definition for this hook. 
@var{session_id} is used together with @code{note_netsync_start} and
@code{note_netsync_end}.  If you're not interested in that type of
tracking, you can ignore that variable entirely.

@item note_netsync_pubkey_received (@var{keyname}, @var{session_id})

Called by monotone after a pubkey is received through netsync. @var{keyname}
is the name of the key received. There is no default definition for this hook. 
@var{session_id} is used together with @code{note_netsync_start} and
@code{note_netsync_end}.  If you're not interested in that type of
tracking, you can ignore that variable entirely.

@item note_netsync_end (@var{session_id}, @var{status},
@var{bytes_in}, @var{bytes_out}, @var{certs_in}, @var{certs_out},
@var{revs_in}, @var{revs_out}, @var{keys_in}, @var{keys_out})

Called by monotone after all other the netsync notification hooks have
been called.  This hook would usually be used for post-netsync purposes,
like collecting all the data from all other netsync notification hooks,
make some nice output from them and finally send the result somewhere.
It could also be used to prepare parallel databases with all the data
to be displayed through something like viewmtn.

@var{status} is a three digit integer that tells whether there was an error,
and if so what kind of error it was:

@table @strong

@item 200

No error, connection successful.

@item 211

The connection was interrupted after some data may have been transferred.

@item 212

The connection was interrupted before any data could be transferred.

@item 412

The request is not permitted.

@item 422

The client tried to use a key that the server doesn't know about.

@item 432

The client and server have different epochs for a branch.

@item 512

Protocol error (source/sink confusion).

@item 521

Protocol error (packet received at a time when it doesn't make sense).

@item 532

The client did not identify itself correctly. (Possible replay attack?)

@end table

In general, 2xx means there was no error, 4xx means there was a permissions
error, and 5xx means there was a protocol error. xx1 means some data may
have been transferred, xx2 means no data was transferred, and xx0 means all
data was transferred.

@item note_mtn_startup (...)

Called by monotone when it is first started, this hook was added so that
usage of monotone could be monitored for user interface testing.  Note
that by default, no monitoring occurs.  The arguments to the hook
function are the arguments to monotone, without the initial
@command{mtn} command.  They can be accessed through the lua @var{arg}
variable which contains the variable list of arguments.

@end ftable

@subsection User Defaults

These are hooks that can be used to provide smart, context-sensitive
default values for a number of parameters the user might otherwise be
prompted for.

@ftable @code
@item get_branch_key (@var{branchname})

Returns a string which is the name of an @sc{rsa} private key used to sign
certificates in a particular branch @var{branchname}. There is no
default definition for this hook. The command-line option
@option{--key=@var{keyname}} overrides any value returned from this
hook function. If you have only one private key in your database, you
do not need to define this function or provide a
@option{--key=@var{keyname}} option; monotone will guess that you want
to use the unique private key.

@item get_passphrase (@var{keypair_id})

Returns a string which is the passphrase used to encrypt the private
half of @var{keypair_id} in your database, using the @sc{arc4} symmetric
cipher.  @var{keypair_id} is a Lua string containing the label that you
used when you created your key --- something like
@code{"nicole@@example.com"}.  This hook has no default definition. If
this hook is not defined or returns false, monotone will prompt you for
a passphrase each time it needs to use a private key.

@item get_author (@var{branchname}, @var{keypair_id})

Returns a string which is used as a value for automatically generated
@code{author} certificates when you commit changes to
@var{branchname} with the keypair identity @var{keypair_id}.  Generally
this hook remains undefined, and monotone selects your signing key name
for the author certificate. You can use this hook to override that
choice, if you like.

This hook has no default definition, but a couple of possible
definitions might be:
@smallexample
@group
function get_author(branchname, keypair_id)
        -- Key pair identity ignored.
        local user = os.getenv("USER")
        local host = os.getenv("HOSTNAME")
        if ((user == nil) or (host == nil)) then return nil end
        return string.format("%s@@%s", user, host)
end
@end group
@end smallexample
@smallexample
@group
function get_author(branchname, keypair_id)
        -- Branch name ignored.
        if (keypair_id == "joe@@example.com") then
                return "Joe Random <joe@@example.com>"
        end
        return keypair_id
end
@end group
@end smallexample

@item edit_comment (@var{commentary}, @var{user_log_message})

Returns a log entry for a given set of changes, described in
@var{commentary}.  The commentary is identical to the output of
@command{mtn status}. This hook is intended to interface with
some sort of editor, so that you can interactively document each
change you make. The result is used as the value for a
@code{changelog} certificate, automatically generated when you commit
changes.

The contents of @file{_MTN/log} are read and passed as
@var{user_log_message}. This allows you to document your changes as
you proceed instead of waiting until you are ready to commit. Upon
a successful commit, the contents of @file{_MTN/log} are erased setting
the system up for another edit/commit cycle.

For the default definition of this hook, see @ref{Default hooks}.

@item persist_phrase_ok ()

Returns @code{true} if you want monotone to remember the passphrase of
a private key for the duration of a single command, or @code{false} if
you want monotone to prompt you for a passphrase for each certificate
it generates. Since monotone often generates several certificates in 
quick succession, unless you are very concerned about security you
probably want this hook to return @code{true}.

The default definition of this hook is:
@smallexample
@group
function persist_phrase_ok()
        return true
end
@end group
@end smallexample

@item use_inodeprints ()

Returns @code{true} if you want monotone to automatically enable
@ref{Inodeprints} support in all workspaces.  Only affects working
copies created after you modify the hook.

The default definition of this hook is:
@smallexample
@group
function use_inodeprints()
        return false
end
@end group
@end smallexample

@item ignore_file (@var{filename})

Returns @code{true} if @var{filename} should be ignored while adding,
dropping, or moving files. Otherwise returns @code{false}. This is
most important when performing recursive actions on directories, which
may affect multiple files simultaneously. 

The default definition of this hook recognises a number of common file
types and extensions for temporary and generated file types that users
typically don't want to track. If the file @file{.mtn-ignore} exists,
this hook will read a list of regular expressions from the file, one per
line, and ignore all files matching one of these expressions. For the
default definition of this hook, see @ref{Default hooks}.

@item ignore_branch (@var{branchname})

Returns @code{true} if @var{branchname} should be ignored while listing
branches. Otherwise returns @code{false}. This hook has no default
definition, therefore the default behavior is to list all branches.

@end ftable

@subsection Netsync Permission Hooks

These hooks are used when running a netsync server, via
@command{mtn serve}. They are evaluated by the server for each new
connection, based on the certificate used for authentication by the
client.  Note that a long-running server will need to be restarted in
order to reload the hook definitions if the @file{montonerc} file is
changed.

@ftable @code
@item get_netsync_read_permitted (@var{branch}, @var{identity})

Returns @code{true} if a peer authenticated as key @var{identity}
should be allowed to read from your database certs, revisions,
manifests, and files associated with @var{branch}; otherwise @code{false}.
The default definition of this hook reads a file @file{read-permissions} in
the configuration directory. This file looks like
@smallexample
@group
pattern "net.example.project.@{private,security@}*"
allow "joe@@example.net"
allow "jim@@example.net"

comment "everyone can read these branches"
pattern "net.example.@{public,project@}*"
allow "*"
@end group
@end smallexample
This example allows everyone access to branches @code{net.example.project} and
@code{net.example.public} and their sub-branches, except for the branches in
@code{net.example.project.security} and @code{net.example.project.private},
which are only readable by Joe and Jim.

The file is divided into stanzas of one @code{pattern} line followed by any
number of @code{allow} and @code{deny} lines, and possibly a @code{continue}
line. Anything from the unquoted word @code{comment} until the next unquoted
word is ignored. A stanza is processed if the argument to
@code{pattern} is a glob that matches @var{branch}. Any keys which match an
@code{allow} line are given access, and any keys which match a @code{deny} line
are denied access. If there is a @code{continue "true"} line, then if the key
is not granted or denied access in this stanza the next matching stanza will be
processed. If there is not a @code{continue "true"} line, then any key which
has not been given access will be denied access even if it doesn't match any
@code{deny} lines. Thus, deny lines are redundant unless there is also a
@code{continue "true"} line.


If a client connects anonymously, this hook will be called with a
@var{identity} of @code{nil}.

Note that the @var{identity} value is a key ID (such as
``@code{graydon@@pobox.com}'') but will correspond to a @emph{unique}
key fingerprint (hash) in your database. Monotone will not permit two
keys in your database to have the same ID. Make sure you confirm the
key fingerprints of each key in your database, as key ID strings are
``convenience names'', not security tokens.

@item get_netsync_write_permitted (@var{identity})

Returns @code{true} if a peer authenticated as key @var{identity} should
be allowed to write into your database certs, revisions, manifests, and
files; otherwise @code{false}. The default definition of this hook reads a file
@file{write-permissions} in the configuration directory which contains a list
of keys, one per line, which are allowed write access. The special value
@code{*} means to allow access to anyone whose public key we already have.

If a client connects anonymously, it will be unconditionally denied
write access; this hook will @emph{not} be called with a @var{identity}
of @code{nil}.

Note that the @var{identity} value is a key ID (such as
``@code{graydon@@pobox.com}'') but will correspond to a @emph{unique}
key fingerprint (hash) in your database. Monotone will not permit two
keys in your database to have the same ID. Make sure you confirm the
key fingerprints of each key in your database, as key ID strings are
``convenience names'', not security tokens.

Note also that, unlike the equivalent read permission hook, the write
permission hook does not take a @var{branch} name as an argument.  There
is presently no way to selectively grant write access to different
branches via netsync, for a number of reasons. Contributions in the
database from different authors can be selectively trusted using the
@ref{Trust Evaluation Hooks} instead.

@end ftable

@anchor{Netsync Transport Hooks}
@subsection Netsync Transport Hooks

When a monotone client initiates a netsync connection, these hooks are
called to attempt to parse the host argument provided on the command
line. If the hooks fail or return nil, monotone will interpret the
host argument as a network name (possibly with a port number) and open
a TCP socket.

@ftable @code
@item get_netsync_connect_command (@var{uri}, @var{args})

Returns a table describing a command to run to connect to the
specified host. The @var{uri} argument is a table containing
between 0 and 7 components:

@itemize
@item @code{uri["scheme"]}, such as @code{"ssh"} or @code{"file"}
@item @code{uri["user"]}, the name of a remote user
@item @code{uri["host"]}, the name or address of a remote host
@item @code{uri["port"]}, a network port number
@item @code{uri["path"]}, a filesystem path
@item @code{uri["query"]}, for additional parameters
@item @code{uri["fragment"]}, to describe a sub-location within the remote resource
@end itemize

The @var{args} argument is a table containing between 0 and 3
components:

@itemize
@item @code{args["include"]}, the branch pattern to include
@item @code{args["exclude"]}, the branch pattern to exclude
@item @code{args["debug"]}, whether to run the connection in debug mode
@end itemize

The default definition of this hook follows:

@smallexample
@group
function get_netsync_connect_command(uri, args)

        local argv = nil

        if uri["scheme"] == "ssh" 
                and uri["host"] 
                and uri["path"] then

                argv = @{ "ssh" @}
                if uri["user"] then
                        table.insert(argv, "-l")
                        table.insert(argv, uri["user"])
                end
                if uri["port"] then
                        table.insert(argv, "-p")
                        table.insert(argv, uri["port"])
                end

                table.insert(argv, uri["host"])
        end
        
        if uri["scheme"] == "file" and uri["path"] then
                argv = @{ @}
        end

        if argv then

                table.insert(argv, get_mtn_command(uri["host"]))

                if args["debug"] then
                        table.insert(argv, "--debug")
                else
                        table.insert(argv, "--quiet")
                end

                table.insert(argv, "--db")
                table.insert(argv, uri["path"])
                table.insert(argv, "serve")
                table.insert(argv, "--stdio")
                table.insert(argv, "--no-transport-auth")

                if args["include"] then
                        table.insert(argv, args["include"])
                end

                if args["exclude"] then
                        table.insert(argv, "--exclude")
                        table.insert(argv, args["exclude"])
                end
        end
        return argv
end
@end group
@end smallexample


@item use_transport_auth (@var{uri})

Returns a boolean indicating whether monotone should use transport
authentication mechanisms when communicating with @var{uri}. If this
hook fails, the return value is assumed to be @code{true}. The form of
the @var{uri} argument is a table, identical to the table provided as
an argument to @code{get_netsync_connect_command}.

Note that the return value of this hook must "match" the semantics of
the command returned by @code{get_netsync_connect_command}. In
particular, if this hook returns @code{false}, the @command{serve}
command line arguments passed to the remote end of the connection
should include the @option{--no-transport-auth} option. A mismatch
between this hook's return value and the command line returned by
@code{get_netsync_connect_command} will cause a communication failure,
as the local and remote monotone processes will have mismatched
authentication assumptions.


@smallexample
@group
function use_transport_auth(uri)
        if uri["scheme"] == "ssh" 
        or uri["scheme"] == "file" then
                return false
        else
                return true
        end
end
@end group
@end smallexample

@item get_mtn_command(@var{host})

Returns a string containing the monotone command to be executed on
@var{host} when communicating over @command{ssh}.  The @var{host}
argument is a string containing the name of the host to which
@command{ssh} is connecting, from the server URI.  This is useful when
there are multiple monotone binaries on the remote host, or the
monotone binary is not in the default path.

@smallexample
@group
function get_mtn_command(host)
	return "mtn"
end
@end group
@end smallexample

@end ftable


@anchor{Trust Evaluation Hooks}
@subsection Trust Evaluation Hooks

Monotone makes heavy use of certs to provide descriptive information
about revisions. In many projects, not all developers should have the
same privileges, or be trusted for the same purposes (indeed, some
signers might be automated robots, with very specific purposes).

These hooks allow the user to configure which signers will be trusted to
make which kinds of assertions using certs. Monotone uses these certs when
selecting available revisions for commands such as @command{update}.

Each user, or even each workspace, can have their own
implementation of these hooks, and thus a different filtered view of
valid revisions, according to their own preferences and purposes.

@ftable @code
@item get_revision_cert_trust (@var{signers}, @var{id}, @var{name}, @var{val})

Returns whether or not you @emph{trust} the assertion
@var{name}=@var{value} on a given revision @var{id}, given a valid
signature from all the keys in @var{signers}. The @var{signers}
parameter is a table containing all the key names which signed this
cert, the other three parameters are strings.

The default definition of this hook simply returns @code{true}, which
corresponds to a form of trust where every key which is defined in
your database is trusted. This is a @emph{weak} trust setting; you
should change it to something stronger. A possible example of a
stronger trust function (along with a utility function for computing
the intersection of tables) is the following:

@smallexample
@group
function intersection(a,b)
   local s=@{@}
   local t=@{@}
   for k,v in pairs(a) do s[v] = 1 end
   for k,v in pairs(b) do if s[v] ~= nil then table.insert(t,v) end end
   return t
end

function get_revision_cert_trust(signers, id, name, val)
   local trusted_signers = @{ "bob@@happyplace.example.com", 
                             "friend@@trustedplace.example.com", 
                             "myself@@home.example.com" @}
   local t = intersection(signers, trusted_signers)

   if t == nil then return false end

   if    (name ~= "branch" and table.getn(t) >= 1)
      or (name == "branch" and table.getn(t) >= 2)
   then
      return true
   else
      return false
   end
end
@end group
@end smallexample

In this example, any revision certificate is trusted if it is signed
by at least one of three ``trusted'' keys, unless it is an
@code{branch} certificate, in which case it must be signed by
@emph{two} or more trusted keys. This is one way of requiring that
the revision has been approved by an extra ``reviewer'' who used the
@command{approve} command.

@item accept_testresult_change (@var{old_results}, @var{new_results})

This hook is used by the update algorithm to determine whether a
change in test results between update source and update target is
acceptable. The hook is called with two tables, each of which maps a
signing key -- representing a particular testsuite -- to a boolean
value indicating whether or not the test run was successful. The
function should return @code{true} if you consider an update from the
version carrying the @var{old_results} to the version carrying the
@var{new_results} to be acceptable.

The default definition of this hook follows:

@smallexample
@group
function accept_testresult_change(old_results, new_results)
   for test,res in pairs(old_results)
   do
      if res == true and new_results[test] ~= true
      then
	 return false
      end
   end
   return true
end
@end group
@end smallexample

This definition accepts only those updates which preserve the set of
@code{true} test results from update source to target. If no test
results exist, this hook has no affect; but once a @code{true} test
result is present, future updates will require it. If you want a more
lenient behavior you must redefine this hook.

@end ftable

@subsection External Diff Tools

Differences between files can be shown in a number of ways, varying
according to user preference and file type. These hooks allow
customisation of the way file differences are shown.

@ftable @code
@item get_encloser_pattern (@var{file_path})

Called for each file when @command{diff} is given the
@option{--show-encloser} option (and @emph{not} the
@option{--external} option).  @var{file_path} is the pathname of the
file that is being diffed.  The hook should return a string constant
containing a regular expression; this regular expression will be used
to find lines that, in that file, name the ``top-level'' constructs
enclosing each ``hunk'' of changes.  The default is
@code{^[[:alnum:]$_]}, which is correct for many programming
languages; a few text authoring packages, like Texinfo, have special
regular expressions that match their particular syntax.  If you have a
better regular expression for some language, you can add it to this
hook; and if you send it to the monotone developers, we will likely
make it to the default for that language.

@item external_diff (@var{file_path}, @var{old_data}, @var{new_data}, @var{is_binary},
                     @var{diff_args}, @var{old_rev}, @var{new_rev})

Called for each file when @command{diff} is given the
@option{--external} option.  @var{file_path} is the pathname of the
file that is being diffed.  @var{old_data} and @var{new_data} are the
data contents of the old and the new file.  If the data is binary,
@var{is_binary} will be true, otherwise false.  @var{old_rev} and
@var{new_rev} are the revision IDs of the old and new data.

If an extra arguments are given via @option{--diff-args}, the string
will be passed in as @var{diff_args}.  Otherwise @var{diff_args} will
be nil.

The default implementation of this hook calls the program @command{diff},
and if @option{--diff-args} were not passed, takes default arguments
from the Lua variable @code{external_diff_default_args}.  You can
override this variable in your configuration file, without overriding
the whole hook.

@end ftable


@subsection External Merge Tools

Monotone often needs to merge together the work of multiple distributed
developers, and uses these hooks to help this process when the merge
does not automatically succeed.  Often these hooks will be used to invoke
an external interactive merge tool.  

The @ref{Default hooks} include helper functions used by the hooks below
to invoke a number of external merge tools known to monotone, and you
can override or extend these hooks if you have a preferred tool, or if
you have a tool specific to certain file types.

@ftable @code
@anchor{merge3}
@item merge3 (@var{ancestor_path}, @var{left_path}, @var{right_path}, @var{merged_path}, @var{ancestor_text}, @var{left_text}, @var{right_text})

This hook is called to resolve merges that monotone could not resolve
automatically.  The actual ancestor, left, and right contents of the
file are passed in the @var{ancestor_text}, @var{left_text}, and
@var{right_text} strings.  In addition, the hook is given the names
that this file had in the ancestor (@var{ancestor_path}), left
(@var{left_path}), and right (@var{right_path}) trees, and the name it
will end up having in the merged tree (@var{merged_path}).  These
paths are useful for merge tools that can display the names of files
in their GUI, since the actual path names are likely more meaningful
than the temporary file names the merge tool will actually be working
on.

Returns a string, which should be the merger of the given texts.  The
default definition of this hook delegates the actual merge to the
result of @ref{get_preferred_merge3_command}.  The default definition
of @ref{get_preferred_merge3_command} checks to see if the
@env{MTN_MERGE} environment variable, or the Lua variable
@code{merger} are set to the name of a merge tool that it recognizes,
and if not, then simply searches for whatever is installed on the
local system.  For details, see the code in @ref{Default hooks}.


@anchor{get_preferred_merge3_command}
@item get_preferred_merge3_command(@var{tbl})

Returns the results of running an external merge on three strings.
@var{tbl} wraps up the various arguments for each merge command and 
is always provided by @ref{merge3}. If there is a particular editor
that you would like to use to perform merge3 operations, override
this hook to specify it. 

@end ftable

@subsection Selector Expansion

Monotone's selectors are a powerful mechanism used to refer to revisions
with symbolic names or groupings. Thanks to the hooks described in this
section, it is possible to use various forms of shorthand in selection
strings; these hooks are designed to recognise shorthand patterns and
expand them to their full form.

For more detail on the use of selectors, see @ref{Selectors}.  

@ftable @code
@item expand_selector (@var{str})

Attempts to expand @var{str} as a selector. Expansion generally means
providing a type prefix for the selector, such as @code{a:} for authors
or @code{d:} for dates. This hook is called once for each element of a
combined selector string (between @code{/} separators) prior to
evaluation of the selector. For the default definition of this hook, see
@ref{Default hooks}.

@item expand_date (@var{str})

Attempts to expand @var{str} as a date expression. Expansion means
recognizing and interpreting special words such as @code{yesterday} or
@code{6 months ago} and converting them into well formed date
expressions. For the default definition of this hook, see @ref{Default
hooks}.

@end ftable

@subsection Attribute Handling

Some files in a project are special; they may require different handling
(such as binary or structured files that should always be manually
merged -- see @ref{Merging}), or they may represent executable scripts
or programs.

Monotone allows each file (or directory) in a repository to carry
arbitrary @ref{File Attributes}.  Persistent attributes are stored
each revision's manifest. The hooks in this section allow files to be
automatically recognised as having certain attributes at the time
they're added, and for custom triggers to be invoked on each file
according to its attributes when the workspace is changed.

@ftable @code
@item attr_functions [@var{attribute}] (@var{filename}, @var{value})

This is not a hook function, but a @emph{table} of hook
functions. Each entry in the table @code{attr_functions}, at table
entry @var{attribute}, is a function taking a file name @var{filename}
and a attribute value @var{value}. The function should ``apply'' the 
attribute to the file, possibly in a platform-specific way.

Hook functions from this table are called for each existing attr,
after any command which modifies the workspace. This facility can
be used to extend monotone's understanding of files with
platform-specific attributes, such as permission bits, access control
lists, or special file types.

By default, there is only one entry in this table, for the @code{mtn:execute}
attribute. Its definition is:

@smallexample
@group
attr_functions["mtn:execute"] = 
  function(filename, value) 
        if (value == "true") then
         make_executable(filename)
      end
   end
@end group
@end smallexample

@item attr_init_functions [@var{attribute}] (@var{filename})

This is not a hook function, but a @emph{table} of hook
functions. Each entry in the table @code{attr_init_functions}, at
table entry @var{attribute}, is a function taking a file (or
directory) name @var{filename}. Each function defines the attributes
that should be set on the file named @var{filename}. This table of
hook functions is called once for each file during an @dfn{add}.

By default, there are only two entries in this table, for the
@code{mtn:execute} and @code{mtn:manual_merge} attributes. Their
definition is:

@smallexample
@group
attr_init_functions["mtn:execute"] = 
   function(filename)
      if (is_executable(filename)) then 
        return "true" 
      else 
        return nil 
      end
   end
attr_init_functions["mtn:manual_merge"] = 
   function(filename)
      if (binary_file(filename)) then 
        return "true" -- binary files must be merged manually
      else 
        return nil
      end 
   end
@end group
@end smallexample

The @code{binary_file} function is also defined as a Lua hook. See
@ref{Default hooks}. 

@end ftable

@subsection Validation Hooks

If there is a policy decision to make, Monotone defines certain hooks to
allow a client to validate or reject certain behaviors.

@ftable @code
@item validate_commit_message (@var{message}, @var{revision_text}, @var{branchname})

This hook is called after the user has entered his/her commit message.
@var{message} is the commit message that the user has entered and 
@var{revision_text} is the full text of the changes for this revision,
which can be parsed with the parse_basic_io function. The @var{branchname} on
which the new revision will be committed if all goes well is passed in as the third
parameter.
If the hook finds the commit message satisfactory, it can return @code{true,
""}. If it finds fault, then it can return @code{false, reason} where
@var{reason} is the reason the message was rejected. By default, this hook
rejects empty log messages.

@end ftable

@page
@node   Additional Lua Functions
@section Additional Lua Functions

This section documents the additional Lua functions made available to
hook writers. 

@ftable @code

@item existonpath(@var{possible_command})

This function receives a string containing the name of an external
program and returns 0 if it exists on path and is executable, -1
otherwise. 
As an example, @code{existonpath("xxdiff")} returns 0 if the
program xxdiff is available.
On Windows, this function automatically appends ``.exe'' to the
program name. In the previous example, @code{existonpath} would search
for ``xxdiff.exe''.

@item get_confdir()

Returns the path to the configuration directory, either implied or given
with @option{--confdir}.

@item get_ostype()

Returns the operating system flavor as a string.

@item guess_binary_file_contents(@var{filespec})

Returns true if the file appears to be binary, i.e. contains one or
more of the following characters:
@smallexample
@group
0x00 thru 0x06
0x0E thru 0x1a
0x1c thru 0x1f
@end group
@end smallexample

@item include(@var{scriptfile}) 

This function tries to load and execute the script contained into
scriptfile.  It returns true for success and false if there is an
error. 

@item includedir(@var{scriptpath})

This function loads and executes in alphabetical order all the scripts
contained into the directory scriptpath.
If one of the scripts has an error, the functions doesn't process the
remaining scripts and immediately returns false.

@item includedirpattern(@var{scriptpath}, @var{pattern})

This function loads and executes in alphabetical order all the scripts
contained into the directory scriptpath that match the given pattern.
If one of the scripts has an error, the functions doesn't process the
remaining scripts and immediately returns false.

@item is_executable(@var{filespec})

This function returns true if the file is executable, false
otherwise.  On Windows this function returns always false.

@item kill(@var{pid} [, @var{signal}])

This function calls the kill() C library function on POSIX systems and
TerminateProcess on Win32 (in that case @var{pid} is the process
handle).  If the optional @var{signal} parameter is missing, SIGTERM
will be used. 
Returns 0 on success, -1 on error.

@item make_executable(@var{filespec})

This function marks the named file as executable.  On Windows has no
effect. 

@item match(@var{glob}, @var{string})

Returns true if @var{glob} matches @var{str}, return false otherwise.

@item mkstemp(@var{template})

Like its C library counterpart,  mkstemp creates a unique name and
returns a file descriptor for the newly created file. 
The value of template should be a pointer to a character buffer loaded
with a null-terminated string that consists of contiguous, legal file
ad path name characters followed by six Xs. 
The function mkstemp replaces the Xs by an alpha-numeric sequence
that is chosen to ensure that no file in the chosen directory has that
name. 
Furthermore, subsequent calls to mkstemp within the same process
each yield different file names. 
Unlike other implementations, monotone mkstemp allows the template
string to contain a complete path, not only a filename, allowing users
to create temporary files outside the current directory.

@strong{Important notice:}@*
To create a temporary file, you must use the @code{temp_file()}
function, unless you need to run monotone with the @option{--nostd}
option.  @code{temp_file()} builds on @code{mkstemp()} and creates a
file in the standard TMP/TEMP directories.
For the definition of @code{temp_file()}, see @ref{Default hooks}.

@item parse_basic_io(@var{data})

Parse the string @var{data}, which should be in basic_io format. It returns nil
if it can't parse the string; otherwise it returns a table. This will be a list
of all statements, with each entry being a table having a "name" element that is
the symbol beginning the statement and a "values" element that is a list of all
the arguments.

For example, given this as input:

@smallexample
@group
thingy "foo" "bar"
thingy "baz"
spork
frob "oops"
@end group
@end smallexample

The output table will be:
@smallexample
@group
@{
   1 = @{ name = "thingy", args = @{ 1 = "foo", 2 = "bar" @} @},
   2 = @{ name = "thingy", args = @{ 1 = "baz" @} @},
   3 = @{ name = "spork", args = @{ @} @},
   4 = @{ name = "frob", args = @{ 1 = "oops" @} @}
@}
@end group
@end smallexample

@item regex.search(@var{regexp}, @var{string})

Returns true if a match for @var{regexp} is found in @var{str}, return
false otherwise.

@item sleep(@var{seconds})

Makes the calling process sleep for the specified number of seconds.

@item spawn(@var{executable} [, @var{args ...}])

Starts the named executable with the given arguments.  Returns the
process PID on POSIX systems, the process handle on Win32 or -1 if
there was an error.
Calls fork/execvp on POSIX, CreateProcess on Win32.

@strong{Important notice:}@*
To spawn a process and wait for its completion, use the @code{execute()}
function, unless you need to run monotone with the @option{--nostd}
option.  @code{execute()} builds on @code{spawn()} and @code{wait()}
in a standardized way.

@item spawn_pipe(@var{executable} [, @var{args ...}])

Like spawn(), but returns three values, where the first two are the
subprocess' standard input and standard output, and the last is the
process PID on POSIX systems, the process handle on Win32 or -1 if
there was an error.

@item spawn_redirected(@var{infile}, @var{outfile}, @var{errfile}, @var{executable} [, @var{args ...}])

Like spawn(), but with standard input, standard output and standard
error redirected to the given files.

@item wait(@var{pid})

Wait until the process with given PID (process handle on Win32) exits.
Returns two values: a result value and the exit code of the waited-for
process.
The exit code is meaningful only if the result value is 0.

@end ftable


@node    Special Topics
@chapter Special Topics

This chapter describes some ``special'' issues which are not directly
related to monotone's @emph{use}, but which are occasionally of
interest to people researching monotone or trying to learn the
specifics of how it works. Most users can ignore these sections.

@menu
* Internationalization::   Using monotone in non-English locales.
* Hash Integrity::         Notes on probability and failure.
* Rebuilding ancestry::    In case of corruption.
* Mark-Merge::             The merging algorithm used by Monotone.
@end menu

@page
@node    Internationalization
@section Internationalization

Monotone initially dealt with only ASCII characters, in file path
names, certificate names, key names, and packets. Some
conservative extensions are provided to permit internationalized
use. These extensions can be summarized as follows:

@itemize

@item
Monotone uses GNU gettext to provide localized progress and error
messages. Translations may or may not exist for your locale, but the
infrastructure is present to add them.

@item
All command-line arguments are mapped from your local character set to
UTF-8 before processing. This means that monotone can @emph{only}
handle key names, file names and certificate names which map cleanly
into UTF-8.

@item
Monotone's control files are stored in UTF-8. This includes: revisions
and manifests, both inside the database and when written to the
@file{_MTN/} directory of the workspace; the @file{_MTN/options} and
@file{_MTN/revision} files. Converting these files to any other
character set will cause monotone to break; do not do so.

@item
File path names in the workspace are converted to the locale's
character set (determined via the LANG or CHARSET environment
variables) before monotone interacts with the file system. If you are
accustomed to being able to use file names in your locale's character
set, this should ``just work'' with monotone.

@item
Key and cert names, and similar ``name-like'' entities are subject to
some cleaning and normalization, and conversion into network-safe
subsets of ASCII (typically ACE). Generally, you should be able to use
``sensible'' strings in your locale's character set as names, but they
may appear mangled or escaped in certain contexts such as network
transmission.

@item
Monotone's transmission and storage forms are otherwise
unchanged. Packets and database contents are 7-bit clean ASCII.

@end itemize

The remainder of this section is a precise specification of monotone's
internationalization behavior.

@heading General Terms

@table @asis
@item Character set conversion
The process of mapping a string of bytes representing wide characters
from one encoding to another. Per-file character set conversions are
specified by a Lua hook @code{get_charset_conv} which takes a filename
and returns a table of two strings: the first represents the
"internal" (database) charset, the second represents the "external"
(file system) charset.

@item LDH
Letters, digits, and hyphen: the set of ASCII bytes @code{0x2D},
@code{0x30..0x39}, @code{0x41..0x5A}, and @code{0x61..0x7A}.

@item stringprep
RFC 3454, a general framework for mapping, normalizing, prohibiting
and bidirectionality checking for international names prior to use in
public network protocols.

@item nameprep
RFC 3491, a specific profile of stringprep, used for preparing
international domain names (IDNs)

@item punycode
RFC 3492, a "bootstring" encoding of Unicode into ASCII. 

@item IDNA
RFC 3490, international domain names for applications, a combination
of the above technologies (nameprep, punycoding, limiting to LDH
characters) to form a specific "ASCII compatible encoding" (ACE) of
Unicode, signified by the presence of an "unlikely" ACE prefix string
"xn--". IDNA is intended to make it possible to use Unicode relatively
"safely" over legacy ASCII-based applications. the general picture of
an IDNA string is this:

@smallexample
@group     
      @{ACE-prefix@}@{LDH-sanitized(punycode(nameprep(UTF-8-string)))@}
@end group
@end smallexample

It is important to understand that IDNA encoding does @emph{not}
preserve the input string: it both prohibits a wide variety of
possible strings and normalizes non-equal strings to supposedly
"equivalent" forms.

By default, monotone does @emph{not} decode IDNA when printing to the
console (IDNA names are ASCII, which is a subset of UTF-8, so this
normal form conversion can still apply, albeit oddly). this behavior
is to protect users against security problems associated with
malicious use of "similar-looking" characters. If the hook
@code{display_decoded_idna} returns true, IDNA names are decoded for
display.

@end table
  
@heading Filenames

@itemize

@item
Filenames are subject to normal form conversion. 

@item
Filenames are subject to an additional normal form stage which adjusts
for platform name semantics, for example changing the Windows
@code{0x5C} '\' path separator to @code{0x2F} '/'. This extra
processing is performed by boost::filesystem.

@item
FIXME: Monotone does not properly handle case insensitivity on Windows.

@item
A filename (in normal form) is constrained to be a nonempty sequence
of path components, separated by byte @code{0x2F} (ASCII / ), and
without a leading or trailing @code{0x2F}.

@item
A path component is a nonempty sequence of any UTF-8 character codes
except the path separator byte @code{0x2F} and any ASCII "control codes"
(@code{0x00..0x1F} and @code{0x7F}).

@item
The path components "." and ".." are prohibited.

@item
Manifests and revisions are constructed from the normal form
(UTF-8). The LC_COLLATE locale category is @emph{not} used to sort
manifest or revision entries.

@end itemize

@heading File contents

@itemize
@item
Files are subject to character set conversion and line ending
conversion.

@item
File SHA1 values are calculated from the internal form of the
conversions. If the external form of a file differs from the internal
form, running a 3rd party program such as @command{sha1sum} will produce
different results than those entries shown in a corresponding manifest.

@end itemize

@heading UI messages

UI messages are displayed via calls to @code{gettext()}. 

@heading Host names

Host names are read on the command-line and subject to normal form
conversion. Host names are then split at @code{0x2E} (ASCII '.'), each
component is subject to IDNA encoding, and the components are
rejoined.

After processing, host names are stored internally as ASCII. The
invariant is that a host name inside monotone contains only sequences
of LDH separated by @code{0x2E}.

@heading Cert names

Read on the command line and subject to normal form conversion and
IDNA encoding as a single component. The invariant is that a cert name
inside monotone is a single LDH ASCII string.

@heading Cert values

Cert values may be either text or binary, depending on the return
value of the hook @code{cert_is_binary}. If binary, the cert value is
never printed to the screen (the literal string "<binary>" is
displayed, instead), and is never subjected to line ending or
character conversion. If text, the cert value is subject to normal
form conversion, as well as having all UTF-8 codes corresponding to
ASCII control codes (@code{0x0..0x1F} and @code{0x7F}) prohibited in
the normal form, except @code{0x0A} (ASCII LF).

@heading Var domains

Read on the command line and subject to normal form conversion and IDNA
encoding as a single component. The invariant is that a var domain
inside monotone is a single LDH ASCII string.

@heading Var names and values

Var names and values are assumed to be text, and subject to normal form
conversion.

@heading Key names

Read on the command line and subject to normal form conversion and
IDNA encoding as an email address (split and joined at '.' and '@@'
characters). The invariant is that a key name inside monotone contains
only LDH, @code{0x2E} (ASCII '.') and @code{0x40} (ASCII '@@')
characters.

@heading Packets

Packets are 7-bit ASCII. The characters permitted in packets are
the union of these character sets:

@itemize
@item
The 65 characters of base64 encoding (64 coding + "=" pad).
@item
The 16 characters of hex encoding.
@item
LDH, '@@' and '.' characters, as required for key and cert names.
@item
'[' and ']', the packet delimiters.
@item
ASCII codes 0x0D (CR), 0x0A (LF), 0x09 (HT), and 0x20 (SP). 
@end itemize

@page
@node    Hash Integrity
@section Hash Integrity

Some proponents of a competing, proprietary version control system
have suggested, in a
@uref{http://www.usenix.org/events/hotos03/tech/full_papers/henson/henson_html/,
usenix paper}, that the use of a cryptographic hash function such as
@sc{sha1} as an identifier for a version is unacceptably unsafe. This
section addresses the argument presented in that paper and describes
monotone's additional precautions.

To summarize our position:
@itemize
@item
the analysis in the paper is wrong,
@item
even if it were right, monotone is sufficiently safe.
@end itemize

@heading The analysis is wrong

The paper displays a fundamental lack of understanding about what a
@emph{cryptographic} hash function is, and how it differs from a
normal hash function. Furthermore it confuses accidental collision
with attack scenarios, and mixes up its analysis of the risk involved
in each. We will try to untangle these issues here.

A cryptographic hash function such as @sc{sha1} is more than just a
uniform spread of inputs to an output range. Rather, it must be
designed to withstand attempts at:

@itemize
@item 
reversal: deriving an input value from the output
@item 
collision: finding two different inputs which hash to the same output
@end itemize

Collision is the problem the paper is concerned with. Formally, an
n-bit cryptographic hash should cost @math{2^n} work units to collide
against a given value, and @math{sqrt(2^n)} tries to find a random
pair of colliding values. This latter probability is sometimes called
the hash's ``birthday paradox probability''.

@subheading Accidental collision 

One way of measuring these bounds is by measuring how single-bit
changes in the input affect bits in the hash output. The @sc{sha1}
hash has a strong @emph{avalanche property}, which means that flipping
@emph{any one bit} in the input will cause on average half the 160
bits in the output code to change. The fanciful @sc{val1} hash
presented in the paper does not have such a property --- flipping its
first bit when all the rest are zero causes @emph{no change} to any of
the 160 output bits --- and is completely unsuited for use as a
@emph{cryptographic hash}, regardless of the general shape of its
probability distribution.

The paper also suggests that birthday paradox probability cannot be
used to measure the chance of accidental @sc{sha1} collision on ``real
inputs'', because birthday paradox probability assumes a uniformly
random sample and ``real inputs'' are not uniformly random. The paper
is wrong: the inputs to @sc{sha1} are not what is being measured (and
in any case can be arbitrarily long); the collision probability being
measured is of @emph{output space}. On output space, the hash is
designed to produce uniformly random spread, even given nearly
identical inputs. In other words, it is @emph{a primary design
criterion} of such a hash that a birthday paradox probability is a
valid approximation of its collision probability.

The paper's characterization of risk when hashing ``non-random
inputs'' is similarly deceptive. It presents a fanciful case of a
program which is @emph{storing} every possible 2kb block in a
file system addressed by @sc{sha1} (the program is trying to find a
@sc{sha1} collision). While this scenario @emph{will} very likely
encounter a collision @emph{somewhere} in the course of storing all
such blocks, the paper neglects to mention that we only expect it to
collide after storing about @math{2^{80}} of the @math{2^{16384}} possible
such blocks (not to mention the requirements for compute time to
search, or disk space to store @math{2^{80}} 2kb blocks).

Noting that monotone can only store @math{2^{41}} bytes in a database,
and thus probably some lower number (say @math{2^{32}} or so) active
rows, we consider such birthday paradox probability well out of
practical sight. Perhaps it will be a serious concern when
multi-yottabyte hard disks are common.


@subheading Collision attacks

Setting aside accidental collisions, then, the paper's underlying
theme of vulnerability rests on the assertion that someone will break
@sc{sha1}. Breaking a cryptographic hash usually means finding a way
to collide it trivially. While we note that @sc{sha1} has in fact
resisted attempts at breaking for 8 years already, we cannot say that
it will last forever. Someone might break it. We can say, however,
that finding a way to trivially collide it only changes the resistance
to @emph{active attack}, rather than the behavior of the hash on
benign inputs.

Therefore the vulnerability is not that the hash might suddenly cease
to address benign blocks well, but merely that additional security
precautions might become a requirement to ensure that blocks are
benign, rather than malicious. The paper fails to make this
distinction, suggesting that a hash becomes ``unusable'' when it is
broken. This is plainly not true, as a number of systems continue to
get useful low collision hashing behavior --- just not good security
behavior --- out of ``broken'' cryptographic hashes such as MD4.

@heading Monotone is probably safe anyways

Perhaps our arguments above are unconvincing, or perhaps you are the
sort of person who thinks that practice never lines up with
theory. Fair enough. Below we present @emph{practical} procedures you
can follow to compensate for the supposed threats presented in the
paper.

@subheading Collision attacks

A successful collision attack on @sc{sha1}, as mentioned, does not
disrupt the @emph{probability} features of @sc{sha1} on benign
blocks. So if, at any time, you believe @sc{sha1} is ``broken'', it
does @emph{not} mean that you cannot use it for your work with
monotone. It means, rather, that you cannot base your @emph{trust} on
@sc{sha1} values anymore. You must trust who you communicate with.

The way around this is reasonably simple: if you do not trust
@sc{sha1} to prevent malicious blocks from slipping into your
communications, you can always augment it by enclosing your
communications in more security, such as tunnels or additional
signatures on your email posts. If you choose to do this, you will
still have the benefit of self-identifying blocks, you will simply
cease to trust such blocks unless they come with additional
authentication information.

If in the future @sc{sha1} (or, indeed, @sc{rsa}) becomes accepted as
broken we will naturally upgrade monotone to a newer hash or public
key scheme, and provide migration commands to recalculate existing
databases based on the new algorithm. 

Similarly, if you do not trust our vigilance in keeping up to date
with cryptography literature, you can modify monotone to use any
stronger hash you like, at the cost of isolating your own
communications to a group using the modified version. Monotone is free
software, and runs atop @code{botan}, so it is both legal and
relatively simple to change it to use some other algorithm.

@page
@node    Rebuilding ancestry
@section Rebuilding ancestry

As described in @ref{Historical records}, monotone revisions contain the
@sc{sha1} hashes of their predecessors, which in turn contain the
@sc{sha1} hashes of @emph{their} predecessors, and so on until the
beginning of history.  This means that it is @emph{mathematically
impossible} to modify the history of a revision, without some way to
defeat @sc{sha1}.  This is generally a good thing; having immutable
history is the point of a version control system, after all, and it
turns out to be very important to building a @emph{distributed} version
control system like monotone.

It does have one unfortunate consequence, though.  It means that in the
rare occasion where one @emph{needs} to change a historical revision, it
will change the @sc{sha1} of that revision, which will change the text
of its children, which will change their @sc{sha1}s, and so on;
basically the entire history graph will diverge from that point
(invalidating all certs in the process).

In practice there are two situations where this might be necessary:
@itemize
@item
bugs: monotone has occasionally allowed nonsense, uninterpretable
changesets to be generated and stored in the database, and this was not
detected until further work had been based off of them.
@item
advances in crypto: if or when @sc{sha1} is broken, we will need to
migrate to a different secure hash.
@end itemize
Obviously, we hope neither of these things will happen, and we've taken
lots of precautions against the first recurring; but it is better to be
prepared.

If either of these events occur, we will provide migration commands and
explain how to use them for the situation in question; this much is
necessarily somewhat unpredictable.  In the past we've used the (now
defunct) @command{db rebuild} command, and more recently the @command{db
rosterify} command, for such changes as monotone developed.  These
commands were used to recreate revisions with new formats.  Because the
revision id's changed, all the existing certs that you trust also must
be reissued, signed with your key.@footnote{Regardless of who originally
signed the certs, after the rebuild they will be signed by you.  This
means you should be somewhat careful when rebuilding, but it is
unavoidable --- if you could sign with other people's keys, that would
be a rather serious security problem!}

While such commands can reconstruct the ancestry graph in @emph{your}
database, there are practical problems which arise when working in a
distributed work group.  For example, suppose our group consists of the
fictional developers Jim and Beth, and they need to rebuild their
ancestry graph. Jim performs a rebuild, and sends Beth an email telling
her that he has done so, but the email gets caught by Beth's spam
filter, she doesn't see it, and she blithely syncs her database with
Jim's. This creates a problem: Jim and Beth have combined the
pre-rebuild and post-rebuild databases.  Their databases now contain two
complete, parallel (but possibly overlapping) copies of their project's
ancestry.  The ``bad'' old revisions that they were trying to get rid of
are still there, mixed up with the ``good'' new revisions.

To prevent such messy situations, monotone keeps a table of branch
@dfn{epochs} in each database. An epoch is just a large bit string
associated with a branch. Initially each branch's epoch is zero. Most
monotone commands ignore epochs; they are relevant in only two
circumstances:

@itemize

@item 
When monotone rebuilds ancestry, it generates a new @emph{random}
epoch for each branch in the database.

@item 
When monotone runs netsync between databases, it checks to make sure
that all branches involved in the synchronization have the same
epochs. If any epochs differ, the netsync is aborted with no changes
made to either database. If either side is seeing a branch for the
first time, it adopts the epoch of the other side.

@end itemize

Thus, when a user rebuilds their ancestry graph, they select a new
epoch and thus effectively disassociate with the group of colleagues
they had previously been communicating with. Other members of that
group can then decide whether to follow the rebuild user into a new
group --- by pulling the newly rebuilt ancestry --- or to remain
behind in the old group.

In our example, if Jim and Beth have epochs, Jim's rebuild creates a
new epoch for their branch, in his database.  This causes monotone to
reject netsync operations between Jim and Beth; it doesn't matter if
Beth loses Jim's email. When she tries to synchronize with him, she
receives an error message indicating that the epoch does not
match. She must then discuss the matter with Jim and settle on a new
course of action --- probably pulling Jim's database into a fresh
database on Beth's end -- before future synchronizations will succeed.

@heading Best practices

The previous section described the theory and rationale behind rebuilds
and epochs.  Here we discuss the practical consequences of that
discussion.

If you decide you must rebuild your ancestry graph --- generally by
announcement of a bug from the monotone developers --- the first thing
to do is get everyone to sync their changes with the central server;
if people have unshared changes when the database is rebuilt, they
will have trouble sharing them afterwards.

Next, the project should pick a designated person to take down the
netsync server, rebuild their database, and put the server back up
with the rebuilt ancestry in it.  Everybody else should then pull this
history into a fresh database, check out again from this database, and
continue working as normal.

In complicated situations, where people have private branches, or
ancestries cross organizational boundaries, matters are more complex.
The basic approach is to do a local rebuild, then after carefully
examining the new revision IDs to convince yourself that the rebuilt
graph is the same as the upstream subgraph, use the special @command{db
epoch} commands to force your local epochs to match the upstream ones.
(You may also want to do some fiddling with certs, to avoid getting
duplicate copies of all of them; if this situation ever arises in real
life we'll figure out how exactly that should work.)  Be very careful
when doing this; you're explicitly telling monotone to let you shoot
yourself in the foot, and it will let you.

Fortunately, this process should be extremely rare; with luck, it will
never happen at all.  But this way we're prepared.

@page
@node    Mark-Merge
@section Mark-Merge

Monotone makes use of the Mark-Merge (also known as *-merge) algorithm.
The emails reproduced below document the algorithm. Further information 
can be found at @uref{http://revctrl.org/MarkMerge, revctrl.org}.

@subheading Initial mark-merge proposal

@verbatim
From: Nathaniel Smith <njs <at> pobox.com>
Subject: [cdv-devel] more merging stuff (bit long...)
Newsgroups: gmane.comp.version-control.codeville.devel, gmane.comp.version-control.monotone.devel
Date: 2005-08-06 09:08:09 GMT

I set myself a toy problem a few days ago: is there a really, truly,
right way to merge two heads of an arbitrary DAG, when the object
being merged is as simple as possible: a single scalar value?

I assume that I'm given a graph, and each node in the graph has a
value, and no other annotation; I can add annotations, but they have
to be derived from the values and topology.  Oh, and I assume that no
revision has more than 2 parents; probably things can be generalized
to the case of indegree 3 or higher, but it seems like a reasonable
restriction...

So, anyway, here's what I came up with.  Perhaps you all can tell me
if it makes sense.

User model
----------

Since the goal was to be "really, truly, right", I had to figure out
what exactly that meant... basically, what I'm calling a "user model"
-- a formal definition of how the user thinks about merging, to give
an operational definition of "should conflict" and "should clean
merge".  My rules are these:
  1) whenever a user explicitly sets the value, they express a claim
     that their setting is superior to the old setting
  2) whenever a user chooses to commit a new revision, they implicitly
     affirm the validity of the decisions that led to that revision's
     parents
    Corollary of (1) and (2): whenever a user explicitly sets the
     value, they express that they consider their new setting to be
     superior to _all_ old settings
  3) A "conflict" should occur if, and only if, the settings on each
     side of the merge express parallel claims.
This in itself is not an algorithm, or anything close to it; the hope
is that it's a good description of what people actually want out of a
merge algorithm, expressed clearly enough that we can create an
algorithm that fits these desiderata.

Algorithm
---------

I'll use slightly novel notation.  Lower case letters represent values
that scalar the scalar takes.  Upper case letters represent nodes in
the graph.

Now, here's an algorithm, that is supposed to just be a transcription
of the above rules, one step more formal:
  First, we need to know where users actively expressed an intention.
  Intention is defined by (1), above.  We use * to mark where this
  occurred:

    i)      a*     graph roots are always marked

            a
    ii)     |      no mark, value was not set
            a

            a
    iii)    |      b != a, so b node marked
            b*

          a   b
    iv)    \ / 
            c*
                   c is totally new, so marked
          a   a
           \ / 
            c*

          a   b    we're marking places where users expressed
    v)     \ /     intention; so b should be marked iff this
            b?     was a conflict (!)

          a   a    for now I'm not special-casing the coincidental
    vi)    \ /     clean merge case, so let's consider this to be
            a?     a subclass of (v).

  That's all the cases possible.  So, suppose we go through and
  annotate our graph with *s, using the above rules; we have a graph
  with some *s peppered through it, each * representing one point that
  a user took action.

  Now, a merge algorithm per se: Let's use *(A) to mean the unique
  nearest marked ancestor of node A.  Suppose we want to merge A and
  B.  There are exactly 3 cases:
    - *(A) is an ancestor of B, but not vice versa: B wins.
    - *(B) is an ancestor of A, but not vice versa: A wins.
    - *(A) is _not_ an ancestor of B, and vice versa: conflict,
      escalate to user
  Very intuitive, right?  If B supercedes the intention that led to A,
  then B should win, and vice-versa; if not, the user has expressed
  two conflicting intentions, and that, by definition, is a conflict.

  This lets us clarify what we mean by "was a conflict" in case (v)
  above.  When we have a merge of a and b that gives b, we simple
  calculate *(a); if it is an ancestor of 'b', then we're done, but if
  it isn't, then we mark the merge node.  (Subtle point: this is
  actually not _quite_ the same as detecting whether merging 'a' and
  'b' would have given a conflict; if we somehow managed to get a
  point in the graph that would have clean merged to 'a', but in fact
  was merged to 'b', then this algorithm will still mark the merge
  node.)  For cases where the two parents differ, you have to do this
  using the losing one; for cases where the two parents are the same,
  you should check both, because it could have been a clean merge two
  different ways.  If *(a1) = *(a2), i.e., both sides have the same
  nearest marked ancestor, consider that a clean merge.

  That's all.

Examples
--------

Of course, I haven't shown you this is well-defined or anything, but
to draw out the suspense a little, have some worked examples (like
most places in this document, I draw graphs with two leaves and assume
that those are being merged):

  graph:
       a*
      / \
     a   b*
  result: *(a) is an ancestor of b, but *(b) is not an ancestor of a;
    clean merge with result 'b'.

  graph:
       a*
      / \
     b*  c*
  result: *(b) = b is not an ancestor of c, and *(c) = c is not an
    ancestor of c; conflict.

  graph:
       a*
      / \
     b*  c*  <--- these are both marked, by (iii)
     |\ /|
     | X |
     |/ \|
     b*  c*  <--- which means these were conflicts, and thus marked
  result: the two leaves are both marked, and thus generate a conflict,
    as above.

Right, enough of that.  Math time.

Math
----

Theorem: In a graph marked following the above rules, every node N
  will have a unique least marked ancestor M, and the values of M and N
  will be the same.
Proof: By downwards induction on the graph structure.  The base case
  are graph roots, which by (i) are always marked, so the statement is
  trivially true.  Proceeding by cases, (iii) and (iv) are trivially
  true, since they produce nodes that are themselves marked.  (ii) is
  almost as simple; in a graph 'a' -> 'a', the child obviously
  inherits the parent's unique least marked ancestor, which by
  inductive hypothesis exists.  The interesting case is (v) and (vi):
     a   b
      \ /
       b
  If the child is marked, then again the statement is trivial; so
  suppose it is not.  By definition, this only occurs when *(a) is an
  ancestor of 'b'.  But, by assumption, 'b' has a unique nearest
  ancestor, whose value is 'b'.  Therefore, *(a) is also an ancestor
  of *(b).  If we're in the weird edge case (vi) where a = b, then
  these may be the same ancestor, which is fine.  Otherwise, the fact
  that a != b, and that *(a)'s value = a's value, *(b)'s value = b's
  value, implies that *(a) is a strict ancestor of *(b).  Either way,
  the child has a unique least marked ancestor, and it is the same
  ULMA as its same-valued parent, so the ULMA also has the right
  value.  QED.

Corollary: *(N) is a well-defined function.

Corollary: The three cases mentioned in the merge algorithm are the
  only possible cases.  In particular, it cannot be that *(A) is an
  ancestor of B and *(B) is an ancestor of A simultaneously, unless
  the two values being merged are identical (and why are you running
  your merge algorithm then?).  Or in other words: ambiguous clean
  merge does not exist.
Proof: Suppose *(A) is an ancestor of B, and *(B) is an ancestor of A.
  *(B) is unique, so *(A) must also be an ancestor of *(B).
  Similarly, *(B) must be an ancestor of *(A).  Therefore:
    *(A) = *(B)
  We also have:
    value(*(A)) = value(A)
    value(*(B)) = value(B)
  which implies
    value(A) = value(B).  QED.

Therefore, the above algorithm is well-defined in all possible cases.

We can prove another somewhat interesting fact:
Theorem: If A and B would merge cleanly with A winning, then any
  descendent D of A will also merge cleanly with B, with D winning.
Proof: *(B) is an ancestor of A, and A is an ancestor of D, so *(B) is
  an ancestor of D.

I suspect that this is enough to show that clean merges are order
invariant, but I don't have a proof together ATM.

Not sure what other properties would be interesting to prove; any
suggestions?  It'd be nice to have some sort of proof about "once a
conflict is resolved, you don't have to resolve it again" -- which is
the problem that makes ambiguous clean merge so bad -- but I'm not
sure how to state such a property formally.  Something about it being
possible to fully converge a graph by resolving a finite number of
conflicts or something, perhaps?

Funky cases
-----------

There are two funky cases I know of.

Coincidental clean merge:
    |
    a
   / \
  b*  b*

Two people independently made the same change.  When we're talking
about textual changes, some people argue this should give a conflict
(reasoning that perhaps the same line _should_ be inserted twice).  In
our context that argument doesn't even apply, because these are just
scalars; so obviously this should be a clean merge.  Currently, the
only way this algorithm has to handle this is to treat it as an
"automatically resolved conflict" -- there's a real conflict here, but
the VCS, acting as an agent for the user, may decide to just go ahead
and resolve it, because it knows perfectly well what the user will do.
In this interpretation, everything works fine, all the above stuff
applies; it's somewhat dissatisfying, though, because it's a violation
of the user model -- the user has not necessarily looked at this
merge, but we put the * of user-assertion on the result anyway.  Not a
show-stopper, I guess...

It's quite possible that the above stuff could be generalized to allow
non-unique least marked ancestors, that could only arise in exactly
this case.

I'm not actually sure what the right semantics would be, though.  If
we're merging:
    |
    a
   / \
  b   b
   \ / \
    b   c
Should that be a clean merge?  'b' was set twice, and only one of
these settings was overridden; is that good enough?

Do you still have the same opinion if the graph is:
    |
    a
    |
    b
   / \
  c   b
  |  / \
  b  b  c
  \ /
   b
?  Here the reason for the second setting of 'b' was that a change
away from it was reverted; to make it extra cringe-inducing, I threw
in that change being reverted was another change to 'c'... (this may
just be an example of how any merge algorithm has some particular case
you can construct where it will get something wrong, because it
doesn't _actually_ know how to read the users's minds).

Supporting these cases may irresistably lead back to ambiguous clean,
as well:
     |
     a
    / \
   b*  c*
  / \ / \
 c*  X   b*
  \ / \ /
   c   b

The other funky case is this thing (any clever name suggestions?):
    a
   / \
  b*  c*
   \ / \
    c*  d*
Merging here will give a conflict, with my algorithm; 3-way merge
would resolve it cleanly.  Polling people on #monotone and #revctrl,
the consensus seems to be that they agree with 3-way merge, but giving
a conflict is really not _that_ bad.  (It also seems to cause some
funky effects with darcs-merge; see zooko's comments on #revctrl and
darcs-users.)

This is really a problem with the user model, rather than the
algorithm.  Apparently people do not interpret the act of resolving
the b/c merge to be "setting" the result; They seem to interpret it as
"selecting" the result of 'c'; the 'c' in the result is in some sense
the "same" 'c' as in the parent.  The difference between "setting" and
"selecting" is the universe of possible options; if you see
   a   b
    \ /
     c
then you figure that the person doing the merge was picking from all
possible resolution values; when you see 
   a   b
    \ /
     b
you figure that the user was just picking between the two options
given by the parents.  My user model is too simple to take this into
account.  It's not a huge extension to the model to do so; it's quite
possible that an algorithm could be devised that gave a clean merge
here, perhaps by separately tracking each node's nearest marked
ancestor and the original source of its value as two separate things.

Relation to other work
----------------------

This algorithm is very close to the traditional codeville-merge
approach to this problem; the primary algorithmic difference is the
marking of conflict resolutions as being "changes".  The more
important new stuff here, I think, are the user model and the proofs.

Traditionally, merge algorithms are evaluated by coming up with some
set of examples, eyeballing them to make some guess as to what the
"correct" answer was, comparing that to the algorithm's output, and
then arguing with people whose intuitions were different.
Fundamentally, merging is about deterministically guessing the user's
intent in situations where the user has not expressed any intent.
Humans are very good at guessing intent; we have big chunks of squishy
hardware designed to form sophisticated models of others intents, and
it's completely impossible for a VCS to try and duplicate that in
full.  My suggestion here, with my "user model", is to seriously and
explicitly study this part of the problem.  There are complicated
trade-offs between accuracy (correctly modeling intention),
conservatism (avoiding incorrectly modeling intention), and
implementability (describing the user's thought processes exactly
isn't so useful if you can't apply it in practice).  It's hard to make
an informed judgement when we don't have a name for the thing we're
trying to optimize, and hard to evaluate an algorithm when we can't
even say what it's supposed to be doing.

I suspect the benefit of the proofs is obvious to anyone who has spent
much time banging their head against this problem; until a few days
ago I was skeptical there _was_ a way to design a merge algorithm that
didn't run into problems like ambiguous clean merge.

I'm still skeptical, of course, until people read this; merging is
like crypto, you can't trust anything until everyone's tried to break
it... so let's say I'm cautiously optimistic .  If this holds up,
I'm quite happy; between the user model and the proofs, I'm far more
confident that this does something sensible in all cases and has no
lurking edge cases than I have been in any previous algorithm.  The
few problem cases I know of display a pleasing conservatism -- perhaps
more cautious than they need to be, but even if they do cause an
occasional unnecessary conflict, once the conflict is resolved it
should stay resolved.

So... do your worst!

-- Nathaniel

-- 
So let us espouse a less contested notion of truth and falsehood, even
if it is philosophically debatable (if we listen to philosophers, we
must debate everything, and there would be no end to the discussion).
  -- Serendipities, Umberto Eco
@end verbatim

Replies and further discussion concerning this email can be found in the  @uref{http://thread.gmane.org/gmane.comp.version-control.monotone.devel/4297, monotone-devel archives}.

@subheading Improvements to *-merge

@verbatim
From: Nathaniel Smith <njs@...>
Subject: improvements to *-merge
Newsgroups: gmane.comp.version-control.revctrl, gmane.comp.version-control.monotone.devel
Date: 2005-08-30 09:21:18 GMT

This is a revised version of *-merge:
  http://thread.gmane.org/gmane.comp.version-control.monotone.devel/4297
that properly handles accidental clean merges.  It does not improve
any of the other parts, just the handling of accidental clean merges.
It shows a way to relax the uniqueness of the *() operator, while
still preserving the basic results from the above email.  For clarity,
I'll say 'unique-*-merge' to refer to the algorithm given above, and
'multi-*-merge' to refer to this one.

This work is totally due to Timothy Brownawell <tbrownaw@...>.
All I did was polish up the proofs and write it up.  He has a more
complex version at:
  http://article.gmane.org/gmane.comp.version-control.monotone.devel/4496
that also attempts to avoid the conflict with:
     a
    / \
   b*  c*
    \ / \
     c*  d*
and has some convergence in it, but the analysis for that is not done.

So:

User model
----------

We keep exactly the same user model as unique-*-merge:

  1) whenever a user explicitly sets the value, they express a claim
     that their setting is superior to the old setting
  2) whenever a user chooses to commit a new revision, they implicitly
     affirm the validity of the decisions that led to that revision's
     parents
    Corollary of (1) and (2): whenever a user explicitly sets the
     value, they express that they consider their new setting to be
     superior to _all_ old settings
  3) A "conflict" should occur if, and only if, the settings on each
     side of the merge express parallel claims.

The difference is that unique-*-merge does not _quite_ fulfill this
model, because in real life your algorithm will automatically resolve
coincidental clean merge cases without asking for user input; but
unique-* is not smart enough to take this into account when inferring
user intentions.

Algorithm
---------

We start by marking the graph of previous revisions.  For each node in
the graph, we either mark it (denoted by a *), or do not.  A mark
indicates our inference that a human expressed an intention at this
node.

    i)      a*     graph roots are always marked

            a1
    ii)     |      no mark, value was not set
            a2

            a
    iii)    |      b != a, so 'b' node marked
            b*

          a   b
    iv)    \ / 
            c*
                   'c' is totally new, so marked
          a1  a2
           \ / 
            c*

          a   b1   we're marking places where users expressed
    v)     \ /     intention; so 'b' should be marked iff this
            b2?    was a conflict

          a1  a2   'a' matches parents, and so is not marked
    vi)    \ /     (alternatively, we can say this is a special
            a3     case of (v), that is never a conflict)

Case (vi) is the only one that differs from unique-* merge.  However,
because of it, we must use a new definition of *():

Definition: By *(A), we mean we set of minimal marked ancestors of A.
"Minimal" here is used in the mathematical sense of a node in a graph
that has no descendents in that graph.

Algorithm: Given two nodes to merge, A and B, we consider four cases:
   a) value(A) = value(B): return the shared value
   b) *(A) > B: return value(B)
   c) *(B) > A: return value(A)
   d) else: conflict; escalate to user
Where "*(A) > B" means "all elements of the set *(A) are non-strict
ancestors of the revision B".  The right way to read this is as "try
(a) first, and then if that fails try (b), (c), (d) simultaneously".

Note that except for the addition of rule (a), this is a strict
generalization of the unique-* algorithm; if *(A) and *(B) are
single-element sets, then this performs _exactly_ the same
computations as the unique-* algorithm.

Now we can say what we mean by "was a conflict" in case (v) above:
given a -> b2, b1 -> b2, we leave b2 unmarked if and only if
*(a) > b1.

Examples
--------

1.
    a1*
   / \
  a2  b*

result: *(a2) = {a1}, a1 > b, so b wins.

2.
    a*
   / \
  b*  c*

result: *(b) = {b}, *(c) = {c}, neither *(b) > c nor *(c) > b, so
 conflict.

3.
    a*
   / \
  b1* b2*
   \ / \
    b3  c1*

result: *(b3) = {b1, b2}; b2 > c1, but b1 is not > c, so c does not
 win.  *(c1) = {c1}, which is not > b3.  conflict.
note: this demonstrates that this algorithm does _not_ do convergence.
Instead, it takes the conservative position that for one node to
silently beat another, the winning node must pre-empt _all_ the
intentions that created the losing node.  While it's easy to come up
with just-so stories where this is the correct thing to do (e.g., b1
and b2 each contain some other changes that independently require 'a'
to become 'b'; c1 will have fixed up b2's changes, but not b1's), this
doesn't actually mean much.  Whether this is good or bad behavior a
somewhat unresolved question, that may ultimately be answered by which
merge algorithms turn out to be more tractable...

4.
    a*
   / \
  b1* b2*
  |\ /|
  | X |
  |/ \|
  b3  c*

result: *(b3) = {b1, b2} > c.  *(c) = {c}, which is not > b3.  c wins
 cleanly.

5.
     a*
    / \
   b1* c1*
  / \ / \
 c2* X   b2*
  \ / \ /
   c3  b3

result: *(c3) = {c1, c2}; c1 > b3 but c2 is not > b3, so b3 does not
 win.  likewise, *(b3) = {b1, b2}; b1 > c3 but b2 is not > c3, so c3
 does not win either.  conflict.

6.
     a*
    / \
   b1* c1*
  / \ / \
 c2* X   b2*
  \ / \ /
   c3  b3
   |\ /|
   | X |
   |/ \|
   c4* b4*

(this was my best effort to trigger an ambiguous clean merge with this
algorithm; it fails pitifully:)
result: *(c4) = {c4}, *(b4) = {b4}, obvious conflict.

Math
----

The interesting thing about this algorithm is that all the unique-*
proofs still go through, in a generalized form.  The key one that
makes *-merge tractable is:

Theorem: In a graph marked by the above rules, given a node N, all
 nodes in *(N) will have the same value as N.
Proof: By induction.  We consider the cases (i)-(vi) above.  (i)
 through (iv) are trivially true.  (v) is interesting.  b2 is marked
 when *(a) not > b1.  b2 being marked makes that case trivial, so
 suppose *(a) > b1.  All elements of *(a) are marked, and are
 ancestors of b1; therefore, by the definition of *() and "minimal",
 they are also all ancestors of things in *(b1).  Thus no element of
 *(a) can be a minimal marked ancestor of b2.
 (vi) is also trivial, because *(a3) = *(a1) union *(a2).  QED.

We also have to do a bit of extra work because of the sets:

Corollary 1: If *(A) > B, and any element R of *(B) is R > A, then
 value(A) = value(B).
Proof: Let such an R be given.  R > A, and R marked, imply that there
 is some element S of *(A) such that R > S.
 On the other hand, *(A) > B implies that S > B.  By similar reasoning
 to the above, this means that there is some element T of *(B) such
 that S > T.  So, recapping, we have:
  nodes:   R  >  S  >  T
   from: *(B)  *(A)  *(B)
 *(B) is a set of minimal nodes, yet we have R > T and R and T both in
 *(B).  This implies that R = T.  R > S > R implies that S = R,
 because we are in a DAG.  Thus
   value(A) = value(S) = value(R) = value(B)
 QED.

Corollary 2: If *(A) > B and *(B) > A, then not only does value(A) =
 value(B), but *(A) = *(B).
Proof: By above, each element of *(B) is equal to some element of
 *(A), and vice-versa.

This is good, because it means our algorithm is well-defined.  The
only time when options (b) and (c) (in the algorithm) can
simultaneously be true, is when the two values being merged are
identical to start with.  I.e., no somewhat anomalous "4th case" of
ambiguous clean merge.

Actually, this deserves some more discussion.  With *() returning a
set, there are some more subtle "partial ambiguous clean" cases to
think about -- should we be worrying about cases where some, but not
all, of the marked ancestors are pre-empted?  This is possible, as in
example 5 above:
     a*
    / \
   b1* c1*
  / \ / \
 c2* X   b2*
  \ / \ /
   c3  b3
A hypothetical (convergence supporting?) algorithm that said A beats B
if _any_ elements of *(A) are > B would give an ambiguous clean merge
on this case.  (Maybe that wouldn't be so bad, so long as we marked
the result, but I'm in no way prepared to do any sort of sufficient
analysis right now...)

The nastiest case of this is where *(A) > B, but some elements of *(B)
are > A -- so we silently make B win, but it's really not _quite_
clear that's a good idea, since A also beat B sometimes -- and we're
ignoring those user's intentions.

This is the nice thing about Corollary 1 (and why I didn't just
collapse it into Corollary 2) -- it assures us that the only time this
_weak_ form of ambiguous clean can happen is when A and B are already
identical.  This _can_ happen, for what it's worth:
       a*
      /|\
     / | \
    /  |  \
   /   |   \
  b1*  b2*  d*
  |\   /\  /
  | \ /  \/
  |  X   b3*
  | / \ /
  |/   b4
  b5
Here *(b5) = {b3, b2}, *(b6) = {b2, b4}.  If we ignore for a moment
that b4 and b5 have the same value, this is a merge that b4 would win
and b5 would lose, even though one of b4's ancestors, i.e. b1, is
pre-empted by b5.  However, it can _only_ happen if we ignore that
they have the same value...

The one other thing we proved about unique-* merge also still applies;
the proof goes through word-for-word:
Theorem: If A and B would merge cleanly with A winning, then any
  descendent D of A will also merge cleanly with B, with D winning.
Proof: *(B) > A, and A > D, so *(B) > D.

Discussion
----------

This algorithm resolves one of the two basic problems I observed for
unique-* merge -- coincidental clean merges are now handled, well,
cleanly, and the user model is fully implemented.  However, we still
do not handle the unnamed case (you guys totally let me down when I
requested names for this case last time):
    a
   / \
  b*  c*
   \ / \
    c*  d*
which still gives a conflict.  We also, of course, continue to not
support more exotic features like convergence or implicit rollback.

Not the most exciting thing in the world.  OTOH, it does strictly
increase the complexity of algorithms that are tractable to formal
analysis.

Comments and feedback appreciated.

-- Nathaniel

-- 
"The problem...is that sets have a very limited range of
activities -- they can't carry pianos, for example, nor drink
beer."
@end verbatim

Replies and further discussion concerning this email can be found in the  @uref{http://thread.gmane.org/gmane.comp.version-control.revctrl/93, monotone-devel archives}.

@subheading More on "mark-merge"

@verbatim
From: Timothy Brownawell <tbrownaw@...>
Subject: more on "mark-merge"
Newsgroups: gmane.comp.version-control.revctrl, gmane.comp.version-control.monotone.devel

Prerequisite:
http://thread.gmane.org/gmane.comp.version-control.monotone.devel/4297

A user can make 2 types of merge decisions:
(1): One parent is better than the other (represented by *)
(2): Both parents are wrong (represented by ^)

Since there are 2 types of merge decisions, it would be bad to treat all
merge decisions the same. Also, in the case of merge(a, a) = a, it is
possible for there to be multiple least decision ancestors.

=====

Define: ^(A) is the set of ancestors of A that it gets its value from
(found by setting N=A and iterating N = *(N) until there is no change)
        *(A) is the set of least ancestors of A in which the user made a
decision

note that erase_ancestors(^(A)) = ^(A),
and erase_ancestors(*(A)) = *(A)

=====

& is intersection, | is union

*(A) has the same properties as before, except that it is not a single
ancestor, but a set. This set can acquire more than one member only in
the case of
   Aa    Ba
     \  /
      Ca
, where *(A) and *(B) are different; *(C) will be
erase_ancestors(*(A) | *(B))

The ancestory corollary becomes:
any ancestor C of A with value(C) != value(A) will be an ancestor of at
least one member of *(A)

When merging A and B:

# if one side knows of _all_ places that the other side was chosen, it
wins
(1)
set X = erase_ancestors(*(A) | *(B))
    if X & *(B) = {}, A wins
    if X & *(A) = {}, B wins
else, X contains members of both *(A) and *(B)

# if one side knows of _all_ places that the other side originated, it
wins
(2)
set Y = erase_ancestors(*(A) | ^(B))
set Z = erase_ancestors(*(B) | ^(A))
    if Y & ^(B) = {} and Z & ^(A) = {}, conflict
    if Y & ^(B) = {}, A wins
    if Z & ^(A) = {}, B wins

# if one side knows of _any_ places that the other side originated, it
wins
(3)
    if Y & ^(B) != ^(B) and Z & ^(A) != ^(A), conflict
    if Y & ^(B) != ^(B), A wins
    if Z & ^(A) != ^(A), B wins

# else, nobody knows anything
(4) conflict

(3) is convergence, and can be safely left out if unwanted

====

"Funky cases"

Coincidental clean does not exist; a mark is only needed when there is
user intervention.

    |
    a
   / \
  b   b
   \ / \
    b   c
and the example after it will resolve cleanly iff (3) is included.

     |
     a
    / \
   b*  c*
  / \ / \
 c*  X   b*
  \ / \ /
   c   b
will be a conflict.

    a
   / \
  b*  c*
   \ / \
    c*  d*
This ("the other funky case") is handled by (2), and resolves cleanly.

Tim
@end verbatim

Replies and further discussion concerning this email can be found in the  @uref{http://thread.gmane.org/gmane.comp.version-control.revctrl/92, monotone-devel archives}.

@node Default hooks
@appendix Default hooks

This section contains the entire source code of the standard hook file,
that is built in to the monotone executable, and read before any user
hooks files (unless @option{--nostd} is passed).  It contains the
default values for all hooks.

@verbatiminclude std_hooks.lua

@node General Index
@unnumbered General Index
     
@printindex cp

@bye
