\input texinfo   @c -*-texinfo-*-
@c %**start of header
@setfilename monotone.info
@settitle monotone documentation
@setchapternewpage odd
@finalout
@ifhtml
@paragraphindent 0
@exampleindent 0
@end ifhtml
@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 - 2010 Derek Scherger @*
Copyright @copyright{} 2005, 2006 Daniel Carosone @*
Copyright @copyright{} 2006 Jeronimo Pellegrini @*
Copyright @copyright{} 2006 Alex Queiroz @*
Copyright @copyright{} 2006, 2007 William Uther @*
Copyright @copyright{} 2006 - 2010 Thomas Keller @*
Copyright @copyright{} 2007 - 2010 Stephen Leake @*

This manual is made available under the GNU GPL version 2.0 or
greater.  See the accompanying file COPYING for details.

@end titlepage

@ifnottex
@node Top, Concepts, (dir), (dir)
@top Overview

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
* Lua Reference::               How Lua is integrated in 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, Tutorial, Top, Top
@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, Versions of trees, Concepts, Concepts
@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, Historical records, Versions of files, Concepts
@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
attributes, 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, Certificates, Versions of trees, Concepts
@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, Storage and workflow, Historical records, Concepts
@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, Forks and merges, Certificates, Concepts
@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, Branches, Storage and workflow, Concepts
@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,  , Forks and merges, Concepts
@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,,10cm}
@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, fully qualified, domain 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, Advanced Uses, Concepts, Top
@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, Generating Keys, Tutorial, Tutorial
@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.

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

and Abe issues the command:

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

Beth decides to use monotone's built-in database management functionality.
monotone then expects to find managed database files in a couple of predefined
places (like f.e. @file{~/.monotone/databases} on Unix and
@file{%APPDATA%\monotone\databases} on Windows, this is customizable) and acts
upon those by knowing only their file or basename from anywhere.

To create a new managed database, Beth issues the @command{mtn db init} command
like this:

@smallexample
@group
$ mtn db init --db=:beth
@end group
@end smallexample

Beth can distinguish a managed database name from an unmanaged one by the
leading colon in its name.  This special alias can now be used interchangeably
in every monotone invocation.
If Beth wants to see where monotone actually created the database and what
other databases monotone knows of, she uses the @command{mtn list databases}
command (or @command{mtn ls dbs}) for that.  We'll come back to this in a bit.

@page
@node    Generating Keys, Starting a New Project, Creating a Database, Tutorial
@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
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: generating key-pair 'jim@@juicebot.co.jp'
mtn: storing key-pair 'jim@@juicebot.co.jp' in /home/jim/.monotone/keys
mtn: key 'jim@@juicebot.co.jp' has hash '398cb10dcd4fadf4f7849a3734b626a83e0bb2ae'
@end group
@end smallexample

Abe does something similar:

@smallexample
@group
$ mtn genkey 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: generating key-pair 'abe@@juicebot.co.jp'
mtn: storing key-pair 'abe@@juicebot.co.jp' in /home/abe/.monotone/keys
mtn: key 'abe@@juicebot.co.jp' has hash '62d8d1798e716868acde75c0fc4c84760003863d'
@end group
@end smallexample

as does Beth:

@smallexample
@group
$ mtn genkey 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: generating key-pair 'beth@@juicebot.co.jp'
mtn: storing key-pair 'beth@@juicebot.co.jp' in /home/beth/.monotone/keys
mtn: key 'beth@@juicebot.co.jp' has hash 'c1d47c065a21f1e1c4fbdefaa2f37bd2c15ee4b1'
@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]
398cb10dcd4fadf4f7849a3734b626a83e0bb2ae jim@@juicebot.co.jp   (*)
(*) - only in /home/jim/.monotone/keys/


[private keys]
398cb10dcd4fadf4f7849a3734b626a83e0bb2ae 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 fingerprint, however distincts keys with equal names
are possible.

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] (1234abcd...):
enter new passphrase for key ID [user@@example.com] (1234abcd...):
confirm passphrase for key ID [user@@example.com] (1234abcd...):
$ 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(key_identity)
  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, Adding Files, Generating Keys, Tutorial
@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, Committing Work, Starting a New Project, Tutorial
@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 -R 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 [0000000000000000000000000000000000000002]

old_revision []

add_dir ""

add_dir "include"

add_dir "src"

add_file "include/jb.h"
 content [f6996ce2dfc5d32bda8b574c3e9ce75db8d55492]

add_file "src/apple.c"
 content [1ce885d2cc59842ff16785834391e864068fbc3c]

add_file "src/banana.c"
 content [ad88bbbb1b7507ddff26be67efd91d95e069afb6]
@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
----------------------------------------------------------------------
Revision: 493bda86628fd72c992eb56f73899db9ead3cf6f
Author:   jim@@juicebot.co.jp
Date:     2004-10-26T02:53:08
Branch:   jp.co.juicebot.jb7

Changes

  added
  added    include
  added    src
  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 and directories.

Jim wants to see the actual details of the files he added, however, so
he runs a command which prints out the revision @emph{and} a GNU
``unified diff'' of the patches involved in the changeset:

@smallexample
@group
$ mtn diff
#
# old_revision []
#
# add_dir ""
#
# add_dir "include"
#
# add_dir "src"
#
# add_file "include/jb.h"
#  content [f6996ce2dfc5d32bda8b574c3e9ce75db8d55492]
#
# add_file "src/apple.c"
#  content [1ce885d2cc59842ff16785834391e864068fbc3c]
#
# add_file "src/banana.c"
#  content [ad88bbbb1b7507ddff26be67efd91d95e069afb6]
#
============================================================
--- include/jb.h	f6996ce2dfc5d32bda8b574c3e9ce75db8d55492
+++ include/jb.h	f6996ce2dfc5d32bda8b574c3e9ce75db8d55492
@@ -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	1ce885d2cc59842ff16785834391e864068fbc3c
+++ src/apple.c	1ce885d2cc59842ff16785834391e864068fbc3c
@@ -0,0 +1,7 @@
+#include "jb.h"
+
+void
+dispense_apple_juice()
+@{
+  /* Fill this in please, Abe. */
+@}
============================================================
--- src/banana.c	ad88bbbb1b7507ddff26be67efd91d95e069afb6
+++ src/banana.c	ad88bbbb1b7507ddff26be67efd91d95e069afb6
@@ -0,0 +1,7 @@
+#include "jb.h"
+
+void
+dispense_banana_juice()
+@{
+  /* Fill this in please, Beth. */
+@}
@end group
@end smallexample

@page
@node    Committing Work, Basic Network Service, Adding Files, Tutorial
@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 493bda86628fd72c992eb56f73899db9ead3cf6f
@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
493bda86628fd72c992eb56f73899db9ead3cf6f
@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 493bda86628fd72c992eb56f73899db9ead3cf6f
-----------------------------------------------------------------
Key   : jim@@juicebot.co.jp (398cb10d...)
Sig   : ok
Name  : branch
Value : jp.co.juicebot.jb7
-----------------------------------------------------------------
Key   : jim@@juicebot.co.jp (398cb10d...)
Sig   : ok
Name  : date
Value : 2004-10-26T02:53:08
-----------------------------------------------------------------
Key   : jim@@juicebot.co.jp (398cb10d...)
Sig   : ok
Name  : author
Value : jim@@juicebot.co.jp
-----------------------------------------------------------------
Key   : jim@@juicebot.co.jp (398cb10d...)
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{493bda86628fd72c992eb56f73899db9ead3cf6f} 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:
493bda86628fd72c992eb56f73899db9ead3cf6f 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, Synchronising Databases, Committing Work, Tutorial
@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 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, Making Changes, Basic Network Service, Tutorial
@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, Dealing with a Fork, Synchronising Databases, Tutorial
@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 [493bda86628fd72c992eb56f73899db9ead3cf6f]
#
# patch "src/apple.c"
#  from [1ce885d2cc59842ff16785834391e864068fbc3c]
#    to [e2c64f6bde75a192d48d2256385df3dd7a963349]
#
============================================================
--- src/apple.c	1ce885d2cc59842ff16785834391e864068fbc3c
+++ src/apple.c	e2c64f6bde75a192d48d2256385df3dd7a963349
@@ -3,5 +3,8 @@ dispense_apple_juice()
 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
@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
Enter a description of this change following the Changelog line below.
The values of Author, Date and Branch may be modified as required.

*** REMOVE THIS LINE TO CANCEL THE COMMIT ***
----------------------------------------------------------------------
Revision: 42eae36587508faa664b111cefc291f0b85ef83a
Parent:   493bda86628fd72c992eb56f73899db9ead3cf6f
Author:   abe@@juicebot.co.jp
Date:     2004-10-26T02:53:08
Branch:   jp.co.juicebot.jb7

Changelog:

polling implementation of src/apple.c

----------------------------------------------------------------------
Changes against parent 493bda86628fd72c992eb56f73899db9ead3cf6f

  patched  src/apple.c

@end group
@end smallexample

Abe enters a single line below the Changelog: header, saying ``polling
implementation of src/apple.c''. He then saves the file and quits the
editor. Monotone confirms that no other lines have been changed and
extracts the message to be stored in the associated ``changelog''
cert, leaving only Abe's short message. Returning to the shell, Abe's
commit completes:

@smallexample
@group
mtn: beginning commit on branch 'jp.co.juicebot.jb7'
mtn: committed revision 42eae36587508faa664b111cefc291f0b85ef83a
@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 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 --branch=jp.co.juicebot.jb7 checkout juicebot
@end group
@end smallexample

and since she is using a managed database, monotone automatically remembers
the connection between the newly created workspace and the database.  She
now looks at the output of @command{mtn list databases} and sees the
following:

@smallexample
@group
$ mtn list databases
:beth.mtn (in /home/beth/.monotone/databases):
        jp.co.juicebot.jb7 (in /home/beth/juicebot)
@end group
@end smallexample

Beth realizes that, whenever the database of the workspace changes, monotone
will adapt the known paths for the old and the new database for her.

But let us get back to the work, Beth now start to 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 85573a54105cd3220db10aa6a0713643cdf5ce6f
@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, Branching and Merging, Making Changes, Tutorial
@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 493bd...
@item Abe changed revision 493bd... into revision 42eae...
@item Beth derived revision 42eae... into revision 85573...
@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 85573... 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 [85573a54105cd3220db10aa6a0713643cdf5ce6f]
#
# patch "src/banana.c"
#  from [d7e28a01cf6fc0f9ac04c6901dcafd77c2d32fb8]
#    to [dd979c3c880e6a7221fcecd7148bd4afcfb3e964]
#
============================================================
--- src/banana.c	d7e28a01cf6fc0f9ac04c6901dcafd77c2d32fb8
+++ src/banana.c	dd979c3c880e6a7221fcecd7148bd4afcfb3e964
@@ -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()
 @{
+  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 90abe0f1bc354a73d42d3bff1b02946559682bd9
@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 42eae..., 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:
90abe0f1bc354a73d42d3bff1b02946559682bd9 abe@@juicebot.co.jp 2004-10-26T02:53:16
951da88860a4cf7419d66ed9094d8bf24df5fb8b 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: 2 heads on branch 'jp.co.juicebot.jb7'
mtn: merge 1 / 1:
mtn: calculating best pair of heads to merge next
mtn: [left]  90abe0f1bc354a73d42d3bff1b02946559682bd9
mtn: [right] 951da88860a4cf7419d66ed9094d8bf24df5fb8b
mtn: [merged] 3aca69c7749bde9bd07fe4c92bb868bd69b2e421
mtn: note: 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, or Jim could have used the @command{conflicts} set of
commands to resolve it (@pxref{Conflicts}).

After merging, the branch has a single head again, and Jim updates
his workspace.

@smallexample
@group
$ mtn update
mtn: updating along branch 'jp.co.juicebot.jb7'
mtn: selected update target 3aca69c7749bde9bd07fe4c92bb868bd69b2e421
mtn: [left]  d60c18ec5e0cf1163b276f0bfdd908c1dfd53b4a
mtn: [right] 3aca69c7749bde9bd07fe4c92bb868bd69b2e421
mtn: updating src/apple.c
mtn: updating src/banana.c
mtn: updated to base revision 3aca69c7749bde9bd07fe4c92bb868bd69b2e421
@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, Network Service Revisited, Dealing with a Fork, Tutorial
@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.

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

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

@smallexample
@group
$ mtn ls branches
jp.co.juicebot.jb7
jp.co.juicebot.jb7.muffins
$ mtn heads
mtn: branch 'jp.co.juicebot.jb7.muffins' is currently merged:
4e48e2c9a3d2ca8a708cb0cc545700544efb5021 beth@@juicebot.co.jp 2007-07-08T02:17:37
$ mtn suspend 4e48e2c9a3d2ca8a708cb0cc545700544efb5021
$ mtn ls branches
jp.co.juicebot.jb7
@end group
@end smallexample

@page
@node    Network Service Revisited,  , Branching and Merging, Tutorial
@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
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: generating key-pair 'monotone-server@@www.juicebot.co.jp'
mtn: storing key-pair 'monotone-server@@www.juicebot.co.jp' in /home/jim/.monotone/keys
mtn: key 'abe@@juicebot.co.jp' has hash '78be08f7a2a316a9f7c6b0db544ed20673ea2190'
$ 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{Lua
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, CVS Phrasebook, Tutorial, Top
@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.
* Merge Conflicts::             The various conflict types and how to resolve them.
* 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.
* Exporting to GIT::            Building a git repository from a monotone database.
* Using packets::               Transferring data ``by hand''.
* Bisecting::                   Finding bad revisions.
@end menu

@page
@node    Other Transports, Selectors, Advanced Uses, Advanced Uses
@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

@code{ssh:} and @code{file:} are currently not supported on the native
Win32 platform; they are supported on Cygwin and all other platforms.

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. Therefore, it must also be writable, even when monotone isn't
going to modify it, as it is the case for @command{pull}.  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, Restrictions, Other Transports, Advanced Uses
@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 Message selection
Uses selector type @code{m}. For example @code{m:*foobar*} matches
@code{changelog} and @code{comment} certs where the cert value
contains the glob @code{*foobar*}.
@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 Parent selection
Uses selector type @code{p}. For example, @code{p:0f3a} matches the
revision IDs which are the parent of the revision ID which begins with
@code{0f3a}. If you give a bare @code{p:}, monotone will require you to be in
a workspace, and query the parent of the base workspace revision.
@item Update selection
Uses selector type @code{u}. This selector must be used from within a
workspace and must not have any associated value. It matches the base
revision ID of the workspace before the last @command{update} command
was executed. This can be useful for reviewing incoming
revisions. After each update operation, or at least before the next
update operation, run a command similar to the following:
@smallexample
$ mtn log --to u: --diffs
@end smallexample
to log all revisions back to the last update. It can also be
used for quickly jumping between two different revisions. For example,
the following command:
@smallexample
$ mtn update -r u:
@end smallexample
will update back to the previous update revision. Repeating this
command will swap the current and previous update revision.
@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.
@item Workspace base revision
Uses selector type @code{w}. This selector must be used from within a
workspace and must not have any associated value. It matches the base
revision ID(s) this workspace is based on.
@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{Lua 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 @code{now}
Expands to the current date and time.
@item @code{today}
Expands to today's date. @code{e} and @code{l} selectors assume time 00:00:00
@item @code{yesterday}
Expands to yesterday's date. @code{e} and @code{l} selectors assume
time 00:00:00
@item @code{<number> @{minute|hour@} <ago>}
Expands to today date and time, minus the specified @code{number} of
minutes|hours.
@item @code{<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 @code{<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{Lua 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, Scripting, Selectors, Advanced Uses
@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}
@item @command{log}
@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} } and @option{--exclude=@var{path}}
options. The value @var{n} given to @option{--depth} specifies the
maximum number of directories to descend. For example, @var{n}=0
disables recursion, @var{n}=1 means descend at most one directory
below each specified path, and so on.  The @option{--depth} value
applies individually to each path specified on the command line. The
value @var{path} given to @option{--exclude} specifies a path that
should be excluded from the restriction. Multiple @option{--exclude}
options may be specified to exclude several files or subdirectories.

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.

In addition to including all of the explicitly specified paths and
excluding all of the paths specified with @option{--exclude} options a
restriction also implicitly includes the parent directories of all
included paths. This is done to allow commands operating on newly
added files to succeed. For example, if a new directory @file{a} is
added and a file @file{a/b} is added to this directory restricting to
exactly @file{a/b} will produce a meaningless state that doesn't
include the required parent directory @file{a}.

The implicit inclusion of required parent directories is done for all
of the commands listed above with the exception of
@command{revert}. This is done to allow reverting the addition of
files in newly added or renamed directories without reverting the
directories themselves. If the parent directories were implicitly
included their addition or name changes would also be reverted.

@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
@file{.}  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 @file{.} 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 @file{../../..} 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. The
@option{--no-workspace} option may be used to prevent the search entirely.

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, Inodeprints, Restrictions, Advanced Uses
@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}.

@node    Inodeprints, Merge Conflicts, Scripting, Advanced Uses
@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{Lua Reference} for details.

@page
@node    Merge Conflicts, Workspace Collisions, Inodeprints, Advanced Uses
@section Merge Conflicts

Several different types of conflicts may be encountered when merging
two revisions using the database merge commands @command{merge},
@command{explicit_merge}, @command{propagate} and
@command{merge_into_dir} or when using the workspace merge commands
@command{update}, @command{pluck} and @command{merge_into_workspace}.

The @command{show_conflicts} and @command{automate show_conflicts}
commands can be used to list conflicts between database revisions
which would be encountered by the database merge commands.
Unfortunately, these commands can't yet list conflicts between a
database revision and the current workspace.

In addition, the @command{conflicts} set of commands can be used to
specify resolutions for some conflicts. The resolutions are stored in a
file, and given to the @command{merge} command via the
@command{--resolve-conflicts-file=filename} or
@command{--resolve-conflicts} option; see @xref{Conflicts}.

The @command{merge} command normally will perform as many merges as
necessary to merge all current heads of a branch. However, when
@command{--resolve-conflicts-file} is given, the conflicts and their
resolutions apply only to the first merge, so the subsequent merges
are not done; the @command{merge} command must be repeated, possibly
with new conflicts and resolutions, to merge the remaining heads.

If @command{conflicts} supports resolving a particular conflict, that
is the simplest way to resolve it. Otherwise, resolving the different
types of conflicts is accomplished by checking out one of the
conflicting revisions, making changes as described below, committing
these changes as a new revision and then running the merge again using
this new revision as one of the merge parents. This process can be
repeated as necessary to get two revisions into a state where they
will merge cleanly, or with a minimum of file content conflicts.

The possible conflict resolutions are discussed with each conflict in
the following sections.

@subsection Conflict Types

Monotone versions both files and directories explicitly and it tracks
individual file and directory identity from birth to death so that
name changes throughout the full life-cycle can be tracked exactly.
Partly because of these qualities, monotone also notices several types
of conflicts that other version control systems may not.

The two most common conflicts are described first, then all other
possible conflicts.

@subheading File Content Conflict

This type of conflict is generally the one encountered most commonly
and represents conflicting changes made to lines of text within two
versions of a single file.

Monotone does not generally use CVS style conflict markers for content
conflicts. Instead it makes the content of both conflicting files and
the content of their common ancestor available for interactive use
during the merge with your favorite merge tool. See the @code{merge3}
hook for more information.

Alternatively, rather than using a merge tool it is possible to make
further changes to one or both of the conflicting file versions so
that they will merge cleanly. This can also be a very helpful strategy
if the merge conflicts are due to sections of text in the file being
moved from one location to another. Rather than struggling to merge
such conflicting changes with a merge tool, similar rearrangements can
be made to one of the conflicting files before redoing the merge.

Finally, you can use your favorite merge tool asychronously with the
merge, and specify the result file in the conflicts file, using the
@command{conflicts} command (@pxref{Conflicts}):
@smallexample
mtn conflicts resolve_first user filename
@end smallexample

@subheading Duplicate Name Conflict

A duplicate name conflict occurs when two distinct files or
directories have been given the same name in the two merge parents.
This can occur when each of the merge parents adds a new file or
directory with the conflicting name, or when one parent adds a new
file or directory with the conflicting name and the other renames an
existing file or directory to the conflicting name, or when both
parents rename an existing file or directory to the conflicting name.

In earlier versions of monotone (before version 0.39) this type of
conflict was referred to as a @emph{rename target conflict} although
it doesn't necessarily have anything to do with renames.

There are two main situations in which duplicate name conflicts occur:

@itemize
@item
Two people both realize a new file should be added, and commit it. In
this case, the files have the right name and the right contents, but
monotone reports a conflict because they were added separately.

@item
Two people each decide to add new files with different content, and
accidently pick the same name.
@end itemize

These conflicts are reported when someone tries to merge the two
revisions containing the new files.

There are similar conflicts for directories; the process for resolving
them is different, because we need to worry about the files in the
directories.

@subsubheading Same file
For the first case, the conflict is resolved by dropping one file,
using @command{conflicts} commands. The contents should be manually
merged, in case they are slightly different. Typically, a user will
have one of the files in their current workspace; the other can be
retrieved via @command{automate get_file_of}; the revision id is shown
in the merge error message.

The process for files can be confusing; here's a detailed example.

Suppose Beth and Abe each commit a new file @file{checkout.sh}. When
Beth attempts to merge the two heads, she gets a message like:

@smallexample
@group
mtn: 2 heads on branch 'testbranch'
mtn: [left]  ae94e6677b8e31692c67d98744dccf5fa9ccffe5
mtn: [right] dfdf50b19fb971f502671b0cfa6d15d69a0d04bb
mtn: conflict: duplicate name 'checkout.sh'
mtn: added as a new file on the left
mtn: added as a new file on the right
mtn: error: merge failed due to unresolved conflicts
@end group
@end smallexample

The file labeled @code{right} is the file in Beth's workspace. To
start the conflict resolution process, Beth first saves the list of
conflicts:

@smallexample
mtn conflicts store
@end smallexample

In order to merge Beth's and Abe's file versions, Beth retrieves a
copy of Abe's file:

@smallexample
@group
mtn automate get_file_of checkout.sh \
--revision=ae94e6677b8e31692c67d98744dccf5fa9ccffe5 \
> _MTN/resolutions/checkout.sh-abe
@end group
@end smallexample

Now Beth manually merges (using her favorite merge tool)
@file{checkout.sh} and @file{_MTN/resolutions/checkout.sh-abe},
leaving the results in @file{_MTN/resolutions/checkout.sh-merge}
(@emph{not} in her copy).

Then Beth specifies the conflict resolution, and finishes the merge:

@smallexample
@group
mtn conflicts resolve_first_left drop
mtn conflicts resolve_first_right user _MTN/resolutions/checkout.sh-merge
mtn merge --resolve-conflicts-file=_MTN/conflicts
mtn conflicts clean
mtn update
@end group
@end smallexample

When Abe later syncs and updates, he will get the merged version.

@subsubheading Different files
The second case, where two different files accidently have the same
name, is resolved by renaming one or both of them.

Suppose Beth and Abe each start working on different thermostat models
(say Honeywell and Westinghouse), but they both name the file
@file{thermostat}. When Beth attempts to merge, she will get the same
error message as in the first case. When she retrieves Abe's file, she
will see that they should be different files. So she renames her file,
merges, and updates:

@smallexample
@group
mtn conflicts store
mtn conflicts resolve_first_left rename thermostat-westinghouse
mtn conflicts resolve_first_right rename thermostat-honeywell
mtn merge --resolve-conflicts-file=_MTN/conflicts
mtn conflicts clean
mtn update
@end group
@end smallexample

Now she has her file in @file{thermostat-honeywell}, and Abe's in
@file{thermostat-westinghouse}.

@subsubheading Directories
When two directories are given the same name, there are still the two
basic approaches to resolving the conflict; drop or rename. However,
if a directory is dropped, all the files in it must also be dropped.
Therefore, it is almost always better to first rename one of the
directories to a temporary name as the conflict resolution, and
then deal with the files individually, renaming or merging and
dropping each. Then finally drop the temporary directory.

@subheading Missing Root Conflict

Monotone's merge strategy is sometimes referred to as
@emph{die-die-die} merge, with reference to the fact that when a file
or directory is deleted there is no means of resurrecting it. Merging
the deletion of a file or directory will @emph{always} result in that
file or directory being deleted.

A missing root conflict occurs when some directory has been moved to
the root directory in one of the merge parents and has been deleted in
the other merge parent. Because of die-die-die merge the result will
not contain the directory that has been moved to the root.

Missing root conflicts should be very rare because it is unlikely that
a project's root directory will change. It is even more unlikely that
a project's root directory will be changed to some other directory in
one merge parent and that this directory will also be deleted in the
other merge parent. Even still, a missing root directory conflict can
be easily resolved by moving another directory to the root in the
merge parent where the root directory was previously changed. Because
of die-die-die merge, no change to resolve the conflict can be made to
the merge parent that deleted the directory which was moved to the
root in the other merge parent.

See the @command{pivot_root} command for more information on moving
another directory to the project root.

@command{conflicts} does not yet support resolving this conflict.

@subheading Invalid Name Conflict

Monotone reserves the name @file{_MTN} in a workspace root directory
for internal use and treats this name as @emph{illegal} for a
versioned file or directory in the project root. This name is
@emph{legal} for a versioned file or directory as long as it is not in
the project root directory.

An invalid name conflict occurs when some directory is moved to the
project root in one of the merge parents and a file or directory that
exists in this new root directory is renamed to @file{_MTN} or a new
file or directory is added with the name @file{_MTN} to this directory
in the other merge parent.

Invalid name conflicts should be very rare because it is unlikely that
a project's root directory will change. It is even more unlikely that
a project's root directory will change and the new root directory will
contain a file or directory named @file{_MTN}. Even still, an invalid
name conflict can be easily resolved in several different ways. A
different root directory can be chosen, the offending @file{_MTN} file
or directory can be renamed or deleted, or it can be moved to some
other subdirectory in the project.

See the @command{pivot_root} command for more information on moving
another directory to the project root.

@command{conflicts} does not yet support resolving this conflict.

@subheading Directory Loop Conflict

A directory loop conflict occurs when one directory is moved under a
second in one of the merge parents and the second directory is moved
under the first in the other merge parent.

Directory loop conflicts should be rare but can be easily resolved by
moving one of the conflicting directories out from under the other.

@command{conflicts} does not yet support resolving this conflict.

@subheading Orphaned Node Conflict

An orphaned node conflict occurs when a directory and all of its
contents are deleted in one of the merge parents and further files or
directories are added to this deleted directory, or renamed into it,
in the other merge parent.

Orphaned node conflicts do happen occasionally but can be easily
resolved by renaming the orphaned files or directories out of the
directory that has been deleted and into another directory that exists
in both merge parents, or that has been added in the revision
containing the orphaned files or directories.

@command{conflicts} supports resolving this conflict. However, if the
orphaned node is a directory that is not empty, and the desired
resolution is 'drop', the user must drop the directory contents and
commit before invoking the conflicts commands.

@subheading Multiple Name Conflict

A multiple name conflict occurs when a single file or directory has
been renamed to two different names in the two merge parents.
Monotone does not allow this and requires that each file and directory
has exactly one unique name.

Multiple name conflicts do happen occasionally but can be easily
resolved by renaming the conflicting file or directory in one or both
of the merge parents so that both agree on the name.

@command{conflicts} does not yet support resolving this conflict.

In earlier versions of monotone (those before version 0.39) this type
of conflict was referred to as a @emph{name conflict}.

@subheading Attribute Conflict

An attribute conflict occurs when a versioned attribute on a file or
directory is set to two different values by the two merge parents or
if one of the merge parents changes the attribute's value and the
other deletes the attribute entirely.

Attribute conflicts may happen occasionally but can be easily resolved
by ensuring that the attribute is set to the same value or is deleted
in both of the merge parents. Attributes are @emph{not} merged using
the die-die-die rules and may be resurrected by simply setting their
values.

@command{conflicts} does not yet support resolving this conflict.

@page
@node    Workspace Collisions, Quality Assurance, Merge Conflicts, Advanced Uses
@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}, @command{pivot_root} 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. Furthermore, all workspace-changing commands have
an option @option{--move-conflicting-paths}, which moves unversioned, but
conflicting files and directories from the workspace into a new subdirectory
under _MTN/resolutions. This is useful if you want to ensure that an update
always succeeds and you just want to move blocking paths out of the way.

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, Vars, Workspace Collisions, Advanced Uses
@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{Lua Reference}.

@page
@node    Vars, Reserved Files, Quality Assurance, Advanced Uses
@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.
@item delta-direction
This tells monotone whether to store @samp{reverse} deltas (the default),
@samp{forward} deltas, or @samp{both} kinds of deltas for reconstructing
versions of files. Reverse deltas are faster when inspecting recent files,
while forward deltas are much faster for sending over the network. This
should probably be set to @samp{both} for a server database, unless disk
space is severely limited. Note that as @emph{receiving} deltas involves
reconstructing the file version that the delta was made against, a server
using a database with only forward deltas will be somewhat slower at
receiving new revisions unless your particular history graph is highly
linear.

Changing this value does not affect deltas that have already been stored.
@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, Reserved Certs, Vars, Advanced Uses
@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 and directories

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. @xref{Regexps}, for the syntax of these regular expressions.
@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/commit
If a commit fails, f.e. because a header field could not be parsed
properly, then this file will contain a dump of the complete contents
which have been saved through the editor.  After the information has
been recovered from this file, it has to be removed explicitly, since
a new commit won't be possible as long as this file exists.
@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.
@item _MTN/bisect
Contains the current state of an ongoing bisection.  See @ref{Bisecting}
for more information.
@item _MTN/update
Remembers the update / previous base revision of the workspace when
the @code{u:} selector is used.  See @ref{Selectors} for more information.
@item _MTN/conflicts
The default file which is used by monotone to read and write merge conflicts
for conflict resolution.  See @ref{Conflicts} for more information.
@item _MTN/resolutions
The directory in which monotone moves unversioned, conflicting files from
a workspace to, in case @command{update} or other commands are called with
the @option{--move-conflicting-paths} option.
@end table


@page
@node    Reserved Certs, Naming Conventions, Reserved Files, Advanced Uses
@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 suspend
This cert's value is the name of a branch (see the @code{branch} cert).
This cert is generated by the @command{suspend} command.  A suspended
revision is removed from the list of head revisions of a branch in most
cases.  A branch with all its heads suspended will not appear in the
list of branches.  Suspended revisions can still have children, and those
children are in no way affected by the suspend cert on their parent.

@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, File Attributes, Reserved Certs, Advanced Uses
@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, Merging, Naming Conventions, Advanced Uses
@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{Lua 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, Migrating and Dumping, File Attributes, Advanced Uses
@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's 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, Importing from CVS, Merging, Advanced Uses
@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, Exporting to GIT, Migrating and Dumping, Advanced Uses
@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    Exporting to GIT, Using packets, Importing from CVS, Advanced Uses
@section Exporting to GIT

Monotone is capable of exporting the contents of a database to
@code{stdout} in a form suitable to be piped to git-fast-import(1):

@smallexample
@group
$ mkdir test.git
$ cd test.git
$ git init
$ mtn --db test.mtn git_export | git fast import
@end group
@end smallexample

While this feature has been tested and verified to some extent with
various ``real-world'' monotone databases it is important to realize
that translating from one version control system to another can be a
lossy process. Git represents things somewhat differently than
monotone does and cannot fully represent some things that monotone
can. In particular git does not treat directories as first class
objects as monotone does and does not use certificates to represent
@code{author}, @code{date}, @code{branch} and @code{tag} values so
some differences are to be expected.

Git separates the concept of @code{committer} from the concept of
@code{author} while monotone allows multiple @code{author} certs. In
an attempt to represent these different concepts the git exporter uses
the @emph{value} of the author cert as the git author and the
@emph{key} used to sign the author cert as the git committer. When
there are multiple author certs the git exporter arbitrarily choses
one of them. The full list of monotone certs may be exported in the
git commit message using the @option{--log-certs} option described in
@ref{GIT}.

Monotone author names often look like raw email addresses such as
@code{"user@@example.com"}. These are not considered valid by git
which requires the display name and leading `<' and trailing `>'
characters around email addresses such as @code{"User Name
<user@@example.com>"}. The git exporter deals with this difference in
several ways:
@itemize
@item
revisions that don't have any author certs will default to using
@code{Unknown <unknown>} for both the author and committer.
@item
revisions that have one or more author certs will use the value of one
author cert as the author and the key used to sign this cert as
the committer.
@item
both author and committer will be looked up in the file specified by
the @option{--authors-file} option described in @ref{GIT} and
translated to the specified value if found.
@item
any author or committer value not found in the authors file will be
processed by the @code{unmapped_git_author} hook which may adjust the
value so that it represents a valid value.
@end itemize
All git author and committer values will be validated by the
@code{validate_git_author} hook before being written to the output
stream. The export will abort if any author or committer value is
rejected by the validation hook.

Branch names used by monotone are allowed to contain characters that
are not considered valid by git. These may be mapped to other names
using the @option{--branches-file} option described in @ref{GIT}

A monotone revision may have multiple @code{changelog} certs and
multiple @code{comment} certs. The git exporter deals with these by
first concatenating all of the changelog certs followed by all of the
comment certs into one message to use as the git commit
message. Duplicate changelog or comment cert messages that may exist
due to automated merges are removed.

Exporting a database may be a time consuming and involved process,
depending on the size and nature of the database. A 200MB database
should export in less than an hour but may take several hours or
longer depending on factors such as hardware, revision sizes, roster
sizes and many others. The monotone process exporting such a database
should require less than 200MB of RAM but may require
@emph{considerably} more in some cases. If the exported file is
written to disk it will likely be @emph{substantially} larger than the
associated database, perhaps between 400MB to 4GB in size.

Anyone using the git exporter must take full responsibility for
verifying that the exported repository matches their expectations and
requirements.

@page
@node    Using packets, Bisecting, Exporting to GIT, Advanced Uses
@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    Bisecting, , Using packets, Advanced Uses
@section Bisecting

Bisecting is an efficient means of finding the earliest revision that
introduced a bug known to exist in some later revision. Given a set of
``good'' earlier revisions that do not contain the bug and a set of
``bad'' later revisions that do contain the bug @command{bisect}
performs a binary search over the set of revisions between these two
sets to identify the specific revision that introduced the bug.

Bisection is started by marking revisions with the @command{bisect
good} and @command{bisect bad} commands. Once both good and bad
revisions have been specified the set of candidate revisions between
the good and bad revisions is determined. The midpoint of this set is
selected as the next revision to be tested and the workspace is
updated to this selected revision. After the selected revision has
been tested bisection continues when the revision is marked with
@command{bisect good} or @command{bisect bad}. If the selected
revision is marked as good, it and all of its ancestors are considered
to be good and excluded from the remaining search set. If the selected
revision is marked as bad, all of its descendants are considered to be
bad and excluded from the remaining search set. After each selected
revision is marked as good or bad the size of the remaining search set
is halved.

Revisions that are untestable for some reason (e.g. they don't
compile) may be ignored with the @command{bisect skip} command. This
excludes the specified revisions from the candidate set and allows the
bisection operation to continue. Skipping revisions may cause the
search to fail or end on the wrong revision if the revision being
searched for is skipped.

If the workspace is updated to some unrelated revision during a
bisection operation the @command{bisect update} command can be used to
update back to the next revision selected for bisection. This command
can also be used if a previous @command{bisect good}, @command{bisect
bad} or @command{bisect skip} command fails to update the workspace
due to the existence of conflicting unversioned paths.

The current status of the bisection operation and the next revision to
be tested is reported by the @command{bisect status} command. This
command can be run at any stage of the bisection operation to see how
many revisions remain to be tested and how many revisions have been
ruled out.

Currently @command{bisect} updates the workspace but does @emph{not}
update the workspace @option{branch} option. This may leave the
workspace at a revision that is @emph{not} in the branch specified by
the workspace @option{branch} option and cause subsequent commits to
be made to the wrong branch. To help avoid this error the
@command{status} command will indicate when the workspace branch does
not match any of the parent revision branches. Take care when
committing new revisions during a bisection operation and be sure to
use the @command{bisect reset} command once the bisection is complete
to update the workspace back to the revision from which the bisection
started.

The bisection operation completes successfully when the last remaining
revision is marked as ``bad''.  If the last remaining revision is
marked as ``good'' the bisection fails without finding the initial bad
revision.

Once bisection is complete the workspace can be updated back to the
starting revision with the @command{bisect reset} command. This
command also removes all stored bisection information in preparation
for future bisect operations.

@page
@node    CVS Phrasebook, Command Reference, Advanced Uses, Top
@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 -R .
$ 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, Lua Reference, CVS Phrasebook, Top
@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
* GIT::                         Exporting a monotone repository to git
@end menu


@page
@node    Tree, Workspace, Command Reference, Command Reference
@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 [--move-conflicting-paths] --revision=@var{id} @var{directory}
@itemx mtn co [--move-conflicting-paths] --revision=@var{id} @var{directory}
@itemx mtn [--move-conflicting-paths] --branch=@var{branchname} checkout @var{directory}
@itemx mtn [--move-conflicting-paths] --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 @var{address}[:@var{port}] @var{branchname} [@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. If no database is given, the configured default
database is created or re-used (see the hook
@code{get_default_database_alias} in the @ref{Lua Reference} for
more details). Then it 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.  If no @var{directory}
is given, the @var{branchname} is used as directory.

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

A commit message may be provided. A message stating the revision ids
that were merged will be prepended to any user commit message.

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.

A commit message may be provided. A message stating the source and
target branches will be prepended to any user commit message.

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.

Roughly speaking, @command{mtn import} does the following:

@example
@group
$ mtn setup @r{(with a twist)}
$ mtn drop --missing
$ mtn add --unknown
$ mtn commit
@end group
@end example

The twist with the @command{mtn setup} part is that it sets the parent
to be the given revision or the head of the given branch instead of the
null revision.
@end ftable

@page
@menu
* Conflicts::
@end menu

@node    Conflicts,  , Tree, Tree
@subsection Conflicts
The @command{conflicts} set of commands is used to specify conflict
resolutions for merges, asynchronously from the merge command itself.
This lets the user take as much time as needed to prepare all the
conflict resolutions, and avoids losing work when a merge is aborted
due to a complicated conflict.

These commands require a workspace, to provide a place to store the
conflicts and user resolution files.

For all of these commands, if the @command{--conflicts-file} option is
not given, the file @file{_MTN/conflicts} is used. If the
@command{--conflicts-file} option is given, the file must be in the
bookkeeping directory.

Files given in these commands are relative to the current working
directory, or absolute. In the conflict file, they are relative to the
workspace root, or absolute.

@subheading Commands

@ftable @command
@item mtn conflicts --conflicts-file=@var{file} store @var{left_rev_id} @var{right_rev_id}
Store the conflicts encountered by merging @var{left_rev_id} with
@var{right_rev_id}, in the specified file.

If @var{left_rev_id} and @var{right_rev_id} are not given, the first
two heads that the @command{merge} command would merge are used.

The conflicts file format is as output by the @command{automate
show_conflicts} command; see @xref{Automation}.

Content conflicts that can be resolved by the internal line merger
have resolutions, so they will not show up in subsequent
@command{show_first} commands.

@item mtn conflicts --conflicts-file=@var{file} show_first
Show the first unresolved conflict in the conflicts file, and list the
possible resolutions.

@item mtn conflicts --conflicts-file=@var{file} show_remaining
Show remaining unresolved conflicts in the conflicts file.

@item mtn conflicts --conflicts-file=@var{file} resolve_first @var{resolution}
Specify a resolution for the first conflict in the conflicts file; it
must be a single file conflict. The conflicts file is updated.

@item mtn conflicts --conflicts-file=@var{file} resolve_first_left @var{resolution}
@itemx mtn conflicts --conflicts-file=@var{file} resolve_first_right @var{resolution}
Specify a resolution for one of the files in the first conflict in the
conflicts file; it must be a two file conflict. The conflicts file is
updated.

@item mtn conflicts clean
Delete the default conflicts file @file{_MTN/conflicts}, and the
directory @file{_MTN/resolutions}. Users may store conflict
resolution files in @file{_MTN/resolutions}; this command provides a
convenient way to clean up.
@end ftable

@subheading Single file conflict resolutions

For single file conflicts, there are several possible resolutions:

@ftable @command
@item interactive @var{file}
The Lua @code{merge3} hook is called to allow the user to manually
merge the left and right files, leaving the result in the specified file.

@var{file} must be a bookkeeping path; under @file{_MTN}.

This inserts a @var{resolved_user_left file} conflict resolution in the
conflicts file.

@item user @var{file}
The file contents are replaced by the contents of the specified file.

This inserts a @var{resolved_user_left file} conflict resolution in the
conflicts file.

@item drop
The file is dropped in the merge. This is useful for an orphaned file
conflict.

This inserts a @var{resolved_drop_left} conflict resolution in the
conflicts file.

@item rename @var{filename}
The file is renamed. This is useful for an orphaned file
conflict.

This inserts a @var{resolved_rename_left filename} conflict resolution
in the conflicts file.

@end ftable

@subheading Two file conflict resolutions

For two file conflicts, the possible resolutions are:

@ftable @command
@item drop
The file is dropped in the merge.

This inserts a @var{resolved_drop_left} or @var{resolved_drop_right}
conflict resolution in the conflicts file.

@item keep
The file is kept in the merge.

This inserts a @var{resolved_keep_left} or @var{resolved_keep_right}
conflict resolution in the conflicts file.

@item rename @var{filename}
The file is renamed.

This inserts a @var{resolved_rename_left filename} or
@var{resolved_rename_right filename} conflict resolution in the
conflicts file.

@item user @var{file}
The file contents are replaced by the contents of the specified file.
The other file in the conflict must be dropped or renamed.

This inserts a @var{resolved_user_left file} or
@var{resolved_user_right file} conflict resolution in the conflicts
file.

@end ftable

monotone internals note: we don't provide an @code{interactive}
resolution for two-file conflicts, because monotone currently does not
provide a @code{merge2} Lua hook. two-file conflicts don't have a
shared ancestor, so @code{merge3} is not applicable.

@page
@node    Workspace, Network, Tree, Command Reference
@section Workspace

@ftable @command
@item mtn setup -b @var{branchname} [-d @var{database}] [@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
to be used.  If no database is given, the configured default
database is created or re-used (see the hook
@code{get_default_database_alias} in the @ref{Lua Reference} for
more details).
Both settings, branch and database name, 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 [--recursive | -R] [--no-respect-ignore] @var{pathname...}
@item mtn add [--recursive | -R] [--no-respect-ignore] --unknown [@var{pathname...}]
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.

Adding directories, whether explicitly or using the @option{--unknown}
option, is non-recursive by default.  The @command{add} command can be
made recursive using the @option{--recursive} option.  When adding a
directory non-recursively, monotone will warn if the directory has
any files that would be added by a recursive add.

@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 @file{.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 undrop @var{pathname...}
Undoes a previous ``drop''; useful when you make a mistake. If the
file was deleted from the workspace, this reverts it. If it was not
deleted (because it was changed), it just removes the pending drop.

@item mtn [--bookkeep-only] rename @var{src} @var{dst}
@itemx 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.  In the case where
@var{dst} must be a directory (multiple @var{src} items), exists
physically in the filesystem as a directory or is specified as a
directory by convention (a trailing /), it will be automatically added
to the workspace if it is not already versioned.

@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 parameter named @var{user_log_message}.  The
log message passed to the user's editor will contain a line that the
user may remove allowing them 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 @option{--message-file=_MTN/log} is specified, the contents of
@file{_MTN/log} will be used without confirmation.

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{user_log_message})}, which typically invokes
an external editor program, in which you can compose and/or review the
revision and log message for the change.
@end itemize

The @var{user_log_message} passed to the @code{edit_comment} hook will
contain a full summary of the revision as it would have been displayed
by the @command{status} command prior to committing and as the
@command{log} command will display it after it has been committed:

@smallexample
@group
Enter a description of this change following the Changelog line below.
The values of Author, Date and Branch may be modified as required.

*** REMOVE THIS LINE TO CANCEL THE COMMIT ***
----------------------------------------------------------------------
Revision: 42eae36587508faa664b111cefc291f0b85ef83a
Parent:   493bda86628fd72c992eb56f73899db9ead3cf6f
Author:   abe@@juicebot.co.jp
Date:     2004-10-26T02:53:08
Branch:   jp.co.juicebot.jb7

Changelog:

polling implementation of src/apple.c

----------------------------------------------------------------------
Changes against parent 493bda86628fd72c992eb56f73899db9ead3cf6f

  patched  src/apple.c

@end group
@end smallexample

Values specified in @option{--author}, @option{--date} or
@option{--branch} options on the command line will be displayed in the
editor and may be further changed while editing the changelog
message. The changelog message will be extracted from between the
@code{Changelog:} header and the trailing line of @code{----}
characters. Care must be taken to ensure no other lines are changed or
the commit will abort to avoid extracting an incorrect message. If the
commit needs to be cancelled the line following the leading
instructions should be removed. Any pending text in @file{MTN/log}
will be left untouched if the commit is cancelled.


@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 [--move-conflicting-paths]
@itemx mtn update [--move-conflicting-paths] --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 [--move-conflicting-paths] --revision=@var{to}
@itemx mtn pluck [--move-conflicting-paths] --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] [--move-conflicting-paths] 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.

@item mtn bisect good [--revision=@var{id} ...] [--move-conflicting-paths]
Mark the specified revisions as ``good'' for the current bisection
operation. If no bisection operation is in progress a new bisection is
initialized. If a bisection operation is in progress the next update
target is selected and the workspace is updated to the selected
revision.

If the update is blocked by conflicting unversioned paths existing in
the workspace this command may be re-issued with the
@option{--move-conflicting-paths} option. Alternatively, the
@command{bisect update} command can be used with this option to update
the workspace and move the conflicting paths out of the way.

@item mtn bisect bad [--revision=@var{id} ...] [--move-conflicting-paths]
Mark the specified revisions as ``bad'' for the current bisection
operation. If no bisection operation is in progress a new bisection is
initialized. If a bisection operation is in progress the next update
target is selected and the workspace is updated to the selected
revision.

If the update is blocked by conflicting unversioned paths existing in
the workspace this command may be re-issued with the
@option{--move-conflicting-paths} option. Alternatively, the
@command{bisect update} command can be used with this option to update
the workspace and move the conflicting paths out of the way.

@item mtn bisect skip [--revision=@var{id} ...] [--move-conflicting-paths]
Mark the specified revisions as ``skipped'' for the current bisection
operation. If no bisection operation is in progress a new bisection is
initialized. If a bisection operation is in progress the next update
target is selected and the workspace is updated to the selected
revision.

If the update is blocked by conflicting unversioned paths existing in
the workspace this command may be re-issued with the
@option{--move-conflicting-paths} option. Alternatively, the
@command{bisect update} command can be used with this option to update
the workspace and move the conflicting paths out of the way.

@item mtn bisect update [--move-conflicting-paths]
Update the workspace to the next revision selected by the previous
bisect operation. This command can be useful when the previous bisect
operation fails to update the workspace because of conflicting
unversioned paths existing in the workspace.

@item mtn bisect status
Report the status of the current bisection operation including the
number of revisions that remain to be tested, the number of revisions
that have been tested and the next revision that will selected for
testing.

@item mtn bisect reset
Reset the current bisection operation by updating the workspace back
to the revision from which the bisection was started and clearing the
current bisection information.

@end ftable

@page
@node    Network, Informative, Workspace, Command Reference
@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] [--keys-to-push=@var{key}] [@var{uri-or-address}] [@var{glob} [...] [--exclude=@var{exclude-glob}]]]
@itemx mtn sync [--set-default] [--keys-to-push=@var{key}] [@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{Lua 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, Key and Cert Trust, Network, Command Reference
@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} [...]] [--revision=@var{id} [...]] [--brief] [--no-merges] [--no-files] [--no-graph] [--diffs] [@var{pathname...}]

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

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

If @option{--last=}@var{n} is given, at most @var{n} log entries will
be given and log will trace through history in reverse-ancestry order,
from newer revisions to older revisions.

If @option{--next=}@var{n} is given, at most @var{n} log entries will
be given and log will trace through history in forward-ancestry order,
from older revisions to newer revisions. 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, log starts tracing through
history from the specified revisions, otherwise it starts from the
base revision of your workspace. Log will stop when it reaches the end
of the revision history or revisions specified by the @option{--to}
option.

When tracing through history in reverse-ancestry order and
@option{--to=}@var{id} is given, log will stop when it reaches the
specified revisions or any of their ancestors or the end of the
revision history. When tracing through history in forward-ancestry
order log will stop when it reaches the specified revisions or any of
their descendants or the end of the revision history.

If @option{--revision=}@var{id} is given, log will print only the
specified revisions.

If both @option{--from} and @option{--revision} are given only
revisions included by both options will be logged. Revisions specified
by @option{--revision} that are beyond the starting points specified
by @option{--from} will be excluded.

Additionally, each of the @option{--from}, @option{--to} and
@option{--revision} options accept selectors, see
@ref{Selectors}. These can be used in various ways to log interesting
revisions.  For example:
@verbatim
$ mtn log --revision b:
$ mtn log --revision today
$ mtn log --revision bob
@end verbatim
will log all revisions from the current branch, all revisions dated
today and all revisions with bob as the author, respectively.

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.

If @option{--no-graph} is given, the log output excludes the ASCII revision graph
prefix on log output lines.

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}] [--revs-only] @var{file}

Dumps an annotated copy of the file to stdout. 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.

If @option{--revs-only} is specified, 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.

@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
$ mtn 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] [--no-show-encloser]
@itemx mtn diff --context [--no-show-encloser]
@itemx mtn diff --external [--diff-args=@var{argstring}]
@itemx mtn diff @var{pathname...}
@itemx mtn diff [--reverse] --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 difference from the
base revision to the current revision in the workspace.

With one @option{--revision} option, @command{diff} will print the
difference from the revision @var{id} to the current revision in the
workspace. If @option{--reverse} is given, the order of the diff is
reversed.

With two @option{--revision} options @command{diff} will print the
difference from revision @var{id1} to @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{--no-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, monotone prints the name of the top-level code
construct that encloses each ``hunk'' of changes, unless suppressed with
the @option{--no-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}.  For the regular expression
syntax, @xref{Regexps}.

@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 used to sign 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 (10b5b36b4a...)
Sig   : ok
Name  : author
Value : graydon@@dub.venge.net
-----------------------------------------------------------------
Key   : graydon@@pobox.com (10b5b36b4a...)
Sig   : ok
Name  : branch
Value : monotone
-----------------------------------------------------------------
Key   : graydon@@pobox.com (10b5b36b4a...)
Sig   : ok
Name  : date
Value : 2003-10-17T03:20:27
-----------------------------------------------------------------
Key   : graydon@@pobox.com (10b5b36b4a...)
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 duplicates [--revision=@var{id}]
@item mtn ls duplicates [--revision=@var{id}]

This command lists duplicate files in a given revision. If no revision is
given, the workspace is used instead. Ignored and unknown files are
excluded from the listing.

Two or more files are considered duplicates if the @sc{sha1} hashes of their
contents are equal.

@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 [@var{pattern}] [--exclude=@var{pattern}]
@item mtn ls branches [@var{pattern}] [--exclude=@var{pattern}]

This command lists all known branches in your database. If
@var{pattern} is provided, it is used as a glob to select the branches
listed, otherwise all branches are listed.  If @option{-exclude}
options are provided they are used as globs to exclude specified
branches.

@item mtn list tags [@var{pattern}] [--exclude=@var{pattern}]
@item mtn ls tags [@var{pattern}] [--exclude=@var{pattern}]

This command lists all known tags in your database. If @var{pattern}
is provided, it is used as a glob to select the tags listed, otherwise
all tags are listed.  If @option{-exclude} options are provided they
are used as globs to exclude specified tags.

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

Note that this does not show conflicts due to update commands, since
in that case one revision is the workspace.
@end ftable


@page
@node    Key and Cert Trust, Certificate, Informative, Command Reference
@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.keyhash}.  The key's hash is printed out after
the key has been created.

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{key_identity})}, but this significantly
increases the risk of a key compromise on your local computer. Be
careful using this hook.

The public key is stored in the database; the public and private keys
are stored in the keystore. This allows copying the database without
copying the private key.

The location of the keystore is specified by the @option{--keydir}
option; it defaults to the value stored in @file{_MTN/options} for
commands executed in a workspace, or to
the system default (@file{~/.monotone/keys} on Unix and Cygwin,
@file{%APPDATA%/monotone/keys} on native Win32).

@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{keyid}

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{Lua Reference}).  You pass it
a revision ID, a certificate name, a certificate value, and one or more
key IDs or key names, 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.

The specified keys mist exist either in your keystore or in the database.

@item mtn ssh_agent_add

This command will add your monotone keys to your current ssh-agent session.
You will be asked for the passphrase for each of your monotone private keys
and they will be added to the ssh-agent. Once this is done you should be able
to type @emph{ssh-add -l} and see your monotone key listed. When you
subsequently use these keys through monotone it will use ssh-agent for signing
without asking your for your passphrase.

This command is mainly for use in a session script as monotone will automatically
add your keys to ssh-agent on first use if it is available. For example the
following two examples are equivalent:

@smallexample
@group
$ mtn ssh_agent_add
enter passphrase for key ID [user@@example.com]:
$ mtn ci -m"Changed foo to bar"
$ mtn push -k user@@example.com
@end group
@end smallexample

@smallexample
@group
$ mtn ci -m"Changed foo to bar"
enter passphrase for key ID [user@@example.com]:
$ mtn push -k user@@example.com
@end group
@end smallexample

In the second example, monotone automatically added the key to ssh-agent, making
entering the passphrase not needed during the push.

@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] (1234abcd...):
enter new passphrase for key ID [user@@example.com] (1234abcd...):
confirm passphrase for key ID [user@@example.com] (1234abcd...):
$ 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 -k user@@example.com
@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, Packet I/O, Key and Cert Trust, Command Reference
@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 suspend @var{id}

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

@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, Database, Certificate, Command Reference
@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, Automation, Packet I/O, Command Reference
@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 register_workspace [@var{workspace_path}]

Registers the given workspace from the current database, so that it
will show up in the output of @command{list databases} (the database
has to be in a managed location for this to work).

If no @var{workspace_path} is given, this command defaults to the
current workspace.

@item mtn unregister_workspace [@var{workspace_path}]

Unregisters the given workspace from the current database, so that it
will no longer show up in the output of @command{list databases}.

If no @var{workspace_path} is given, this command defaults to the
current workspace.

@item mtn cleanup_workspace_list

Removes all invalid workspaces from the list of registered workspaces
of the current database.  A workspace is considered invalid if its path
does either not contain an _MTN directory anymore or if the configured
database for this workspace is a different one.

@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}.

@item branches not used or with incorrect head count or missing
in the cache of branch heads. This is a serious problem; it suggests
the presence of a bug in monotone's caching system, but does not
involve data loss; please report this on the monotone mailing
list. You can fix it by running @command{db regenerate_caches}.

@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.  If you execute this command in a workspace, whose
parent revision is the one you are about to delete, the killed revision
is re-applied to this workspace which makes it possible for you to fix
a problem and commit again later on easily. For this to work, the
workspace may not have any changes and/or missing files.

There are a number of other caveats with this command:
@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, RCS, Database, Command Reference
@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 Changes:

@itemize
@item
11.0 -- @var{signer} now prints the hash of the signing key, no longer the name.
        Also, the @var{format_version} stanza has been removed in favour of the
        global @var{interface_version}.
@item
2.2 -- added
@end itemize

@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
     tag "monotree-0.1"
revision [8a121346ce2920b6f85df68b3b620de96bd14a8d]
  signer [de84b575d5e47254393eba49dce9dc4db98ed42d]
branches "net.venge.monotone.contrib" "net.venge.monotone.contrib.monotree"

     tag "monotree-0.2"
revision [5d288b39b49613b0d9dca8ece6b9a42c3773f35b]
  signer [de84b575d5e47254393eba49dce9dc4db98ed42d]
branches "net.venge.monotone.contrib.monotree"

     tag "monotree-0.3"
revision [35cff8e8ba14155f5f7ddf7965073f514fd60f61]
  signer [de84b575d5e47254393eba49dce9dc4db98ed42d]
branches "net.venge.monotone.contrib.monotree"

     tag "monotree-0.4"
revision [f1afc520474f83c58262896ede027ef77226046e]
  signer [de84b575d5e47254393eba49dce9dc4db98ed42d]
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.3

@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 [@option{options...}] [@var{files...}]

@table @strong
@item Arguments:

One or more file paths (optional). If present, only show an inventory for the
given files or directories (and their sub-directories).

@table @option
@item --depth=@var{n}
Maximum number of directories to descend.

@item --exclude=@var{exclude-glob}
File or directory to exclude.

@item --no-ignored
Don't output ignored files or directories.

@item --no-unknown
Don't output unknown directories.

@item --no-unchanged
Don't output files that are known but not changed in any way.

@item --no-corresponding-renames
If restricted to a renamed path, do not output the corresponding old / new
paths for this restriction.

@end table

@item Changes:

@itemize
@item
8.0 -- added the output of the @code{birth} key
@item
7.0 -- added options @option{--no-ignored}, @option{--no-unknown},
@option{--no-unchanged} and @option{--no-corresponding-renames}
@item
6.0 -- converted to basic_io format (restriction support, various fixes)
@item
1.0 -- initial, line-based format
@end itemize

@item Purpose:

Prints the inventory of every file found in the workspace or its
associated base and revision manifests. Each unique path is
listed in a basic_io stanza. Stanzas are separated by blank lines.

@item Sample output:

All basic status cases:
@verbatim
    path "added"
new_type "file"
 fs_type "file"
  status "added" "known"
 changes "content"

    path "attributes_altered"
old_type "file"
new_type "file"
 fs_type "file"
   birth [cb271687054afd3c2b873c8994f206f08fb240d3]
  status "known"
 changes "attrs"

    path "dropped"
old_type "file"
 fs_type "none"
   birth [cb271687054afd3c2b873c8994f206f08fb240d3]
  status "dropped"

   path "ignored~"
fs_type "file"
 status "ignored"

    path "missing"
old_type "file"
new_type "file"
 fs_type "none"
   birth [cb271687054afd3c2b873c8994f206f08fb240d3]
  status "missing"

    path "original"
old_type "file"
new_path "renamed"
 fs_type "none"
   birth [cb271687054afd3c2b873c8994f206f08fb240d3]
  status "rename_source"

    path "patched"
old_type "file"
new_type "file"
 fs_type "file"
   birth [cb271687054afd3c2b873c8994f206f08fb240d3]
  status "known"
 changes "content"

    path "patched_and_attributes_altered"
old_type "file"
new_type "file"
 fs_type "file"
   birth [cb271687054afd3c2b873c8994f206f08fb240d3]
  status "known"
 changes "content" "attrs"

    path "renamed"
new_type "file"
old_path "original"
 fs_type "file"
   birth [cb271687054afd3c2b873c8994f206f08fb240d3]
  status "rename_target" "known"

    path "unchanged"
old_type "file"
new_type "file"
 fs_type "file"
   birth [cb271687054afd3c2b873c8994f206f08fb240d3]
  status "known"

   path "unknown"
fs_type "file"
 status "unknown"
@end verbatim

Two files swapped in both the revision manifest and the workspace:
@verbatim
    path "original"
old_type "file"
new_path "unchanged"
new_type "file"
old_path "unchanged"
 fs_type "file"
   birth [cb271687054afd3c2b873c8994f206f08fb240d3]
  status "rename_source" "rename_target" "known"

    path "unchanged"
old_type "file"
new_path "original"
new_type "file"
old_path "original"
 fs_type "file"
   birth [cb271687054afd3c2b873c8994f206f08fb240d3]
  status "rename_source" "rename_target" "known"
@end verbatim

Recorded in the revision manifest that two files were swapped, but
they were not actually swapped in the workspace. Thus they both appear
as patched:
@verbatim
    path "original"
old_type "file"
new_path "unchanged"
new_type "file"
old_path "unchanged"
 fs_type "file"
   birth [cb271687054afd3c2b873c8994f206f08fb240d3]
  status "rename_source" "rename_target" "known"
 changes "content"

    path "unchanged"
old_type "file"
new_path "original"
new_type "file"
old_path "original"
 fs_type "file"
   birth [cb271687054afd3c2b873c8994f206f08fb240d3]
  status "rename_source" "rename_target" "known"
 changes "content"

@end verbatim

Rename (in the manifest and the workspace) @file{foo} to @file{bar};
add (in the manifest and the workspace) new file @file{foo}:
@verbatim
    path "foo"
old_type "file"
new_path "bar"
new_type "file"
 fs_type "file"
   birth [cb271687054afd3c2b873c8994f206f08fb240d3]
  status "rename_source" "added" "known"

    path "bar"
new_type "file"
old_path "foo"
 fs_type "file"
   birth [cb271687054afd3c2b873c8994f206f08fb240d3]
  status "rename_target" "known"
@end verbatim

Rotated files @file{foo} -> @file{bar} -> @file{baz} -> @file{foo} (in
the manifest and the workspace):
@verbatim
    path "foo"
old_type "file"
new_path "bar"
new_type "file"
old_path "baz"
 fs_type "file"
   birth [cb271687054afd3c2b873c8994f206f08fb240d3]
  status "rename_source" "rename_target" "known"

    path "bar"
old_type "file"
new_path "baz"
new_type "file"
old_path "foo"
 fs_type "file"
   birth [cb271687054afd3c2b873c8994f206f08fb240d3]
  status "rename_source" "rename_target" "known"

    path "baz"
old_type "file"
new_path "foo"
new_type "file"
old_path "bar"
 fs_type "file"
   birth [cb271687054afd3c2b873c8994f206f08fb240d3]
  status "rename_source" "rename_target" "known"
@end verbatim

Recorded in the revison manifest 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
    path "foo"
old_type "file"
new_path "bar"
new_type "file"
old_path "baz"
 fs_type "file"
   birth [cb271687054afd3c2b873c8994f206f08fb240d3]
  status "rename_source" "rename_target" "known"
 changes "content"

    path "bar"
old_type "file"
new_path "baz"
new_type "file"
old_path "foo"
 fs_type "file"
   birth [cb271687054afd3c2b873c8994f206f08fb240d3]
  status "rename_source" "rename_target" "known"
 changes "content"

    path "baz"
old_type "file"
new_path "foo"
new_type "file"
old_path "bar"
 fs_type "file"
   birth [cb271687054afd3c2b873c8994f206f08fb240d3]
  status "rename_source" "rename_target" "known"
 changes "content"
@end verbatim

Dropped from the manifest but not removed in the workspace and thus
unknown:
@verbatim
    path "dropped"
old_type "file"
 fs_type "file"
   birth [cb271687054afd3c2b873c8994f206f08fb240d3]
  status "dropped" "unknown"
@end verbatim

Added in the manifest but not in the workspace, and thus missing:
@verbatim
    path "added"
new_type "file"
 fs_type "none"
  status "added" "missing"
@end verbatim

Recorded a rename in the manifest, but not moved in the workspace,
and thus unknown source and missing target:
@verbatim
    path "original"
old_type "file"
new_path "renamed"
 fs_type "file"
   birth [cb271687054afd3c2b873c8994f206f08fb240d3]
  status "rename_source" "unknown"

    path "renamed"
new_type "file"
old_path "original"
 fs_type "none"
   birth [cb271687054afd3c2b873c8994f206f08fb240d3]
  status "rename_target" "missing"
@end verbatim

Moved in the workspace but no rename recorded in the manifest, and
thus missing source and unknown target:
@verbatim
    path "original"
old_type "file"
new_type "file"
 fs_type "none"
  status "missing"

   path "renamed"
fs_type "file"
 status "unknown"
@end verbatim

Renamed in the manifest and the workspace and patched:
@verbatim
    path "original"
old_type "file"
new_path "renamed"
 fs_type "none"
   birth [cb271687054afd3c2b873c8994f206f08fb240d3]
  status "rename_source"

    path "renamed"
new_type "file"
old_path "original"
 fs_type "file"
   birth [cb271687054afd3c2b873c8994f206f08fb240d3]
  status "rename_target" "known"
 changes "content"
@end verbatim

Renamed and restricted to @file{original} or @file{renamed}:
@verbatim
    path "original"
old_type "file"
new_path "renamed"
 fs_type "none"
   birth [cb271687054afd3c2b873c8994f206f08fb240d3]
  status "rename_source"

    path "renamed"
new_type "file"
old_path "original"
 fs_type "file"
   birth [cb271687054afd3c2b873c8994f206f08fb240d3]
  status "rename_target" "known"
 changes "content"
@end verbatim

Renamed and restricted to @file{original} with the @option{--no-corresponding-renames} option:
@verbatim
    path "original"
old_type "file"
new_path "renamed"
 fs_type "none"
   birth [cb271687054afd3c2b873c8994f206f08fb240d3]
  status "rename_source"
@end verbatim

Renamed and restricted to @file{renamed} with the @option{--no-corresponding-renames} option:
@verbatim
    path "renamed"
new_type "file"
old_path "original"
 fs_type "file"
   birth [cb271687054afd3c2b873c8994f206f08fb240d3]
  status "rename_target" "known"
 changes "content"
@end verbatim

File is missing, an unversioned directory is in the way:
@verbatim
    path "missing_file"
old_type "file"
new_type "file"
 fs_type "directory"
   birth [cb271687054afd3c2b873c8994f206f08fb240d3]
  status "invalid"
 changes "content"
@end verbatim

Directory is missing, an unversioned file is in the way:
@verbatim
    path "missing_directory"
old_type "directory"
new_type "directory"
 fs_type "file"
  status "invalid"
@end verbatim

Directory @file{source} renamed to @file{target}, @file{target} is missing, an
unversioned file is in the way:
@verbatim
    path "source"
old_type "directory"
new_path "target"
 fs_type "none"
   birth [cb271687054afd3c2b873c8994f206f08fb240d3]
  status "rename_source"

    path "source/a"
old_type "file"
new_path "target/a"
 fs_type "none"
   birth [cb271687054afd3c2b873c8994f206f08fb240d3]
  status "rename_source"

    path "target"
new_type "directory"
old_path "source"
 fs_type "file"
   birth [cb271687054afd3c2b873c8994f206f08fb240d3]
  status "rename_target" "invalid"

    path "target/a"
new_type "file"
old_path "source/a"
 fs_type "none"
   birth [cb271687054afd3c2b873c8994f206f08fb240d3]
  status "rename_target" "missing"
@end verbatim

@item Output format:

Each path is printed in one basic_io stanza. Stanzas are separated by
a blank line. Each stanza starts with a @code{path} line, and contains
up to seven lines. The order of the lines is not important, and may
change in future revisions, except that the first line will always be
@code{path}.

@table @option
@item path
The file or directory path, relative to the workspace root. The file
either exists in the workspace, or is listed in the base or revision
manifest.
@option{path} is always output.

@item old_type
The type of the node in the base manifest.
``type'' is either @option{file} or @option{directory}.
@option{old_type} is output for all old nodes (i.e. unchanged or dropped paths
and rename sources).

@item new_type
The type of the node in the revision manifest.
``type'' is either @option{file} or @option{directory}.
@option{new_type} is output for all new nodes (i.e. unchanged or added paths
and rename targets).

@item fs_type
The type of the node in the workspace (also called the filesystem).
``type'' is either @option{file}, @option{directory} or @option{none}
(if the path does not exist in the file system).
@option{fs_type} is always output.

@item old_path
The old path for the node, if it has been renamed in the revision
manifest.
@option{old_path} is only output for rename targets.

@item new_path
The new path for the node, if it has been renamed in the revision
manifest.
@option{new_path} is only output for rename sources.

@item birth
The identify of the revision that the node was first added in.
@option{birth} is only output if it exists in a committed revision.

@item status
@option{status} is always output. Its value is one or more of:

@table @option
@item rename_source
@var{path} is part of a rename and denotes the old name of a renamed node.

@item rename_target
@var{path} is part of a rename and denotes the new name of a renamed node.

@item added
@var{path} has been added in the revision manifest, but not existent in the
base manifest.

@item dropped
@var{path} has been deleted in the revision manifest and the workspace.

@item missing
@var{path} has been deleted in the workspace, but still exists in the revision
manifest.

A file will also be labeled @option{missing} if it is in a directory
that is ignored due to a regular expression in @file{.mtn-ignore}, but
is also in the revision manifest. A warning is issued in this case.

@item ignored
@var{path} is ignored by monotone.

@item known
@var{path} exists in the workspace, and in the revision manifest.

@item unknown
@var{path} exists in the workspace, but not in the revision manifest, i.e.
is unversioned.

@item invalid
@var{path} is versioned and exists in the workspace and revision manifest, but
with incompatible types (a versioned missing file is replaced by an
unversioned directory and vice versa).
@end table

@item changes
   @table @option
   @item content
   The contents of a file have been changed.

   @item attrs
   The attributes of a path (file or directory) have been changed.

   @end table
@end table

@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 Changes:
@itemize
@item
11.0 -- Keys are now listed by hash instead of name.
@item
1.0 -- Added.
@end itemize

@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'
      the hex-encoded hash of 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 [5cd3b3a7ad2e8645e8887af193ee522dc59112e4]
signature "ok"
     name "author"
    value "emile@alumni.reed.edu"
    trust "trusted"

      key [5cd3b3a7ad2e8645e8887af193ee522dc59112e4]
signature "ok"
     name "branch"
    value "net.venge.monotone"
    trust "trusted"

      key [5cd3b3a7ad2e8645e8887af193ee522dc59112e4]
signature "ok"
     name "changelog"
    value "propagate from branch 'net.venge.monotone.annotate' (head 76a886ef7c8ae12a4bba5fc2bd252557bf863aff)
            to branch 'net.venge.monotone' (head 2490479a4e4e99243fead6d627d78291fde592f0)
"
    trust "trusted"

      key [5cd3b3a7ad2e8645e8887af193ee522dc59112e4]
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 Changes:

@itemize
@item
12.0 -- Introduced out of band streams ('e', 'p', 't', 'w'); the main output
    of a command now only happens in the 'm' stream; the 'l' stream now marks
    the end of all streams of a command; introduced the concept of "headers"
    which are output before the first command is issued; specific error codes
    to distinguish command from interface errors have also been introduced.
@item
3.1 -- Added the 'o' item to the recognized input. This change should not
break anything.
@item
1.0 -- Initial version.
@end itemize

@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. For flag options that
don't take values, specify the second string as zero length; @code{0:}.

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
format-version: 2

0:m:41:7706a422ccad41621c958affa999b1a1dd644e79
0:l:1:0
...
1:e:38:misuse: key 'test@test' already exists
1:l:1:2
...
2:w:39:skipping file '\' with unsupported name
2:m:144:    path ""
old_type "directory"
new_type "directory"
 fs_type "directory"
   birth [276264b0b3f1e70fc1835a700e6e61bdbe4c3f2f]
  status "known"
...
3:t:34:c:certificates;k:keys;r:revisions;
3:t:12:c=0;k=0;r=0;
3:t:13:c#0;k#0;r#64;
3:t:14:c#0;k#0;r#128;
3:t:6:c;k;r;
...
@end verbatim

@item Output format:

Right after a stdio session has been set up, header information is
issued; to date the only header defined is @code{format-version},
which denotes the version of the stdio format used throughout the
session. The original format had no such version output, so our
numbering starts with "2" here.

Headers are separated from each other by single newline character @code{'\n'}
and the last is separated from the following output by a pair of newline
characters.

After a command has been issued, one or more packets are returned for it.
A packet looks like:

@verbatim
<command number>:<stream>:<size>:<output>
@end verbatim

@code{<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.

@code{<stream>} is an identifier for which output stream this packet represents,
allowing multiple streams to be multiplexed over the channel.  The following
streams are presently defined; more streams may be added later.

@itemize
@item
 @code{m}: this stream represents the normal ("main") stdout automate output of
 the command, formatted as described in the description for that command.
@item
 @code{e}: this stream represents any (unstructured) error message data.

 Internally, this maps to calls to the @code{E()} print macros that would
 normally be written by the command to the program's stderr stream, if the
 automate sub-command had been called directly rather than via '''stdio'''.
@item
 @code{w}: this stream represents any (unstructured) warning message data.

 Internally, this maps to calls to the @code{W()} print macro that would
 normally be written by the command to the program's stderr stream, if the
 automate sub-command had been called directly rather than via '''stdio'''.
@item
 @code{p}: this stream represents any (unstructured) progress message data.

 Internally, this maps to calls to the @code{P()} print macro that would
 normally be written by the command to the program's stderr stream, if the
 automate sub-command had been called directly rather than via '''stdio'''.
@item
 @code{t}: this stream represents ticker updates, which may be used
 by a user interface to display the progress of a command.

 The output for this channel can be described as follows:

 @itemize
 @item
 @code{<output>       ::= <definition><payload><end>}
 @item
 @code{<definition>   ::= <shortname> ':' <longname> <eol>}
 @item
 @code{<payload>      ::= <total_count><advance>+}
 @item
 @code{<end>          ::= <shortname> <eol>}
 @item
 @code{<total_count>  ::= <shortname> '=' <count> <eol>}
 @item
 @code{<advance>      ::= <shortname> '#' <count> <eol>}
 @item
 @code{<shortname>    ::= "\w+"}
 @item
 @code{<longname>     ::= "[^;]+"}
 @item
 @code{<count>        ::= ['0'-'9']+}
 @item
 @code{<eol>          ::= ';'}
 @end itemize

 The definition tells the implementor the short name and long name of
any upcoming ticker event. The names and meanings are command-specific
and are therefore explained in the sections for the particular
commands which support ticker output.

 The @code{total_count} might be 0 right at the start and can later be changed
 to a different number if the command later on knows a more exact value. If
 this is the case, this stanza is output again with this new value. A
 constant @code{total_count} of 0 means that the command may continue to run
 for a undefined amount of time until the end stanza appears.

 The advance tells the implementor how much work has been done so far.

 Finally, the end stanza is printed just before the ticker ends
 (i.e. the work has been done).

 All counts output absolute, raw values; no modulation takes place. It
is usually the case that definition, @code{total_count}, advance and
end are output in separate stanzas. It is also possible that two or
more parallel tickers output their stanzas at the same time, in this
case it's ensured that the output does not get intermixed; first
all definitions are output, afterwards all total_counts, and so on.

 @emph{Note:} The ticker format used for stdio is fixed and cannot be selected
 explicitely via the global @option{--ticker} option. However, if you run an
 automate command outside of stdio you can set a different ticker type, f.e.
 @var{count}, @var{dot} or @var{none}.
@item
 @code{l}: this stream marks the termination of a command and all of
 its streams and carries the return code of the command in the payload.

 A return code "0" stands for success, "1" for an error which occurred within
 the stdio interface (f.e. syntax errors or missing privileges) before the
 command is run and finally "2" for any other command-specific error.
@end itemize

@code{<size>} is the number of bytes in the output.

@code{<output>} is a piece of the output of the command.

@item Error conditions:

Errors in the commands run through this interface do not affect the exit
status of this command. Instead, if a badly formatted or invalid command
is received, or a command is given with invalid arguments or options,
an error message to the error stream is printed and and the particular
sub-command exits with return code "1". Other command-specific errors are
returned as code "2".

Trying to run the @code{automate stdio} or @code{automate remote_stdio}
sub-commands will exit the particular command with return code "1".

@item Notes:

Keyboard interaction is disabled, just as if @option{--non-interactive} is
specified. Actions which require operations on password-encrypted private keys
will therefor fail unless the @code{get_passphrase} hook is set up locally.

@item Multiple streams

The multiple stream encoding allows the output of errors and warnings to be
associated with the command that generated them, allows the communication
path to always stay in sync, and offers the opportunity to add other stream
types for other useful purposes in the future as needs arise.

@end table

@item mtn automate remote_stdio [@var{hostname}]

@table @strong
@item Arguments

@var{hostname} is the host (and optionally port) of the monotone server
process to connect to. If not given, the default server is used.

@item Added in

12.0

@item Purpose

Permit @code{automate} commands to be run against a database that is
being used to serve netsync connections.

@item Input/Output format

This command takes input and produces output in exactly the
same format as @code{automate stdio}. Note that the commands run with
@code{automate remote_stdio} may conform to a different @var{interface_version},
because they are handled by a remote instance of monotone.

There will be some extra chatter on stderr unless @option{--quiet} is given.

@item Error Conditions

If left idle for too long or there are network problems, the connection to the
server may be dropped. This will not be detected while monotone is waiting for
input. Instead, when a complete command has been entered and monotone tries to
send it to the remote server it will print a message to stderr and exit with
code 1.

@item Notes

On the server side the @code{get_remote_automate_permitted} hook has to be
configured to include every command which should be executable over this
interface.

For both, the client and the server, keyboard interaction is disabled,
just as if @option{--non-interactive} is specified. Actions which require
operations on password-encrypted private keys will therefor fail unless the
@code{get_passphrase} hook is set up locally and / or remotely.

@end table

@item mtn automate remote @option{--remote-stdio-host=host} @var{command} @var{args-and-opts}

@table @strong
@item Arguments

A command and its arguments, to execute on the remote server specified
by the @option{--remote-stdio-host} option. If no host is given, the default
server is used. If options are to be passed to the command, they must be
preceded by @option{--} to prevent them from being interpreted as local options.

Remote options @strong{must} be given as a single token, ie
@option{--branch=foo} or @option{-bfoo}. This is because the local and remote
monotones may not understand exactly the same options (so the local monotone
cannot know if an option given as @option{--branch} or @option{-b} should be
followed by an argument), and because the server sees this as an
@code{automate remote_stdio} connection (so it expects the options to already
be parsed).

@item Added in

12.0

@item Purpose

Permit a single @code{automate} command to be run against a database that is
being used to serve netsync connections, without having its input and output
encoded as by @code{automate stdio}.

@item Input/Output Format

This command does not accept input.

The output will be whatever output the remote command generates.

Remote diagnostic messages are written to standard error, prefixed either
with @code{mtn: remote error:}, @code{mtn: remote warning:} or
@code{mtn: remote message:} to make them distinguishable from local
diagnostics. Tickers are not supported over this interface. If you need
remote ticker support, please use @command{automate remote_stdio}.

@item Error Conditions

If the remote command returns a nonzero error code, will exit with code 1 and
print "received remote error code N" to standard error, with "N" being
the remote error code.

@item Notes

On the server side the @code{get_remote_automate_permitted} hook has to be
configured to include every command which should be executable over this
interface.

Keyboard interaction is disabled on the server, just as if
@option{--non-interactive} would have been specified on server startup.
Actions which require operations on password-encrypted private keys will
therefor fail unless a @code{get_passphrase} hook is set up remotely.

@end table


@item mtn automate pull [--set-default] [@var{uri-or-address}] [@var{glob} [...] [--exclude=@var{exclude-glob}]]]
@itemx mtn automate push [--set-default] [--keys-to-push=@var{key}] [@var{uri-or-address}] [@var{glob} [...] [--exclude=@var{exclude-glob}]]]
@itemx mtn automate sync [--set-default] [--keys-to-push=@var{key}] [@var{uri-or-address}] [@var{glob} [...] [--exclude=@var{exclude-glob}]]]

@table @strong
@item Arguments:

The automate versions of pull, push and sync have the same set of arguments and
options compared to the non-automate versions. Please check this manual in the
appropriate section for a full explanation.

@item Added in:

12.0

@item Purpose:

Pushes, pulls or syncs (push & pull) revisions, certificates and keys of
the given database to, from or with the given netsync server.

@item Sample output (stdio):

The following output shows an example of a pull which transferred two revisions
and eight certs.

@emph{Note:} The linebreaks are not part of the actual format, but have been
added for better readability.

@verbatim
0:p:62:doing anonymous pull; use -kKEYNAME if you need authentication
0:p:25:connecting to monotone.ca0:0:p:29:finding items to synchronize:
0:t:34:c:certificates;k:keys;r:revisions;
0:t:12:c=0;k=0;r=0;
0:t:13:c#0;k#0;r#64;
0:t:14:c#0;k#0;r#128;
[...]
0:t:6:c;k;r;
0:t:44:>:bytes in;<:bytes out;c:certs in;r:revs in;
0:t:16:>=0;<=0;c=0;r=0;
0:t:21:>#420;<#1344;c#0;r#0;
0:t:22:>#1165;<#1741;c#0;r#0;
[...]
0:t:24:>#20839;<#14882;c#0;r#1;
0:t:24:>#20839;<#14882;c#3;r#1;
0:t:24:>#20839;<#14882;c#4;r#2;
0:t:24:>#20839;<#14882;c#6;r#2;
0:t:24:>#20863;<#14930;c#8;r#2;
0:t:8:<;>;c;r;
0:p:36:successful exchange with monotone.ca
0:l:1:0
@end verbatim

@item Output format:

If ran outside of @command{automate stdio}, the output of these commands is
equal to the normal netsync command output.

If these commands are run over stdio, the stdio ticker format is used
(for a description of this format, check @command{automate stdio}).

The following ticker types are printed out during the refinement phase:

@itemize
@item @code{c}: The number of certs found for an upcoming synchronization
@item @code{k}: The number of keys found for an upcoming synchronization
@item @code{r}: The number of revisions found for an upcoming synchronization
@end itemize

After refinement the actual synchronization between the two nodes start. The
ticker stanzas in this phase are the following:

@itemize
@item @code{>}: The number of incoming bytes
@item @code{<}: The number of outgoing bytes
@item @code{c}: The number of incoming certs  (only pull and sync)
@item @code{C}: The number of outgoing certs  (only push and sync)
@item @code{r}: The number of incoming revisions  (only pull and sync)
@item @code{R}: The number of outgoing revisions  (only push and sync)
@end itemize

@item Error conditions:

If a netsync error occurs, the command outputs an error and exits with status 1.

@end table


@item mtn automate genkey @var{name} @var{passphrase}

@table @strong
@item Aguments

@var{name} is the name to associate with the new key, and @var{passphrase} is
the passphrase that will be used to encrypt the private half.

@item Changes:
@itemize
@item
10.0 -- The separate hashes for the private half of a key really didn't
make much sense; have one @code{hash [...]} line instead of separate
@code{public_hash [...]} and @code{private_hash [...]} lines.
@item
3.1 -- initial
@end itemize

@item Purpose:

Generate a key with the given name and passphrase.

@item Sample output:

@verbatim
            name "tbrownaw@gmail.com"
            hash [475055ec71ad48f5dfaf875b0fea597b5cbbee64]
 public_location "database" "keystore"
private_location "keystore"

@end verbatim

@item Output format:

A basic_io stanza. 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.

@item Error conditions:

Error conditions: If the passphrase is empty or the key already exists,
prints an error message to stderr and exits with status 1.

@end table

@item mtn automate get_revision @var{id}

@table @strong
@item Arguments:

The argument @var{id} specifies the revision id for which the changeset
information should be printed.

@item Changes:

@itemize
@item
7.0 -- @var{id} is now mandatory
@item
1.0 -- initial
@end itemize

@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_current_revision [--exclude @var{excl}] [--depth=@var{depth}] [@var{path} ...]

@table @strong
@item Arguments:

One or more @var{path} arguments restrict the revision to these paths,
otherwise all changes in workspace are taken into account.

Options @var{excl} and @var{depth} work just like in @var{mtn commit}.

@item Added in:

7.0

@item Purpose:

Prints change information for the current workspace, optionally restricted by
one or more paths.

@item Sample output:

See @var{automate get_revision}

@item Output format:

See @var{automate get_revision}

@item Error conditions:

If the command is executed outside of a workspace, or the restriction is
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 get_attributes @var{path}

@table @strong
@item Arguments:

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

@item Added in:

@itemize
@item
11.0 -- removed the @command{format_version} stanza
@item
5.0 -- renamed from @command{attributes} to @command{get_attributes}
@item
3.0 -- initial
@end itemize

@item Purpose:

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

@item Sample output:

@verbatim
 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
'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 path specified is unknown in the new workspace revision, prints an error
message to stderr and exits with status 1.

@end table

@item mtn automate set_attribute @var{path} @var{key} @var{value}

@table @strong
@item Arguments:

A path, an attribute key and an attribute value.

@item Added in:

5.0

@item Purpose:

Edits the current workspace revision and inserts the given attribute key and
value for the specified path. Note that this change is not committed and
therefor behaves exactly like @command{mtn attr set @var{key} @var{value}}.

@item Output format:

This command does not print out anything if successful.

@item Error conditions:

If the path specified is unknown in the new workspace revision, prints an error
message to stderr and exits with status 1.

@end table

@item mtn automate drop_attribute @var{path} [@var{key}]

@table @strong
@item Arguments:

A path and an attribute key (optional).

@item Added in:

5.0

@item Purpose:

Removes an attribute from the current workspace revision for the specified path.
If no attribute key is given, all attributes of this path are removed. Note that
this change is not committed and therefor behaves exactly like
@command{mtn attr drop @var{path} [@var{key}]}.

@item Output format:

This command does not print out anything if successful.

@item Error conditions:

If the path specified is unknown in the new workspace revision or the attribute
key is not found for this path, prints an error message to stderr and exits with
status 1.

@end table


@item mtn automate content_diff [--revision=@var{id1} [--revision=@var{id2}]] [--reverse] [@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 from the parent (base) revision of this
workspace to the workspace revision.
@item
one revision: the diff is done from the given revision @option{id1} to
the workspace revision. If @option{--reverse} is given, the order is
reversed.
@item
two revisions: the diff is done from @option{id1} to @option{id2}; no
workspace is needed in this case.
@end itemize

@item Changes:

@itemize
@item
9.0 -- added @option{--with-header} option
@item
4.0 -- initial
@end itemize

@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 quiet on renames or drops by default, as the
header of @command{mtn diff} is omitted unless @option{--with-header} is given
and is omitted regardless if there are no changes.

@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 file_merge @var{left-rid} @var{left-path} @var{right-rid} @var{right-path}

@table @strong
@item Arguments:

@var{left-rid}, @var{left-fid}, @var{right-rid}, @var{right-fid}
specify two files to merge, by revision and file path.

@item Added in:

9.0

@item Purpose:

Prints the result of the internal line merge on the contents of the
specified files.

This command does not just take two file ids, because the revision ids
and paths are needed to check for manual merge and file encoding
attributes.

@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 merge results are output without modification.

@item Error conditions:

If either file id is unknown or invalid, or if the internal line
merger fails, 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 Changes:

@itemize
@item
11.0 -- Instead of having a "name" item, there are
"given_name" and "local_name" items.
@item
10.0 -- The separate hashes for the private half of a key really didn't
make much sense; have one @code{hash [...]} line instead of separate
@code{public_hash [...]} and @code{private_hash [...]} lines.
@item
1.1 -- initial

@end itemize

@item Purpose:

Print all keys in basic_io format.

@item Sample output:

@verbatim
            hash [475055ec71ad48f5dfaf875b0fea597b5cbbee64]
      given_name "tbrownaw@gmail.com"
      local_name "tbrownaw@gmail.com"
 public_location "database" "keystore"
private_location "keystore"

           hash [3ac4afcd86af28413b0a23b7d22b9401e15027fc]
      given_name "tomfa@debian.org"
      local_name "tomfa@debian.org"
public_location "database"

            hash [115fdc73d87a5e9901d018462b21a1f53eca33a1]
      given_name "underwater@fishtank.net"
      local_name "underwater@fishtank.net"
 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. given_name is the name provided when the key was created,
and local_name is the name returned by the @code{get_local_key_name} hook.

The keys are ordered by hash value.

@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:

4.0

@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:

@itemize
@item
No content mark is returned if @var{file} is a directory.
@item
One content mark is returned if @var{file} is a file and has recently been
changed exclusively in one revision (be it by a commit or merge).
@item
Multiple content marks are returned if @var{file} is a file and has recently
been part of a clean merge case.
A clean merge happens when the same change to @var{file} is made on both sides
of the particular merge, together with other unrelated changes, which make the
resulting revisions not collapse into one revision.
@end itemize

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:

4.0

@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 get_db_variables [@var{domain}]

@table @strong
@item Arguments:

The optional @var{domain} restricts the output to variables only within
this domain.

@item Changes:

@itemize
@item
7.0 -- converted output to basic_io, renamed to 'get_db_variables'
@item
4.1 -- added as 'db_get'
@end itemize

@item Purpose:

Reads and outputs database variables. For more information about variables,
see @ref{Vars}.

@item Sample output:

@verbatim
domain "database"
 entry "default-exclude-pattern" ""
 entry "default-include-pattern" "net.venge.monotone*"
 entry "default-server" "monotone.ca"

domain "known-servers"
 entry "monotone.ca" "3e6f5225bc2fffacbc20c9de37ff2dae1e20892e"
 entry "monotone.mtn-host.prjek.net" "a52f85615cb2445989f525bf17a603250381a751"
 entry "venge.net" "70a0f283898a18815a83df37c902e5f1492e9aa2"
@end verbatim

@item Output format:

basic_io-formatted stanzas. Each stanza starts with a 'domain', followed by one
or more 'entry' lines. Each 'entry' contains the @var{name} and the @var{value}
of the respective database variable.

@item Error conditions:

If the domain is unknown or no variables where found, prints an error message
to stderr and exits with status 1.

@end table

@item mtn automate set_db_variable @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 Changes:

@itemize
@item
7.0 -- renamed to 'set_db_variable'
@item
4.1 -- added as 'db_set'
@end itemize

@item Purpose:

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

@item Sample usage:

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

@item Output format:

No output.

@item Error conditions:

None.

@end table

@item mtn automate drop_db_variables @var{domain} [@var{name}]

@table @strong
@item Arguments:

The @var{domain} and @var{name} specify the database variable
which should be dropped. If @var{name} is ommitted, all database
variables in the @var{domain} are dropped.

@item Added in:

7.0

@item Purpose:

Drops one or more database variables, see also @ref{Vars}.

@item Sample usage:

@verbatim
mtn automate drop_db_variables known-servers
@end verbatim

@item Output format:

No output.

@item Error conditions:

If the specific variable or any variables in the given domain are not found,
prints to stderr and exits with status 1.

@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

@item mtn automate show_conflicts [@var{--branch BRANCH}] [@var{left_rev right_rev}]

@table @strong
@item Arguments:

Optional left and right revision ids.

If no revs are given, they default to the first two heads that would
be chosen by the @command{merge} command for the current branch. If no
workspace is present, the branch may be given by the @var{--branch}
option.

@item Changes:

@itemize
@item
11.0 -- Add resolution for orphaned node conflicts. Deleted
@code{resolved_user} conflict resolution; use @code{resolved_*_left}
for single file conflicts. Add @code{resolved_keep_left,
resolved_keep_right} resolutions.
@item
9.0 -- Added default resolution for file content conflicts, user
resolutions for others. @code{directory_loop_created} changed to @code{directory_loop}.
@item
8.0 -- initial
@end itemize

@item Purpose:

Show all conflicts between two revisions.

This is intended to be used before a @command{merge}; an external tool
can guide the user thru resolving each conflict in turn, then do the
merge.

The same file format is output by the @command{conflicts store}
command, which also allows specifying user conflict resolutions. The
file syntax for the resolutions is given here, so an external tool can
set them directly.

For more information on conflicts, @ref{Merge Conflicts}.

Note that this cannot be used to show conflicts that would occur in an
@command{update}, since in that case one revision is the workspace.

@item Sample output:

The output starts by listing the revisions and their common ancestor:
@verbatim
    left [532ab5011ea9e64aa212d4ea52363b1b8133d5ba]
   right [b94a03a922c2c281a88d8988db64e76a32edb6a1]
ancestor [ead03530f5fefe50c9010157c42c0ebe18086559]
@end verbatim

If there are no conflicts, the ancestor revision is not output, and no
conflict stanzas are output.

Attribute changed in both branches, or dropped in one:
@verbatim
        conflict attribute
       node_type "file"
       attr_name "attr1"
   ancestor_name "foo"
ancestor_file_id [bab2022ff2ed13501a8a83bcc6bd53f5042141be]
       left_name "foo"
    left_file_id [bab2022ff2ed13501a8a83bcc6bd53f5042141be]
 left_attr_value "valueX"
      right_name "foo"
   right_file_id [bab2022ff2ed13501a8a83bcc6bd53f5042141be]
right_attr_value "valueZ"

        conflict attribute
       node_type "file"
       attr_name "attr2"
   ancestor_name "foo"
ancestor_file_id [bab2022ff2ed13501a8a83bcc6bd53f5042141be]
       left_name "foo"
    left_file_id [bab2022ff2ed13501a8a83bcc6bd53f5042141be]
 left_attr_value "valueY"
      right_name "foo"
   right_file_id [bab2022ff2ed13501a8a83bcc6bd53f5042141be]
right_attr_state "dropped"
@end verbatim

Missing root directory:
@verbatim
     conflict missing_root
    left_type "pivoted root"
ancestor_name "foo"
   right_type "deleted directory"
ancestor_name "foo"
@end verbatim

Directory deleted and/or renamed:
@verbatim
     conflict orphaned_directory
   right_type "deleted directory"
ancestor_name ""
    left_type "renamed directory"
ancestor_name ""
    left_name "bar"

     conflict orphaned_file
   right_type "deleted directory"
ancestor_name "foo"
    left_type "added file"
    left_name "foo/baz"
 left_file_id [f5122a7f896cb2dd7ecaa84be89c94ab09c15101]

        conflict orphaned_file
      right_type "deleted directory"
   ancestor_name "foo"
       left_type "renamed file"
   ancestor_name "bar"
ancestor_file_id [ac4c6d06436632e017bb7d3ea241734e8899f8ce]
       left_name "foo/baz"
    left_file_id [ac4c6d06436632e017bb7d3ea241734e8899f8ce]

     conflict multiple_names
    left_type "renamed directory"
ancestor_name ""
    left_name "aaa"
   right_type "renamed directory"
ancestor_name ""
   right_name "bbb"

     conflict duplicate_name
    left_type "renamed directory"
ancestor_name "foo"
    left_name ""
   right_type "renamed directory"
ancestor_name "bar"
   right_name ""

     conflict multiple_names
    left_type "renamed directory"
ancestor_name "foo"
    left_name "a/foo"
   right_type "renamed directory"
ancestor_name "foo"
   right_name "b/foo"
@end verbatim

Directory loop created:
@verbatim
     conflict directory_loop
    left_type "renamed directory"
ancestor_name "foo"
    left_name "bar/foo"
   right_type "renamed directory"
ancestor_name "bar"
   right_name "foo/bar"
@end verbatim

File content changed (this may be resolvable by the internal line
merger), file also renamed:
@verbatim
         conflict content
        node_type "file"
    ancestor_name "bar"
 ancestor_file_id [f0ef49fe92167fe2a086588019ffcff7ea561786]
        left_name "bar"
     left_file_id [08cd878106a93ce2ef036a32499c1432adb3ee0d]
       right_name "bar"
    right_file_id [0cf419dd93d38b2daaaf1f5e0f3ec647745b9690]
resolved_internal

        conflict content
       node_type "file"
   ancestor_name "foo"
ancestor_file_id [50bf338804db2685a575124c8c8371d06b65c523]
       left_name "bar"
    left_file_id [f1bb6fff2ad16d67143d89fc374ede7abec5d437]
      right_name "baz"
   right_file_id [b966b2d35b99e456cb0c55e4573ef0b1b155b4a9]
@end verbatim
@code{resolved_internal} is a conflict resolution. If the file
contents in the two revs can be successfully merged by the internal
line merger, @code{resolved_internal} is output.

File added and/or renamed:
@verbatim
     conflict duplicate_name
    left_type "added file"
    left_name "bar"
 left_file_id [ba4637112ee3e55a6106d647d6c4e04a6643f8eb]
   right_type "added file"
   right_name "bar"
right_file_id [fe6d523f607e2f2fc0f0defad3bda0351a95a337]

        conflict duplicate_name
       left_type "renamed file"
   ancestor_name "foo"
ancestor_file_id [c6864a8456855c48afe83488a47501fe8b94bd57]
       left_name "bar"
    left_file_id [c6864a8456855c48afe83488a47501fe8b94bd57]
      right_type "added file"
      right_name "bar"
   right_file_id [c809d71002ec57a2f1d10221f05993012a491436]

        conflict duplicate_name
       left_type "renamed file"
   ancestor_name "foo"
ancestor_file_id [918f3642b57a5e2dd13ee874e3dc2518a53ab4b4]
       left_name "abc"
    left_file_id [918f3642b57a5e2dd13ee874e3dc2518a53ab4b4]
      right_type "renamed file"
   ancestor_name "bar"
ancestor_file_id [bdf46a521d5f1dd54c31dda15e99ff6b0c80394a]
      right_name "abc"
   right_file_id [bdf46a521d5f1dd54c31dda15e99ff6b0c80394a]
@end verbatim

File renamed to different names:
@verbatim
        conflict multiple_names
       left_type "renamed file"
   ancestor_name "foo"
ancestor_file_id [e80910e54d0bdea1b6d295ada320b87aaf9fdc23]
       left_name "bar"
    left_file_id [e80910e54d0bdea1b6d295ada320b87aaf9fdc23]
      right_type "renamed file"
   ancestor_name "foo"
ancestor_file_id [e80910e54d0bdea1b6d295ada320b87aaf9fdc23]
      right_name "baz"
   right_file_id [e80910e54d0bdea1b6d295ada320b87aaf9fdc23]
@end verbatim

Invalid file name (@file{_MTN} in root directory):
@verbatim
     conflict invalid_name
    left_type "pivoted root"
ancestor_name "foo"
   right_type "added directory"
   right_name "foo/_MTN"

        conflict invalid_name
       left_type "pivoted root"
   ancestor_name "foo"
      right_type "renamed file"
   ancestor_name "bad/_MTN"
ancestor_file_id [629d9e5d254241abf4b46f108fb53189e314e41d]
      right_name "foo/_MTN"
   right_file_id [629d9e5d254241abf4b46f108fb53189e314e41d]
@end verbatim

Revisions that don't share a common ancestor:
@verbatim
    left [161e426c3b0c3f98d0be225f69d6f893ce8e0442]
   right [0e3260f51acd1e98c40666557eb6c0eefeae5f02]
ancestor []

conflict missing_root

  conflict duplicate_name
 left_type "added directory"
 left_name ""
right_type "added directory"
right_name ""
@end verbatim

All possible conflict resolutions:
@verbatim
   resolved_drop_left
  resolved_drop_right
   resolved_keep_left
  resolved_keep_right
    resolved_internal
 resolved_rename_left file
resolved_rename_right file
   resolved_user_left file
  resolved_user_right file
@end verbatim
For single file conflicts, the @code{resolved_*_left} resolution name is used.

@xref{Conflicts}, for more information on conflict resolutions.

@item Output format:

First the revision ids of the left and right revisions, and their
common ancestor, are printed in one basic_io stanza.

Then each conflict is listed in a basic_io stanza. Stanzas are
separated by blank lines.

Each conflict stanza starts with a @code{conflict} line, and contains
up to eleven lines. The order of the lines is not important, and may
change in future revisions, except that the first line will always be
@code{conflict}.

When the conflicts involve files, the file ids are output, so the file
contents can be retrieved efficiently via @code{automate get_file},
to aid in conflict resolution.

Only the @command{resolved_internal} conflict resolution is output by
this command; the other conflict resolutions are inserted in a
conflicts file by @command{conflicts resolve_first} or an external
tool, and read by @command{merge}.

@item Error conditions:

If the revision IDs are given, but either is unknown or
invalid, prints an error message to stderr and exits with status 1.

@end table

@item mtn automate get_workspace_root

@table @strong
@item Arguments:

None.

@item Added in:

8.0

@item Purpose:

To show the path of the workspace root for the current directory.

@item Sample output:

@verbatim
/home/jim/juice
@end verbatim

@item Output format:

A path.

@item Error conditions:

If the current directory isn't part of a workspace, prints an error to
stderr and exits with status 1.

@end table

@item mtn automate update

@table @strong
@item Arguments:

Same as @command{mtn update}; no arguments, options
@var{--move-conflicting-paths}, @var{--revision=revision}

@item Added in:

12.1

@item Purpose:

Update the current workspace to the latest or given revision; see
@command{update} in @ref{Workspace}.

@item Sample output:

Nothing on stdout. stderr gives progress messages of the form:
@verbatim
mtn: updating along branch 'mms.work_stephe'
mtn: selected update target 233afb8c4832bf33d5f5734225164de5f5a6278c
mtn: [left]  4a368a6b217c40b2ff3b12bb7cfa00987e0f191c
mtn: [right] 233afb8c4832bf33d5f5734225164de5f5a6278c
mtn: renaming build/windows_common.make to build/utf_common.make
mtn: adding build/x86_gnu_linux_release
@end verbatim

These messages are in the 'p' stream in automate stdio.

@item Output format:

Free form, prefixed by ``mtn:''.

@item Error conditions:

see @command{update} in @ref{Workspace}.

@end table

@item mtn automate read_packets @var{packet-data}

@table @strong
@item Arguments:

A data packet, @var{packet-data}, as produced by @command{mtn pubkey @var{keyname}}.

@item Added in:

9.0

@item Purpose:

Store public keys (and incidentally anything else that can be represented as
a packet) into the database.

@item Output format:

No output.

@item Error conditions:

An error will be produced if the argument is not a valid packet.

@end table

@item mtn automate lua @var{function_name} [@var{function_args...}]

@table @strong
@item Arguments:

A valid Lua function name and zero or more function arguments. Note that string
arguments need to be wrapped in another pair of quotes, i.e. @code{"foo"} or
@code{'foo'} will not work, but @code{"'foo'"} or @code{'"foo"'} will.

Complex types are also supported, anything which can be evaluated as valid
Lua expression can be given as input, including nested tables and functions,
like f.e. @code{@{1,true,@{['func'] = function(...) return ... end @}@}}

@item Added in:

9.0

@item Purpose:

Call Lua functions, like monotone hooks, in the monotone context, f.e. to
retrieve user defaults like keys, passwords, ignorable files and more.

@item Output format:

A string dump of the return value of the function, in Lua code. The Lua types
@code{function}, @code{thread}, @code{userdata} and @code{lightuserdata} are not
serialized, but set to @code{nil} in the dump.

Please note that @code{nil} values in tables are not printed since Lua does not
distinguish between unset and not existing entries in a table like other
programming languages do.

@item Sample output:

A single string return value:

@verbatim
[1] = "Output";
@end verbatim

Two numeric return values:

@verbatim
[1] = 3;
[2] = 4.4;
@end verbatim

A nested table:

@verbatim
[1] = {
    ["bar"] = {
        [1] = 1;
        [2] = 2;
        [3] = 3;
    };
};
@end verbatim

A callback function:

@verbatim
[1] = nil --[[function]];
@end verbatim

@item Error conditions:

This command prints an error message and exists with status 1 if the function
does not exist, one or more function arguments could not be evaluated or the
function could not be called for another reason.

@end table

@end ftable

@page
@node    RCS, GIT, Automation, Command Reference
@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


@page
@node    GIT,  , RCS, Command Reference
@section GIT

@ftable @command
@item mtn git_export [--authors-file=@var{authors-file}] [--branches-file=@var{branches-file}]
@itemx mtn git_export [--import-marks=@var{marks-file}] [--export-marks=@var{marks-file}]
@itemx mtn git_export [--log-revids] [--log-certs] [--use-one-changelog]
@itemx mtn git_export [--refs=@var{type}]

This command exports all revisions from the current monotone database
to @code{stdout} in a format that can be piped directly to git
fast-import.

The @option{--authors-file} option may be used to map monotone author
and committer names to different values in a manner similar to that
documented in git-svn(1). Mappings are specified in the
@var{authors-file} as:
@verbatim
loginname = Joe User <user@example.com>
@end verbatim

The list of authors that might need to be mapped can be extracted from
a monotone database with the following sql query:

@verbatim
$ mtn db execute 'select distinct value from revision_certs where name = "author"'
@end verbatim

The list of committers that might need to be mapped can be extracted
from a monotone database with the following sql query:

@verbatim
$ mtn db execute 'select distinct public_keys.name
                  from public_keys
                  left join revision_certs on revision_certs.keypair_id = public_keys.id
                  where revision_certs.name = "author"'
@end verbatim

The @option{--branches-file} option may be used to map monotone branch
names to different values. This may be required as monotone allows
branch names that are not valid according to git. Branch mappings are
specified in the @var{branches-file} as:

@verbatim
monotone-branch-name = git-branch-name
@end verbatim

Revisions with no author cert will use "Unknown <unknown>" for both
the author and the committer. These can be mapped to other values
using the @var{authors-file} option.

The list of branches that might need to be mapped can be extracted
from a monotone database with using the @command{ls branches} command:

@verbatim
$ mtn ls branches --ignore-suspend-certs
@end verbatim

The @option{--import-marks} and @option{--export-marks} options are
similar to those documented in git-fast-export(1) and
git-fast-import(1). These may be used for incremental exports and may
also be useful for repository verification. The @var{marks-file} is
read on startup if @option{--import-marks} is specified and all marked
revs are excluded from the export. The @var{marks-file} is written on
completion if @option{--export-marks} is specified and will contain
marks for all revs that were exported in addition to any marks that
were read on startup. It is safe to use the same file for both
@option{--import-marks} and @option{--export-marks} but different
files may also be used.

The original monotone revision ids may be included in the exported git
commit messages using the @option{--log-revids} option. These will
appear as:

@verbatim
Monotone-Parent: ...
Monotone-Revision: ...
@end verbatim

in the git commit messages and may be useful for repository
verification. Merge revisions with two parents will include two
@code{Monotone-Parent} lines.

The original monotone values for @code{author}, @code{date},
@code{branch} and @code{tag} certificates may be included in the
exported git commit messages using the @option{--log-certs}
option. These will appear as:

@verbatim
Monotone-Author: ...
Monotone-Date: ...
Monotone-Branch: ...
Monotone-Tag: ...
@end verbatim

in the git commit messages and may be useful for repository
verification or maintaining information that is otherwise not
maintained by git. In particular monotone may have several values for
each of these certs and git only represents a single @code{author} and
@code{date} value.

By default, the values of all changelog and comment certs on a
revision are concatenated to form the git commit message for that
revision. The @option{--use-one-changelog} option will prevent this
behaviour and use the value from the first changelog cert
encountered. @emph{WARNING:} this will explicitly lose information in
the exported data. Changelog certs have no implicit ordering, one will
be selected arbitrarily to be used as the git commit message and all
others will be excluded from the exported data. Additionally, all
comment certs will be excluded from the exported data.

References to the original monotone branches and tags are exported as
@code{refs/tags/<tag-name>} and @code{refs/heads/<branch-name>}. In
addition, references to the original monotone revision ids, the root
revisions and the leaf revisions may be exported using
@option{--refs=revs}, @option{--refs=roots} and @option{--refs=leaves}
respectively. These references are exported as
@code{refs/mtn/revs/<id>}, @code{refs/mtn/roots/<id>} and
@code{refs/mtn/leaves/<id>} and may be useful for repository
verification. These additional references should probably not be
maintained after the exported repository has been verified as they
cause considerable clutter in tools like gitk.

@end ftable


@node    Lua Reference, Special Topics, Command Reference, Top
@chapter Lua Reference

Monotone makes use of the @uref{http://www.lua.org, Lua} programming
language to customize and extend its behaviour.  By writing
@dfn{functions} which are loaded and evaluated at runtime, you can
help monotone to make a particular decision, set a suitable default or
preference or perform a certain action.

You can put Lua 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 other predefined
locations.  By specifying @option{--rcfile=@var{directory}} you can
automatically load all the files contained in @var{directory}.

There are two uses for Lua functions; hooks and user-defined
commands. This section documents hooks; see @command{register_command}
in @ref{Additional Lua Functions} for user-defined commands. The source
distribution contains some example user commands in the
@file{contrib/command} directory.

Hooks are Lua functions that are called from monotone code in many
places. Monotone provides default definitions for some hooks; see
@ref{Default hooks} for their complete source. For other hooks, if no
definition is provided a default return value is used. 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 provides a number of helper functions to hook writers
exposing functionality not available with standard Lua.

@menu
* Hooks::                       All hooks called by monotone.
* Additional Lua Functions::    Extra functionality available to hook writers.
* Implementation Differences::  Functional differences from standard Lua
@end menu

@page
@node   Hooks, Additional Lua Functions, Lua Reference, Lua Reference
@section Hooks

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

@subsection Common Data Types

Some hooks take arguments which are more complex than a simple string or number.
Where multiple hooks take the same kind of argument, we generally try to make
them take that kind of argument in the same format.

@ftable @code
@item key_identity

When a key is created, it is given a meaningful name. Because this is chosen by
the key creator and may be unreliable, trust hooks need to be able to look at
the key hash as well. This may be inconvenient, so a local alias is also provided.
This alias is obtained from an other hook, which can provide reliable easy-to-use
names based on the key hash (or however else you want).

@smallexample
@group
@{
   id = "key hash/fingerprint, in hex",
   given_name = "name given when creating the key",
   name = "local alias of the key"
@}
@end group
@end smallexample

@end ftable

@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_key}, @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_key}

The identity of the key being used by the other end of the connection. The fields may
be empty 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 identity of 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_revision_sent (@var{rev_id}, @var{revision}, @var{certs}, @var{session_id})

Called by monotone after the revision @var{rev_id} is sent through
netsync. The arguments are the same as for
@var{note_netsync_revision_received}.

@item note_netsync_cert_received (@var{rev_id}, @var{key_identity}, @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_identity} 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_cert_sent (@var{rev_id}, @var{key_identity}, @var{name}, @var{value}, @var{session_id})

Called by monotone after a cert is sent through netsync, if the revision
that the cert is attached to was not also sent in the same netsync
operation. The arguments are the same as for
@var{note_netsync_cert_received}.

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

Called by monotone after a pubkey is received through netsync. @var{key_identity}
is the identity 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_pubkey_sent (@var{key_identity}, @var{session_id})

Called by monotone after a pubkey is sent through netsync. The arguments are the same as for
@var{note_netsync_pubkey_received}.

@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 as in this example:

@smallexample
@group
function note_mtn_startup(...)
    print("Beginning note_mtn_startup")
    for i = 1,arg.n do
        print(arg[i])
    end
    print("Ending note_mtn_startup")
end
@end group
@end smallexample

@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 or hash 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_netsync_key(@var{server}, @var{include}, @var{exclude})

Returns a string which is the name or hash of the key to use to authenticate
the given netsync connection. When called by the @command{serve} command,
@var{server} is the address monotone is listening on, @var{include} is
@option{"*"}, and @var{exclude} is @option{""}.

There is no default definition of this hook. The command-line option
@option{--key=@var{keyname}} overrides any value returned from this
hook function.

@item get_default_command_options(@var{command})

Returns a table of program options, either valid for the given command or
valid global options. The @var{command} argument is given as a table of command
parts, i.e. for commands with subcommands like @command{automate} or @command{db}
this argument contains at least two elements.

Note that there is no way to "override" these default options via a given
command-line option once they've been set. This is especially true if you
specify options with arguments in this hook such as
@option{--exclude=@var{path}} - no subsequent command-line argument or
@option{--exclude} option argument will be able to replace or remove the
already excluded @var{path}.

Simple example which enables recursive directory scanning for @command{mtn add}
by default:
@smallexample
@group
function get_default_command_options(command)
    local default_options = @{@}
    if (command[1] == "add") then
        table.insert(default_options, "--recursive")
    end
    return default_options
end
@end group
@end smallexample

@item get_passphrase (@var{key_identity})

Returns a string which is the passphrase used to encrypt the private
half of @var{key_identity} in your key store, using the @sc{TripleDES} symmetric
cipher.  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_local_key_name (@var{key_identity})

Return the local alias for the given key. The @var{id} and @var{given_name}
fields of @var{key_identity} will be populated, and the @var{name} field
will not be. The return value indicates what the @var{name} field should
contain. The default implementation make this the same as @var{given_name}.

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

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{key_identity}.  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, key_identity)
        -- 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, key_identity)
        -- Branch name ignored.
        if (key_identity.given_name == "joe@@example.com") then
                return "Joe Random <joe@@example.com>"
        end
        return key_identity
end
@end group
@end smallexample

@item get_default_database_locations ()

Returns a table of paths where monotone should look for managable
databases.  The command @command{list databases} searches all these
paths for valid monotone databases and outputs details on each one.

The default implementation returns a table with a single entry,
@file{$HOME/.monotone/databases} on Unix and
@file{%APPDATA%\monotone\databases} on Windows.

@item get_default_database_alias ()

Returns the alias of the managed database which should be used as default
for commands like @command{clone} or @command{setup} if these are missing
an explicit database option.  This alias and the first path found in the
@code{get_default_database_locations} hook form the complete path
of this default database.

The default implementation returns @code{:default.mtn}.

@item edit_comment (@var{user_log_message})

Returns a log entry for a given set of changes, described in
@var{user_log_message}.  The user_log_message 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. Values for @code{author}, @code{date}, @code{branch}
and the @code{changelog} are extracted from the result and used to
generate these certificates when you commit changes.

The contents of @file{_MTN/log} are read and passed as as the
@code{changelog} value in @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.

@item get_date_format_spec (@var{wanted})

Returns a @code{strftime} format specification, which @command{mtn
log} and similar commands will use to format dates, unless instructed
otherwise.  The default definition returns @samp{%x} for long and short
date formats, @samp{%X} for long and short time formats and @samp{%x %X}
for long and short date time formats, which is equivalent to @samp{22/05/09},
@samp{09:06:14} and @samp{22/05/09 09:06:14} in an English locale.

@var{wanted} can be one of @samp{date_long}, @samp{date_short},
@samp{time_long}, @samp{time_short}, @samp{date_time_long} and
@samp{date_time_short}, though only @samp{date_short} and
@samp{date_time_short} are currently used.

The @samp{date_time_long} format is used by the @command{status},
@command{commit} and @command{log} commands to format revision dates
for printing. This format must preserve a date passed through a
formatting and parsing cycle. Otherwise the @command{status} command
will issue warnings that the format is unsuitable and the
@command{commit} command will abort.

@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{key_identity})

Returns @code{true} if a peer authenticated as key @var{key_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 "f3f62f86eba204a3ce15174083a53349201993d6"

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 with a hash or
local_name that matches 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{key_identity} of @code{nil}.

@item get_netsync_write_permitted (@var{key_identity})

Returns @code{true} if a peer authenticated as key @var{key_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 key hashes or local key names, 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{key_identity}
of @code{nil}.

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.

@item get_remote_automate_permitted(@var{key_identity}, @var{command}, @var{options})

Returns true if a peer authenticated as key @var{key_identity} should be
allowed to execute the given @var{command} with the given @var{options}, as
if through @code{automate stdio}.

@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 identities 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.name] = 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 unless @command{diff} is given the
@option{--no-show-encloser} option (or 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 the default for that language.  @xref{Regexps}, for the
regular expression syntax.

@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 in
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 an attribute value @var{value}. The function should ``apply'' the
attribute to the file, possibly in a platform-specific way.  When
called to set an attribute the value this hook receives will be a
string representing the value of the attribute. When called to clear
an attribute the value this hook receives will be @code{nil}.

Hook functions from this table are called for each existing attribute,
after any command which modifies the workspace. These functions are
also called during creation and modification of a workspace by the
@command{update}, @command{merge_into_workspace}, @command{pluck},
@command{clone} and @command{checkout} commands to set or clear
attributes as they change.

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
         set_executable(filename)
      else
         clear_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 GIT Export Hooks

Exporting monotone revisions in git-fast-import(1) format often
requires translation of monotone author cert values and associated
signing keys into corresponding git author and committer
values. Translation of author and committer values and validation of
the results is controlled by these hooks. See @ref{Default hooks}.

@ftable @code

@item unmapped_git_author(@var{author})

This hook is called for any git author or committer value that does
not come from the current @emph{author map} file. If no @emph{author
map} file is specified this hook will be called for @emph{every}
unique git author and committer value.  It may return the value
unchanged or modify it in some way in an effort to ensure that it is
valid. The default implementation attempts several common pattern
replacements to produce valid authors from monotone authors.

@item validate_git_author(@var{author})

This hook is called before the git author or committer value is
written to the export output stream. The @var{author} value is either
the mapped value from the current @emph{author map} file or the value
produced by the @code{unmapped_git_author} hook. This hook may return
true if the author is valid or false if it is not. The export will be
aborted if this hook returns false for any value.

@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

@subsection Meta Hooks

Monotone allows the execution of arbitrary Lua hooks and functions through a
special generalized "meta hook". See @command{automate lua} for more information.

@ftable @code
@item hook_wrapper (@var{func_name}, @var{...})

This hook is explicitely called on every execution of @command{automate lua}.
It takes a function name and zero or more string function arguments which are
internally evaluated into Lua code. It returns a dump of the return value of
the called function in Lua code on success.

@end ftable

@page
@node   Additional Lua Functions, Implementation Differences, Hooks, Lua Reference
@section Additional Lua Functions

This section documents the additional Lua functions made available to
hook writers.

@ftable @code

@item alias_command(@var{original}, @var{alias})

This function adds a new alias for a monotone command.  A call to this function would
normally be placed directly in the @file{monotonerc} file, rather than in a hook function.

@item change_workspace(@var{directory})

Change to workspace @var{directory}, which may be absolute or
relative to the directory that was current when mtn was started.

Throws an error if @var{directory} does not exist or is not a
workspace (does not contain @file{_MTN}).

After calling change_workspace, the next operation should read the
workspace options. @command{mtn_automate} does this; other Lua
extensions do not. In addition, @command{automate stio} reads the
workspace options before executing each command.

@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 in the directory scriptpath.

If one of the scripts has an error, the function 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 mtn_automate( ... )

The @code{mtn_automate} Lua function calls the Monotone
@command{automate} command passed in its arguments. The result of the
call is a pair consisting of a boolean return code, indicating whether
the call was successful or not, and a string being the @code{stdout}
output from the @command{automate} command. This function is not for use
in ordinary Lua hooks, but rather for Lua based commands as defined by
the Lua function @code{register_command}.

Note that keyboard interaction is disabled, just as if @option{--non-interactive}
is specified. Actions which require operations on password-encrypted private
keys will therefor fail unless the @code{get_passphrase} hook is set up locally.

@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", values = @{ 1 = "foo", 2 = "bar" @} @},
   2 = @{ name = "thingy", values = @{ 1 = "baz" @} @},
   3 = @{ name = "spork", values = @{ @} @},
   4 = @{ name = "frob", values = @{ 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.  @xref{Regexps}, for the syntax of @var{regexp}.

@item register_command(@var{name}, @var{params}, @var{abstract}, @var{description}, @var{function})

Add a command named @var{name} to the @var{user} command group in monotone.  This function is
normally called directly from a @file{monotonerc} file rather than a hook.  When the user issues the
registered command, monotone will call the lua @var{function} name supplied.  That function would
then normally use mtn_automate() calls to service the request.

@item server_request_sync(@var{what}, @var{address}, @var{include}, @var{exclude})

Initiate a netsync connection to the server at @var{address}, with the
given include and exclude patterns, of type @option{sync}, @option{push},
or @option{pull}, as given by the @var{what} argument.

When called by a monotone instance which is not running the @option{serve}
command, this function has no effect.

@item server_set_listening(@var{boolean})

If the argument is @var{false}, make the server not listen for incoming
connections, and exit when all existing connections have closed.

If the argument is @var{true}, cancel an earlier call with @var{false} given.

@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


@page
@node   Implementation Differences, ,Additional Lua Functions, Lua Reference
@section Implementation Differences

This section documents disabled and overwritten functions from the standard
Lua libraries.

@ftable @code

@item print, io.write

Both functions are overwritten to print to standard error (instead of
standard output), formatted as monotone progress message with the prefix
"lua:" in front of every line.

The rationale behind this is to catch most of the informational
messages from hooks which use these functions and present them via
monotone's user interface. This allows them to be logged just as other
progress messages, and prevents unexpected out-of-band output in the
@ref{Automation} interface.

If you explicitely need to write to either stdout or stderr, please use
@code{io.stdout:write} and @code{io.stderr.write}.

@item os.execute, io.popen

Both functions have been disabled for security reasons. You should use
their replacements @code{spawn} and @code{spawn_pipe}.

The original versions do not apply any kind of shell character escaping,
which might lead to serious problems f.e. when a merger is automatically
invoked by such a function.

@end ftable


@node    Special Topics, Default hooks, Lua Reference, Top
@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.
* Regexps::                     The syntax of regular expressions
                                  used by Monotone.
@end menu

@page
@node    Internationalization, Hash Integrity, Special Topics, Special Topics
@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, Rebuilding ancestry, Internationalization, Special Topics
@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, Mark-Merge, Hash Integrity, Special Topics
@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, Regexps, Rebuilding ancestry, Special Topics
@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    Regexps,  , Mark-Merge, Special Topics
@section Regular Expression Syntax

Monotone expects user-provided regular expressions in
@file{.mtn-ignore} files and as the result of the
@code{get_encloser_pattern} Lua hook (for the @command{diff} command).
User-written Lua hooks may also use the
function @code{regex.search} as they see fit.  All these regular
expressions should be written with the same syntax, which is that
expected by the Perl-Compatible Regular Expression library (PCRE).

@menu
* Regexp Summary::  Quick reference to regular expression syntax.
* Regexp Details::  Details of regular expression syntax and semantics.
@end menu

@include pcresyntax.texi
@include pcrepattern.texi

@node Default hooks, General Index, Special Topics, Top
@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,  , Default hooks, Top
@unnumbered General Index

@printindex cp

@bye
