@need 3200

@node Speeding up arch with Revision Tree Libraries
@chapter Speeding up arch with Revision Tree Libraries

@geindex revision library



For many purposes, it is useful to have a library containing pristine
trees of a large number of revisions -- for example, all of the
revisions in a particular version.  To be practical, though, such a
library must be represented in a space-efficient way.


Unix hard-links provide a natural way to store such a library.  Each
successive revision in a series is a copy of the previous, but with
unmodified files shared via hard-links.


@code{arch} provides commands to help you build, maintain, and browse such
a library.


As a pleasant side effect, many @code{arch} commands are speeded up if the
revisions they need to operate are present in your revision library.
You can read more about this in the next chapter.

@need 3200

@section Your Revision Library Location

@geindex my-revision-library



To begin a new revision library, first create a new directory (@code{DIR})
and then register its location:

@example
@group
        % larch my-revision-library DIR
@end group
@group
@end group
@end example

You can check the location of your library with:

@example
@group
        % larch my-revision-library
@end group
@group
@end group
@end example

@noindent
or unregister it with:

@example
@group
        % larch my-revision-library -d
@end group
@group
@end group
@end example



@need 3200

@section Revision Library Format

A revision library has subdirectories of the form:

@example
@group
        ARCHIVE-NAME/CATEGORY/BRANCH/VERSION/REVISION/
@end group
@group
@end group
@end example

Each @code{REVISION} directory contains the complete source of a particular
revision, along with some supplemantary subdirectories and files:

@example
@group

@end group
@group
        REVISION/,,patch-set/
@end group
@group

@end group
@group
                The patch set that creates this revision from
                its ancestor (unless the revision is a full-source
                base revision).
@end group
@group

@end group
@end example

Although the permissions on files in the revision library are
determined as determined by patch sets, @emph{@strong{you must never modify files
int the revision library}}.  Doing so will cause odd errors and
failures in various @code{arch} commands.




@need 3200

@section Adding a Revision to the Library

@geindex library-add



You can add a selected revision to your revision library with:

@example
@group
        % larch library-add REVISION
@end group
@group
@end group
@end example

That will add not only @code{REVISION} to the library, but all directly
preceeding revisions (recursively) which are either from the same
archive, or from other archives which are also in the same library.
("Directly preceeding" in this case means the previous patch level,
for ordinary revisions, or the tagged revision (for revisions which
are tags).)




@need 3200

@section Finding a Revision in the Library

@geindex library-find



You can find a particular revision in the library with @code{library-find}:

@example
@group
        % larch library-find REVISION
        PATH-TO-REVSION
@end group
@group
@end group
@end example

The output is an absolute path name to the library directory containing
the revision.  (Once again, you must not modify files in that
directory.)




@need 3200

@section Removing a Revision from the Library

@geindex library-remove



To remove a particular revision from the library, use:

@example
@group
        % larch library-remove REVISION
@end group
@group
@end group
@end example

Be aware of the following limitation in the current release:  suppose
that you add three successive revisions, @code{A}, @code{B}, and @code{C}.  Then you
remove @code{B}, then re-add @code{B}.  Now there is a chance that the file
sharing between @code{B} and @code{C} will be less than optimal, causing your
library to be larger than it needs to be.  (You can fix this by then
removing and re-adding @code{C}.)




@need 3200

@section Listing Library Contents

@geindex library-archives

@geindex library-categories

@geindex library-branches

@geindex library-versions

@geindex library-revisions



The command @code{library-archives} lists all archives with records in the library:

@example
@group
        % larch library-archives
        ARCHIVE-NAME
        ARCHIVE-NAME
        ...
@end group
@group
@end group
@end example

Similarly, you can list categories, branches, versions, or revisions:

@example
@group
        % larch library-categories [ARCHIVE]
        % larch library-branches [ARCHIVE/CATEGORY]
        % larch library-versions [ARCHIVE/BRANCH]
        % larch library-revisions [ARCHIVE/VERSION]
@end group
@group
@end group
@end example



@need 3200

@section Individual Files in the Revision Library

@geindex library-file

@geindex cat-library-file



You can locate an individual file in a revision library with:

@example
@group
        % archive library-file FILE [REVISION]
        PATH
@end group
@group
@end group
@end example

@noindent
or obtain its contents with:

@example
@group
        % archive cat-library-file FILE [REVISION]
        ...file contents...
@end group
@group
@end group
@end example

Both commands accept the options @code{--tag} and @code{--this}.  With @code{--tag},
the argument @code{FILE} is interpreted as an inventory tag, and the file
with that tag is found.


With @code{--this}, @code{FILE} is interpreted as a file relative to the current
directory, which should be part of a project tree.  The file's
inventory tag is computed and the corresponding file found in
@code{REVISION}.




@need 3200

@section Determining Patch Set Prerequisits

@geindex touched-file-prereqs


@example
@group
          % larch touched-files-prereqs REVISION
@end group
@group
@end group
@end example

That command looks at the patch set for @code{REVISION} and at all
preceding patch sets in the same version (it searches your library
rather than your repository for this purpose).  It reports the list of
patches that touch overlapping sets of files and directories -- in
other words, it tells you what patches can be applied independently of
others.  The command has an option to exclude from consideration file
names matching a certain pattern (e.g. @geindex =README
@dfn{=README} or @geindex ChangeLog
@dfn{ChangeLog}).  It
has an option to exclude from the output list patches which have
already been applied to a given project tree.  It has an option to
report the specific files which are overlapped.







