The Hackerlab at `regexps.com`

## The update/commit Style of Cooperation

up: arch Meets hello-world next: Introducing Changesets prev: Shared and Public Archives

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 simplest techniques.

### Alice and Bob Hack main

Let's suppose that Alice and Bob are both working on the `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:

            % cd ~/wd

            % [ ... remove any directories left from earlier examples ...]

            % larch get hello-world--maineline--0.1  hello-world-Alice
            [....]

            % larch get hello-world--maineline--0.1  hello-world-Bob
            [....]

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

            % cd ~/wd/hello-world-Alice

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

            extern void hello_world (void);

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

            #include <stdio.h>

Bob, meanwhile, has added a much-needed comment to `main` :

            % cd ~/wd/hello-world-Bob

            % cat main.c
            extern void hello_world (void);

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

              /* Exit with status 0
               */
              return 0;
            }

            /* tag: main module of the hello-world project
             */

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

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

       % cd ~/wd/hello-world-Bob

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

       [Bob edits the log message.]

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

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

Then he calls `commit` :

       % larch commit
       [...]

### Alice Can Not commit Yet

Now it's Alice's turn:

       % cd ~/wd/hello-world-Alice

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

       [Alice edits the log message.]

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

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

And then tries to commit:

       % larch commit
       [....]
       commit: project tree out of date

         Working directory is missing these patches:

               patch-2

         Unable to complete "commit".

       Try "larch update --help" or "larch commit --out-of-date-ok"

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

### Studying Why Alice Can Not commit

The `commit` command told Alice that here 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:

            % larch whats-missing
            patch-2

or for more detail:

            % larch whats-missing --summary
            patch-2
                commented return from main

which you should recognize as the `Summary:` line from Bob's log message.

She can get even more detail with the (previously introduced) `revisions` command (see Storing the First Revision in the Archive).

She can view Bob's entire log message:

        % larch 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
        Standard-date: 2003-01-29 20:46:50 GMT
        Summary: commented return from main
        Keywords:
        New-files: {arch}/hello-world/[....]
        Modified-files: main.c
        New-patches: \
          lord@emf.net--2003-example/hello-world--mainline--0.1--patch-2

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

By looking at the headers of that message, Alice can figure out, for example, that Bob modified the file `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.

### The update Command

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

            % cd ~/wd

            % larch update --in-place hello-world-Alice
            [....]

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

            % cd hello-world-Alice

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

            extern void hello_world (void);

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

              /* Exit with status 0
               */
              return 0;
            }

            /* tag: main module of the hello-world project
             */

Since no further changes are missing:

            % larch whats-missing
            [no output]

`commit` is happy to proceed:

            % larch commit
            [....]

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

### How it Works -- The update Command

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

For now, if you are familiar with `diff` and `patch` , you can think of it this way:

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

First, it uses a command called `mkpatch` (which is kind of a fancier variation on `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 `patch-2` revision and replaces Alice's tree with that revision.

Third, `update` uses `dopatch` (a fancier `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 Inexact Patching -- How Conflicts are Handled).

arch Meets hello-world: A Tutorial Introduction to The arch Revision Control System
The Hackerlab at `regexps.com`