Next: , Up: Collaborating With Other People


5.1 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.

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. In this example, we will see how to use a single, central archive shared among several developers.

5.1.1 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 ...]

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

             % tla get hello-world--mainline--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;
             }

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

5.1.2 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

        % tla 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:

        % tla commit
        [...]

5.1.3 Alice Can Not commit Yet

Now it's Alice's turn:

        % cd ~/wd/hello-world-Alice

        % tla 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:

        % 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)

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

5.1.4 Studying Why Alice Can Not commit

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

             % tla missing
             patch-2

or for more detail:

             % tla 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 in Importing the First Revision).

She can view Bob's entire log message:

         % 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
         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.

5.1.5 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

             % tla 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;
             }

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

Since no further changes are missing:

             % tla missing
             [no output]

commit is happy to proceed:

             % tla 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 (missing, update, changes and so forth).

5.1.6 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).