@need 3200

@node Retrieving Earlier Revisions
@chapter Retrieving Earlier Revisions

If you've followed along with the examples in earlier chapters, you
should have:


@strong{Your First Archive} which is also your default archive:

@example
@group
        % larch my-default-archive
        lord@@emf.net--2003-example
@end group
@group

@end group
@group
        % larch whereis-archive lord@@emf.net--2003-example
        /usr/lord/examples/@{archives@}/2003-example
@end group
@group

@end group
@end example

@strong{A hello-world Project in Your Archive}

@example
@group
        % larch categories 
        hello-world
@end group
@group

@end group
@group
        % larch branches hello-world
        hello-world--mainline
@end group
@group

@end group
@group
        % larch versions hello-world--mainline
        hello-world--mainline--0.1
@end group
@group

@end group
@end example

@strong{Two Revisions of the hello-world Project}

@example
@group
        % larch revisions hello-world--mainline--0.1
        base-0
        patch-1
@end group
@group
@end group
@end example

In this chapter, you'll learn how to retrieve revisions from your
archive.

@need 3200

@section Checking Out the Latest Revision

You might also have a left-over project tree.  If so, let's get rid of
that:

@example
@group
        % cd ~/wd
@end group
@group

@end group
@group
        % ls
        hello-world
@end group
@group

@end group
@group
        % rm -rf hello-world
@end group
@group

@end group
@end example

Let's suppose that you now want to get the latest sources for the 
hello world project.  For that, you want to use the @code{get} command:

@example
@group
        % larch get hello-world--mainline--0.1 hello-world
        [...]
@end group
@group


@end group
@group
        % ls 
        hello-world
@end group
@group

@end group
@group
        % ls hello-world
        hw.c    main.c  @{arch@}
@end group
@group

@end group
@end example



@need 3200

@section Checking Out An Earlier Revision

Let's suppose we want to check out an earlier version of the
@code{hello-world} project. 


Notice that in the previous example, we asked just for a particular
version of the project:

@example
@group
        % larch get hello-world--mainline--0.1 hello-world
                    ^^^^^^^^^^^  ^^^^^^^^  ^^^ ^^^^^^^^^^^
                         |           |      |       |
                         |           |      |  target directory
                         |           |      |
@end group
@group
                         |           |      |
@end group
@group
                         |           |   version number
                         |           |
                         |      branch name
                         |
                   category name
@end group
@group
@end group
@end example

We can get an earlier revision name by specifying it's @emph{@strong{patch level}} 
explicitly:

@example
@group
        % larch get hello-world--mainline--0.1--base-0 hello-world-0
                    ^^^^^^^^^^^  ^^^^^^^^  ^^^  ^^^^^^ ^^^^^^^^^^^^^
                         |           |      |      |        |
                         |           |      |      |  target directory
                         |           |      |      |
@end group
@group
                         |           |      | patch level name
                         |           |      |
@end group
@group
                         |           |   version number
                         |           |
                         |      branch name
                         |
                   category name
@end group
@group




@end group
@group
        % ls
        hello-world     hello-world-0
@end group
@group

@end group
@group
        % ls hello-world-0
        hw.c    main.c  @{arch@}
@end group
@group

@end group
@end example

You can see the changes made from @code{base-0} to @code{patch-1} with, for
example, @code{diff -r}:

@example
@group
        % diff -r hello-world-0 hello-world
        diff -r hello-world-0/hw.c hello-world/hw.c
        7c7
        <   (void)printf ("hello warld");
        ---
        >   (void)printf ("hello world\n");
        [...]
@end group
@group
@end group
@end example



@need 3200

@section How it Works -- Retrieving Revisions With get

Retrieving the @code{base-0} revision is easy.  As you should recall, the
@code{base-0} revision is stored as a compressed tar file of the complete
source tree (see @strong{How it Works -- What import Does} in @ref{Importing the First Revision}).  When 
asked to retrieve @code{base-0}, the @code{get} command essentially just unpacks
that tar file.


Retrieving the @code{patch-1} revision happens in two steps.  Recall that
@code{patch-1} is stored as a @emph{changeset} that describes the differences
between @code{base-0} and @code{patch-1} (see @strong{How it Works -- commit of a New Revision} in @ref{Checking-in Changes}).  Therefore, @code{get} works by first retrieving the
@code{base-0} revision, then retrieving the @code{patch-1} changeset, then using
that changeset to modify the @code{base-0} tree and turn it into a
@code{patch-1} tree.  Internally, @code{get} uses a larch command called
@code{dopatch} to apply a changeset, but if you are familiar with
@code{diff/patch} patchsets, then you can think of @code{dopatch} as "patch on
steroids".


Let's suppose that instead of committing just one change you'd
committed many changes:  not just a @code{patch-1} revision but @code{patch-2},
@code{patch-3} and so forth.  In essence, @code{get} will apply each changeset
in order to create the revision you requested.


@strong{Note:}  In fact, @code{get} is a bit more complicated than is described
here.  On the one hand, there are performance optimizations that can
spare @code{get} from having to apply a long list of changesets.  On the
other hand, there can be revisions created by @code{tag} rather than
@code{commit}, for which different rules apply.  You'll learn more about
these exceptions in later chapters.







