The Hackerlab at regexps.com

update/commit を使った共同作業

up: arch Meets hello-world
next: チェンジセット (changeset) の紹介
prev: 共有、公開アーカイブ

以前の章で習ったことは, アーカイブへプロジェクトを加えて 初期ソースを格納し、そのソースに為された変更点を格納し、 アーカイブからリビジョンを取り出す方法でした.

前の章では、アーカイブをネットワークからアクセスできるようにする方法を習いました。

本章で説明しはじめることは、複数のプログラマが一つのアーカイブを 共有し, 一つのプロジェクトへ各々が変更を加えていく方法です.

最初に注意すべきことは, アーカイブをプログラマが共有する方法や一つのプロジェクトで共同作業するには, ほんとに多くの種類があるということです. ここで始める方法は, 一番 単純なものです.

アリスとボブが main をハックする

アリスとボブは両方とも hello-world プロジェクトで 作業をしており、一つのアーカイブを共有しているものと仮定しましょう。 以下の事例では、私たちは両方の役を演じます。

まず最初に、プログラマ達は, それぞれ自身のプロジェクトツリーが必要です:

        % cd ~/wd

        % [ ... 以前の例で残ってたディレクトリを全て消す ...]


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

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

アリスの任務はそれぞれのファイルに法的な通告を加えることです。 彼女が作業を終えたとき (ただし、まだ変更をアーカイブにコミットしてません), ファイルは次のようになってます:

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

ボブは, その間に, 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;
        }


注意してほしいことは, 二人のプログラマの手元には hello-world の修正版がありますが, どちらのプログラマも相方の修正を持ってません.

ボブが先にコミットする

ボブが彼の変更物を最初にコミットしようとしたと仮定します. 単なる復習ですが, ここは二段階あります.

まず、ボブはログメッセージを準備します。

   % cd ~/wd/hello-world-Bob

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

   [ボブはログメッセージを編集する.]

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


そして、彼は commit コマンドを使います:

   % tla commit
   [...]

アリスはまだコミットできません

こんどはアリスの番です。

   % cd ~/wd/hello-world-Alice

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

   [アリスはログメッセージを編集する.]

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


そしてコミットを試みます:

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

ここでの問題は、ボブの変更がアーカイブに既に格納されてても, アリスのツリーはそれらの変更を反映してないことです。

なぜアリスがコミットできないかについて検討する

commit コマンドは、彼女のツリーが"期限切れ"であるとアリスに伝えました。 これの意味するところは, アーカイブに commit された変更が, 彼女の tree にはまだ commit されてない. ということです.

彼女は自分のツリーで欠落してるもの (missing) を尋ねることで, もう少し堀り下げて状況を調べることができます:

        % tla missing
        patch-2

もしくは, もっと詳しく見るために:

        % tla missing --summary
        patch-2
            commented return from main

これらはボブのログメッセージの Summary: であることを思い出すべきです

彼女は(以前に紹介した) revisions コマンドでさらに詳しく調べることができます (アーカイブに初期リビジョンを格納するを参照).

彼女はボブのログメッセージ全体を見ることができます:

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


メッセージのヘッダから, アリスは, 例えば, ボブが main.c ファイルを変更したことを知ることができます.

後の章では、私たちがボブが変更した変更物を検討するためにアリスが使用できるより多くのコマンドを探索します. しかし、ここでは、アリスが彼女のツリーにどのようにしてその変更を加えることができるかについての話題に戻ることにしましょう。

update コマンド

アリスが変更点を commit 可能になるためには, 彼女とボブの変更点を結合させることが必要です. ひとつの簡単な方法は update コマンドです:

        % cd ~/wd

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


これでアリスは彼女のツリーでボブの変更を見つけるでしょう:

        % 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
         */

これ以上変更点は無いので:

        % tla whats-missing
        [出力無し]

commit はうまく行きます:

        % tla commit
        [....]

学習上の注意: 事例のとおりにフォローしていれば、hello-world-Bob の中に、ボブのツリーがあるはずです。アリスのではありません. そのディレクトリに対して、いろんなコマンドを試してみましょう (whats-missing, update, what-changed など).

どのように動作するか -- updateコマンド

update がどのように働くかの十分な説明は、本章では扱いません. もう少し後の章(チェンジセットやパッチログについての章)になってから update コマンドを詳細に理解できるようになります。

とりあえず、 diffpatch に慣れてるなら, 次のように考えることもできます:

アリスのツリーで update の実行で出てくる通知は, アーカイブは patch-2 リビジョンまであることと, しかしながら, 彼女のツリーは patch-1 リビジョンを get でチェックアウトしたものだということです. update の動作は三段階あります:

まず, mkpatch と呼ばれるコマンド (diff の変わり種) を使い, アリスのツリーで彼女がした変更を記述するチェンジセット (patch set の変わり種)を求めます.

次に, patch-2リビジョンのコピーをチェックアウトして, アリスのツリーをそのリビジョンで置き換えます.

その次に, updatedopatch (patch の変わり種)を使い, 最初の段階から新しいツリーへのチェンジセットを適用します.

たぶん、あなたは patch の衝突がどのように扱われるかと思うでしょう。 上記の例は注意深く作って, どんな衝突も回避しました. ご心配なく、私たちはもうすぐその話題に移ります(不正確なパッチ -- 衝突はどう扱われるかを参照).

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