@need 3200

@node The update/commit Style of Cooperation
@chapter The update/commit Style of Cooperation

In earlier chapters, you learned how to add a project to an archive,
store the initial sources, store changes made to those sources, and
retrieve revisions from the archive.


In the previous chapter, you learned how to make an archive network
accessible.


This chapter will begin to explore how multiple programmers can share
an archive, with each of them making changes to a particular project.


You should take note at the outset that there are really many subtle
variations on how programmers can share archives and otherwise
cooperate on a given project.   We're starting here with one of the
very @emph{simplest} techniques.

@need 3200

@section Alice and Bob Hack main

Let's suppose that Alice and Bob are both working on the @code{hello-world}
project and that they are sharing a single archive.  In the examples
that follow, we'll play both roles.


For starters, each programmer will need their own project tree:

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

@end group
@group
        % [ ... remove any directories left from earlier examples ...]
@end group
@group


@end group
@group
        % tla get hello-world--mainline--0.1  hello-world-Alice
        [....]
@end group
@group

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

Alice's task is to add some legal notices to each file.  When she's
done (but has not yet used @code{commit} to write her changes to the
archive), the files look this way:

@example
@group
        % cd ~/wd/hello-world-Alice
@end group
@group

@end group
@group
        % head -3 main.c
        /* Copywrong 1998 howdycorp inc.  All rights reversed.*/
@end group
@group

@end group
@group
        extern void hello_world (void);
@end group
@group

@end group
@group
        % head hw.c
        /* Copywrong 1998 howdycorp inc.  All rights reversed. */
@end group
@group

@end group
@group
        #include <stdio.h>
@end group
@group
@end group
@end example

Bob, meanwhile, has added a much-needed comment to @code{main}:

@example
@group
        % cd ~/wd/hello-world-Bob
@end group
@group

@end group
@group
        % cat main.c
        extern void hello_world (void);
@end group
@group

@end group
@group
        int
        main (int argc, char * argv[])
        @{
          hello_world ();
@end group
@group

@end group
@group
          /* Exit with status 0
           */
          return 0;
        @}
@end group
@group

@end group
@end example

Note that the two programmers now have modified versions of
@code{hello-world}, but neither programmer has the other's changes.




@need 3200

@section Bob commits First

Let's suppose that Bob is the first to try to commit his changes.
Just to review, there are two steps.


First, Bob prepares a log message:

@example
@group
   % cd ~/wd/hello-world-Bob
@end group
@group

@end group
@group
   % tla make-log
   ++log.hello-world--mainline--0.1--lord@@emf.net--2003-example
@end group
@group

@end group
@group
   [Bob edits the log message.]
@end group
@group

@end group
@group
   % cat ++log.hello-world--mainline--0.1--lord@@emf.net--2003-example
   Summary: commented return from main
   Keywords: 
@end group
@group

@end group
@group
   Added a comment explaining how the return from `main'
   relates to the exit status of the program.
@end group
@group

@end group
@end example

Then he calls @code{commit}:

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



@need 3200

@section Alice Can Not commit Yet

Now it's Alice's turn:

@example
@group
   % cd ~/wd/hello-world-Alice
@end group
@group

@end group
@group
   % tla make-log
   ++log.hello-world--mainline--0.1--lord@@emf.net--2003-example
@end group
@group

@end group
@group
   [Alice edits the log message.]
@end group
@group

@end group
@group
   % cat ++log.hello-world--mainline--0.1--lord@@emf.net--2003-example
   Summary: added copywrong statements
   Keywords: 
@end group
@group

@end group
@group
   Added copywrong statements to the source files so 
   that nobody can steal HowdyCorp's code.
@end group
@group

@end group
@end example

And then tries to commit:

@example
@group
   % tla commit
   commit: tree is not up-to-date 
     (missing latest revision is 
       lord@@emf.net--2003b--2003-example/hello-world--mainline--0.1--patch-2)
@end group
@group
@end group
@end example

The problem here is that Bob's changes have already been stored in the
archive, but Alice's tree doesn't reflect those changes.




@need 3200

@section Studying Why Alice Can Not commit

@geindex missing

@geindex cat-archive-log



The @code{commit} command told Alice that her tree is "out of date". 
That means that changes have been committed to the archive that her
tree doesn't have yet.   


She can examine the situation in a little more depth by asking
what her tree is missing:

@example
@group
        % tla missing
        patch-2
@end group
@group
@end group
@end example

@noindent
or for more detail:

@example
@group
        % tla missing --summary
        patch-2
            commented return from main
@end group
@group
@end group
@end example

@noindent
which you should recognize as the @code{Summary:} line from Bob's log
message.


She can get even more detail with the (previously introduced)
@code{revisions} command (see @strong{Storing the First Revision in the Archive} in @ref{Importing the First Revision}).


She can view Bob's entire log message:

@example
@group
    % tla cat-archive-log hello-world--mainline--0.1--patch-2
    Revision: hello-world--mainline--0.1--patch-2
    Archive: lord@@emf.net--2003-example
    Creator: Tom (testing) Lord <lord@@emf.net>
    Date: Wed Jan 29 12:46:50 PST 2003
@end group
@group
    Standard-date: 2003-01-29 20:46:50 GMT
    Summary: commented return from main
@end group
@group
    Keywords: 
    New-files: @{arch@}/hello-world/[....]
    Modified-files: main.c
    New-patches: \
      lord@@emf.net--2003-example/hello-world--mainline--0.1--patch-2
@end group
@group

@end group
@group
    Added a comment explaining how the return from `main'
    relates to the exit status of the program.
@end group
@group

@end group
@end example

By looking at the headers of that message, Alice can figure out, for
example, that Bob modified the file @code{main.c}.


In later chapters, we'll explore more commands that Alice can use to
study the changes that Bob made, but for now, let's turn to how Alice
can add those changes to her tree.




@need 3200

@section The update Command

Alice needs to combine her changes with Bob's before she can @code{commit}
her changes.   One easy way to do that is the @code{update} command:

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

@end group
@group
        % tla update --in-place hello-world-Alice
        [....]
@end group
@group

@end group
@end example

Now she will find Bob's changes added to her tree:

@example
@group
        % cd hello-world-Alice
@end group
@group

@end group
@group
        % cat main.c
        /* Copywrong 1998 howdycorp inc.  All rights reversed. */
@end group
@group

@end group
@group
        extern void hello_world (void);
@end group
@group

@end group
@group
        int
        main (int argc, char * argv[])
        @{
          hello_world ();
@end group
@group

@end group
@group
          /* Exit with status 0
           */
          return 0;
        @}
@end group
@group

@end group
@group
        /* arch-tag: main module of the hello-world project
         */
@end group
@group
@end group
@end example

Since no further changes are missing:

@example
@group
        % tla missing
        [no output]
@end group
@group
@end group
@end example

@code{commit} is happy to proceed:

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

@strong{Learning Note:} If you're following along with the examples, you should
still have a tree in @code{hello-world-Bob} that has Bob's changes, but not
Alice's.  Try various commands for that directory to explore (@code{missing},
@code{update}, @code{changes} and so forth).




@need 3200

@section How it Works -- The update Command

A @emph{full} explanation of how @code{update} works is a little beyond the
scope of this chapter.  You'll be able understand @code{update} in detail
after a few of the later chapters (on changesets and patch logs).


For now, if you are familiar with @code{diff} and @code{patch}, you can think of
it this way:


When @code{update} is run in Alice's tree, it notices that the archive is
up to a @code{patch-2} revision, but that her tree was checked out as a
@code{get} of the @code{patch-1} revision.   @code{update} works in three steps:


First, it uses a command called @code{mkpatch} (which is kind of a fancier
variation on @code{diff}) to compute a changeset (a fancy patch set)
that describes the changes Alice made to her tree.


Second, it checks out a copy of the @code{patch-2} revision and replaces 
Alice's tree with that revision.


Third, @code{update} uses @code{dopatch} (a fancier @code{patch}) to apply the 
changeset from the first step to the new tree.


You may be wondering how patch conflicts are handled.  The examples
above were carefully crafted to avoid any conflicts.  Don't worry --
we'll get to that topic soon enough (see @ref{Inexact Patching -- How Conflicts are Handled}).







