@need 3200

@node Elementary Branches -- Maintaining Private Changes
@chapter Elementary Branches -- Maintaining Private Changes

In this chapter, we'll begin to explore the concept of @geindex branching
@dfn{branching},
which you may be familiar with from other revision control systems.


If you are already familiar with the concept, you should be aware that
branching in @code{arch} almost certainly goes far beyond what you are
accustomed to.


Regardless of whether or not you are familiar with the concept, fear
not -- we'll be starting slow:

@need 3200

@section A Branching Scenario -- The Need for Private Changes

Let's suppose for the moment that the @code{hello-world} project is making
its sources available as a public, read-only mirror (see
@ref{Shared and Public Archives}).


Early on, you (someone not involved in the @code{hello-world} project)
decides that you'll want to use their program, but that you'll need to
make some local changes.


As a sort of toy example, let's suppose that you've decided that in
your environment, saying @geindex hello world
@dfn{hello world} is unacceptable -- you really
require the more correctly punctuated @geindex hello, world
@dfn{hello, world}.


Now, here's the problem:  sure, you can download their sources and
make that change.  But meanwhile, the project is going to keep
working.  They're going to keep making changes.   So, you'll be faced
with a perpetual task of repeatedly downloading their latest sources
and copying your changes to their latest version.


@code{arch} can help automate that task, and this chapter explains how.




@need 3200

@section Making a Branch from a Remote Project in a Local Archive

@geindex tag



In the examples that follow, you'll be changing roles.  Instead of
"playing" Alice or Bob, the programmers on the @code{hello-world}
project, you'll be playing Candice: a third party.


Let's start by giving Candice her own archive to use, and making that
the default archive:

@example
@group

@end group
@group
        % tla make-archive candice@@candice.net--2003-candice \
                             ~/@{archives@}/2003-candice
@end group
@group

@end group
@group
        % tla my-default-archive candice@@candice.net--2003-candice
        default archive set (candice@@candice.net--2003-candice)
@end group
@group

@end group
@end example

(You can review what those commands do by reading @ref{Creating a New Archive}.)


Candice needs to create a @code{hello-world} project in her own archive.
She can use:

@example
@group

@end group
@group
        % tla archive-setup  hello-world--candice--0.1
@end group
@group

@end group
@end example

She doesn't @emph{have} to use the same project name that Alice and Bob are
using and, in fact, in this case she chose a different branch name.
(To review those commands, see @ref{Starting a New Project}.)


When Alice and Bob created their archive, they used @code{import} to create
the first revision.  Since we're creating a @emph{branch}, we'll use a
different command.


For the sake of example, let's suppose Candice is going to start from
the @code{patch-1} revision of Alice and Bob's archive:

@example
@group

@end group
@group
    % tla tag \
        lord@@emf.net--2003-example/hello-world--mainline--0.1--patch-1 \
        hello-world--candice--0.1
    [....]
@end group
@group

@end group
@end example

There are a few things worth noting about that command.


First, note that we used a @emph{@strong{fully qualified revision name}} to refer to
Alice and Bob's @code{patch-1} revision.  That's because that revision is
in some archive other than the current default archive.  (See
@strong{Working with Several Archives at Once} in @ref{Shared and Public Archives}.)


Next, note that we specified the @code{patch-1} revision explicitly.  If we
had left of the @code{--patch-1} suffix, then the @code{tag} command would
assume we meant the @emph{latest} revision in Alice and Bob's archive
(which happens to be @code{patch-3}).




@need 3200

@section What tag Just Did

After using @code{tag}, Candice now has a new revision in her archive:

@example
@group

@end group
@group
   % tla revisions --summary hello-world--candice--0.1
   base-0
       tag of lord@@emf.net--2003-example/hello-world--mainline--0.1--patch-1
@end group
@group


@end group
@end example

She can retrieve that revision in the usual way:

@example
@group

@end group
@group
   % tla get hello-world--candice--0.1 hw-candice
   [...]
@end group
@group

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

@end group
@end example

@strong{Nifty arch Feature:} If you've followed along closely, you should
have noticed that Candice created a branch in her archive from an arch
revision stored in another archive entirely.  In our examples, both of
these archives happen to be on the local file system but that isn't
necessary: Candice could have formed her branch even if she was
accessing Alice and Bob's archive over the network.


@strong{Usage Caution:}  Candice's job isn't quite done yet.   The next 
section explains another step she'll @emph{probably} want to take.




@need 3200

@section Caching a tag Revision

@geindex archive-cache-revision



Candice used @code{tag} to create a branch from Alice and Bob's archive.
When she uses @code{get} to check-out that revision, what happens?  Roughly
speaking, @code{arch} notices that the revision is a branch, then consults
Alice and Bob's archive to really get the source.


The question then arises: what if Alice and Bob's archive "goes
away"?  As things stand, if that happens, Candice will no longer be
able to @code{get} from her branch.


She can fix that though by caching in her archive all of the
information needed to build the revision:

@example
@group

@end group
@group
   % tla cacherev hello-world--candice--0.1--base-0
   [...]
@end group
@group

@end group
@end example

@noindent
and confirm that that worked with:

@example
@group

@end group
@group
   % tla cachedrevs hello-world--candice--0.1
   hello-world--candice--0.1--base-0
@end group
@group

@end group
@end example

Thereafter, @code{arch} will no longer rely on Alice and Bob's archive to
retrieve Candice's @code{base-0} revision.




@need 3200

@section Exploring the New Branch

Earlier, Candice created her branch and used @code{get} to check it out.
Let's examine that tree:

@example
@group

@end group
@group
        % cd ~/wd/hw-candice
@end group
@group

@end group
@group
        % tla log-versions
        candice@@candice.net--2003-candice/hello-world--candice--0.1
        lord@@emf.net--2003-example/hello-world--mainline--0.1
@end group
@group

@end group
@end example

Note that Candice's tree has patch logs both for Alice and Bob's
versions, and for her own branch:

@example
@group

@end group
@group
    % tla logs --summary \
            lord@@emf.net--2003-example/hello-world--mainline--0.1
    base-0
        initial import
    patch-1
        Fix bugs in the "hello world" string
@end group
@group


@end group
@group
    % tla logs --summary hello-world--candice--0.1
    base-0
        tag of \
        lord@@emf.net--2003-example/hello-world--mainline--0.1--patch-1
@end group
@group


@end group
@end example

There are not any later changes on Candice's branch:

@example
@group
        % tla missing hello-world--candice--0.1
        [no output]
@end group
@group
@end group
@end example

@noindent
but recall that Alice and Bob are already up to @code{patch-3}:

@example
@group
        % tla missing -A lord@@emf.net--2003-example \
                hello-world--mainline--0.1
        patch-2
        patch-3
@end group
@group
@end group
@end example



@need 3200

@section Making a Local Change

After the initial @code{tag}, Candice can commit changes to her branch in
the usual way.


Let's suppose that she has edited @code{hw.c} so that it now reads (in
part):

@example
@group

@end group
@group
        % cat hw.c
        [...]
        void
        hello_world (void)
        @{
          (void)printf ("hello, world\n");
        @}
        [...]
@end group
@group

@end group
@end example

@noindent
and that's she's prepared a log message:

@example
@group

@end group
@group
    % cat ++log.hello-world--candice--0.1--lord@@emf.net--2003-candice
    Summary: Punctuated the output correctly
    Keywords: 
@end group
@group


@end group
@group
    This program should say "hello, world" not "hello world".
@end group
@group

@end group
@end example

Now she can simply commit in the usual way, creating her own @code{patch-1}
revision:

@example
@group

@end group
@group
   % tla commit
   [....]
@end group
@group

@end group
@group
   % tla revisions --summary hello-world--candice--0.1
   base-0
       tag of \
       lord@@emf.net--2003-example/hello-world--mainline--0.1--patch-1
   patch-1
       Punctuated the output correctly
@end group
@group

@end group
@end example



@need 3200

@section Updating from a Branched-from Version

@geindex merging

@geindex log-for-merge



Meanwhile, Alice and Bob have gone on to create their revisions
@code{patch-2} and @code{patch-3}.   How can Candice add those changes to her
branch?


Well, really, @code{arch} provides lots of techniques.  Using commands
we've already introduced, she could use either @code{update} or @code{replay}.
In this example, we'll demonstrate using @code{replay}.

@example
@group

@end group
@group
        % cd ~/wd/hw-candice
@end group
@group

@end group
@group
        % tla replay -A lord@@emf.net--2003-example \
                hello-world--mainline--0.1
        [...]
@end group
@group

@end group
@end example

Note that we used a @code{-A} argument to say which archive we are
replaying changes from, and a version name to say which changes we
want.  In this case, @code{replay} applied the changesets for @code{patch-2} and
@code{patch-3} to Candice's tree.


This use of @code{replay} is a form of @geindex merging
@dfn{merging}:  Candice's local changes
have been merged with Alice and Bob's @code{mainline} changes.


@strong{Learning Note:}  If you're following along with the examples, you
should examine @code{hw.c} and notice that Candice's change to the @code{printf}
string and Alice's addition of a "copywrong" notice are both
included.


@strong{Learning Note:} You should also check out a second copy of Candice's
@code{patch-1} revision and experiment with doing the same merge using
@code{update} instead of @code{replay}.  You might have to look at @code{tla update
-help} to figure out exactly what options and arguments to provide.


Note also that, so far, we've only made these changes to Candice's
project tree -- they haven't been checked into Candice's archive.  To
actually record the merge in her archive, she'll have to make a log
message and commit in the usual way (see @ref{Checking-in Changes}).


There is, however, one more convenience to point out.  When Candice
writes her log message, she'll presumably want to note that the merge
took place and what it involves.  @code{arch} includes a command whose
output is ideal for inclusion in such a log message:

@example
@group

@end group
@group
  % cd ~/wd/hw-candice
@end group
@group

@end group
@group
  % tla log-for-merge
  Patches applied:
@end group
@group

@end group
@group
    * lord@@emf.net--2003-example/hello-world--mainline--0.1--patch-3
       added copywrong statements
@end group
@group

@end group
@group
    * lord@@emf.net--2003-example/hello-world--mainline--0.1--patch-2
       commented return from main
@end group
@group

@end group
@end example



@need 3200

@section How It Works -- tag and Elementary Branches

What did @code{tag} do?  Let's look at Candice's archive:

@example
@group

@end group
@group
        % cd ~/@{archives@}
        % cd 2003-candice
        % cd hello-world
        % cd hello-world--candice
        % cd hello-world--candice--0.1
@end group
@group

@end group
@group
        % ls
        +version-lock   base-0          patch-1
        patch-2
@end group
@group

@end group
@end example

Of particular interest is the @code{base-0} revision -- the one created by
@code{tag}:

@example
@group

@end group
@group
        % cd base-0
@end group
@group

@end group
@group
        % ls
        CONTINUATION
        hello-world--candice--0.1--base-0.patches.tar.gz
        hello-world--candice--0.1--base-0.tar.gz
        log
@end group
@group

@end group
@group
        % cat CONTINUATION
        lord@@emf.net--2003-example/hello-world--mainline--0.1--patch-1
@end group
@group

@end group
@end example

The file @code{CONTINUATION} identifies this revision as a @code{tag} revision.
Its contents tell us what revision we branched from.


The changeset for this revision (@code{....patches.tar.gz}) was also created
by @code{tag}.  If you explore that changeset (recall @code{get-changeset} and
@code{show-changeset}) you'll see that all it does is add a log entry to the
tree's patch log.


The source file (@code{...base-0.tar.gz}) was created by
@code{archive-cache-revision}.   It contains a complete copy of Candice's
@code{base-0} revision.  Since that file is there, @code{get} is not obligated
to look at Alice and Bob's archive to construct this revision.







