ペンギン流BK法

Submitted by Hiroshi Miura on 土曜, 2007-01-13 02:44
>

ペンギン流BK法

目次

この文書は、Jeff Garzik がlkmlに投稿したDoing the BK thing, Penguin-Styleを翻訳である。 この一連のメモは、主として(常勤または臨時の)カーネル開発者を対象としてはいるが、 システム管理者やパワーユーザにとっても利益になる情報があるかもしれない。 少なくとも、CVSのユーザレベル(コマンドライン利用)および上級レベル(サーバ利用) の基本的な経験があることを前提としている。 著者の経験の関係上、操作についてはCVSの用語を使って記述するか、 その操作がCVSからどのように異なっているかの説明を行う。 これは、BitKeeperのドキュメントを意図したものでは「ない。」常に"bk help "や Xの"bk helptool "をリファレンスに実行するようにしてほしい。

BitKeeperの考え方

インターネット自身の本来の性質から、BitKeeperは分散システムになっている。 リビジョン制御を行うとき、これはクライアントサーバを離れ、 親子モデル... あるいは本質的にピア to ピアモデルへと変化することを意味する。 開発者から見れば、変更、コミット、マージといった標準ワークフローが、 基本的に分裂されるということになる。BitKeeperのもと、どのように仕事をするのが 最もよいのかを考え、物事を最適化するのに、ここで若干の時間をとる必要があるだろう。 ある意味、これはかなりラジカルなことになる。というのは、大混乱のなかに変更を 混ぜ入れるといったことをそして、奇跡的に正しい方向へと着地させる ことを書こうとしているから... しかし、自分が先頭を切っているわけではないが...

さあ、先へ進めよう。

  • ディスクにある各BitKeeperのソースツリーは、それ自身のリポジトリである。
  • 各リポジトリは親を持つ。
  • 各リポジトリは、変更セット("csets")一式からなる。
  • 各csetは一つか複数の変更されたファイルであり、一つにまとめられている。

各ツリーはリポジトリであるので、すべての変更はローカルツリーへといれられる。 変更がチェックインされるとき、すべての更新されたファイルは、論理的なまとまりで グループ化される。これが変更セットである。内部的には、開発の様々な集中と分岐ラインを 表現するため、BKはこれらの変更セットをツリーにリンクしている。

変更セットのコンセプトの後に、さらに追い討ちをかけることになるが、 複数のソーススリーのコピーを持つことに慣れてほしい。 これは、一部の人にとっては、*本当に*慣れるのが大変だ。 ソースツリーを分けることは、BitKeeperでは、メジャーおよびマイナーの 並行した複数の開発ラインを線引して管理することを意味している。 CVSでいうブランチは、分離されたソースツリーになるが、BitKeeperの 用語では、"クローン"[Heh, or Star Wars]になる。

クローンと変更セットは、BitKeeperを最も強力にするツールになっている。 先に述べたように、各クローンは親を持ち、新しいクローンが 作られたときに、ツリーはソースとして使われる。CVS的にいうと、 親はインターネット上のリモートサーバであり、子供はツリーのローカルコピー に相当する。

一旦、2つのソースツリーを共通のスタートライン(baseline)に立たせたなら、 (つまり共通の親をもったなら)、容易にこれらの2つのツリー間の変更セットを マージできる。ツリーへの変更のマージは、'pull'と呼ばれ、'cvs update' に相似している。 pullは自分の持っていないリモートツリーの全ての変更 セットをダウンロードし、それらをマージする。あるツリーから他のツリーへと 変更を送るには、'push'と呼ばれる方法を使う。Pushは、ローカルツリーの 全ての変更で、リモートにないものを送ってマージする。

いくつか、最初のコマンド例で、これらのコンセプトを見てみよう。

  1. bk clone -q http://linux.bkbits.net/linux-2.5 linus-2.5
    ストックされている2.5カーネルツリーをダウンロードし、"linus-2.5"とローカルディレクトリで命名する。"-q"は、ダウンロード時の各ファイルの一覧表示を抑制する。
  2. bk clone -ql linus-2.5 alpha-2.5
    Alpha AXPアーキテクチャ用の分岐したソースツリーを作成する。"-l"は、両方のツリーがローカルのハードディスクにあるときに、データをコピーする代りにハードリンクを使用することを指示している。上記を、"bk lclone -q ..."で置き換えることもできる。

    ツリーのクローンは、「一回だけ」つくることができる。クローンのあとは、ツリーは、pushしたりpullしたりしてアップデートすることで、ディスクにいくらでもおいておくことができる。

  3. cd alpha-2.5 ; bk pull http://gkernel.bkbits.net/alpha-2.5
    ローカルリポジトリにない、"alpha-2.5"リポジトリでの変更をダウンロードし、ソースツリーにマージする。
  4. bk -r co -q
    各ツリーはつまりはリポジトリであるため、ファイルは、ソースツリーの本来の場所におかれる前にチェックされなければならない。
  5. bk vi fs/inode.c # example change... bk citool # checkin, using X tool bk push bk://gkernel@bkbits.net/alpha-2.5 # upload change BKによる手順でよくあるのは、CVSでたとえて言えば、vi fs/inode.c cvs commit

ここまででBKの概略紹介を終える。これ以上の深いチュートリアルは、 http://www.bitkeeper.com/ にある実際に動かしてのデモや、 ドキュメントを参照して欲しい。

BK と カーネル開発ワークフロー

現在、最新の2.5 ツリーは、http://linux.bkbits.net/linux-2.5 で "bk clone $URL" と "bk pull $URL" を実行することで入手できる。 このURLは、数週間のうちに、kernel.org のURL へと変更されることになっている。

BitKeeperを使う大きな理由に、ローカルディスクにある様々なツリーを組織化し、 これらのツリーや、リモートのツリーでの変更手順を組織化することにある。 desired BK 設定での関係をグラフに表したとすると、以下のような few-many-few グラフ構造になることだろうと考えると思う。

		    linux-2.5
		        |
	       merge-to-linus-2.5
		 /    |      |
	        /     |      |
	vm-hacks  bugfixes  filesys   personal-hacks
	      \	      |	     |		/
	       \      |      |         /
		\     |      |        /
	         testing-and-validation

"bk push" は、ターゲットツリーにない、全ての変更を送り、 "bk pull" は、ソースツリーにない全ての変更を受け取るために、 対象ツリーの特定の変更だけを送りたい、あるいは "peer の親" から 全ての変更を受け取りたくないとおもうでしょう。 例えば、手元のテストし評価したツリーの変更を push すると、 これは vm-ハック や バグフィックス、ファイルシステムの変更、そして個人的ハックを 対象ツリーに送ってしまうことになり、悪い考えと言うことになります。

大抵の場合、一つの"テーマ"に従い作業を行い、VMのハックや、バグフィックス、 ファイルシステムについてなど、開発中は、それぞれの変更は別々のツリーに おいているでしょう。そして、アップストリーム(Linuxや、他のメンテナ)に送るときにも、 ダウンストリーム(あなたの"共有"しているツリー、上記をテストし評価する場合など)に 送るときにも、他の変更と区別してマージするでしょう。

ここで、このような分離は、推奨される方法ではないことを注記しなければならないでしょう。 これは実際には、[いまのところ] BitKeeper に-強制-されていることなのです。 BitKeeperは、変更セットがある順序で維持されることを要求しており、これは"bk push" が、リモートにないすべてのローカルの変更セットを送ろうとするのが理由になっています。 この分離は、最初は多くのディスクスペースの浪費になるように思いますが、 2つの関連のない変更が、コードの同じ部分を"汚染する"ときには、助けになります。

小さな開発ブランチ(クローン)が発生しなくなる:

	-------- A --------- B --------- C --------- D -------
	          \                                 /
		   -----short-term devel branch-----

長いブランチは、マージまでの間ツリー(やツリー群)を並行にします。この最初の例は、 ツリーから定期的にPull("\"をPull)して、変更をメインのラインにpushすることをせず、 ベンダーツリーの変更を追い掛けているときに起るような事象です。


	-------- A --------- B --------- C --------- D -------
	          \                       \           \
	           ----long-term devel branch-----------------

そして、Linux kernel開発でより共通の場合には、ツリー("/"にpush)にマージされて戻されるまで 長期のブランチで以下のようになります。


	-------- A --------- B --------- C --------- D -------
	          \                       \         / \
	           ----long-term devel branch-----------------


Linusに変更を送る

ここで、Linusに変更を送るときの、方法またはスタイルについて述べておきます。 Linusのツリーは現在(あなたが言うところの)BitKeeperシステムに完全に統合された状況になっており、 適切にBitKeeperに変更を提出するには、あらかじめ必要な条件があります。 すべての要求条件は単純に一般的なBKの利用方法から明らかなことです。 つまり、みなさんがBKのエキスパートになって、このプロセスを将来最適化すること (もちろん、Linusも了承するでしょう)です。

  1. まず、あなたのツリーは、もともとはLinusが作ったlinux-2.5ツリーのクローンであることを確認します。もし、ツリーがこれを祖先としていない場合、信頼できる変更セットの交換はできません。
  2. コミットテキストに注意を払います。あなたが提示した各変更セットにつけるコミットメッセージは、将来にわたり歴史に残ります。そしてLinusが、各プレパッチの変更のサマリーに明らかに使われます。その説明には、いかなるコンテキストもないことに注意してください。つまり、

    "fix for new scheduler changes"

    はあまりに曖昧であり、

    "fix mips64 arch for new scheduler switch_to(), TIF_xxx semantics"

    がより良いということです。

  3. Linusにとって、インターネットからpullするのに利用可能なURLを含めます。たとえば、

    Pull from: http://gkernel.bkbits.net/net-drivers-2.5

  4. 各変更セットのサマリーと"diffstat -p1'を含めます。これらはLinusが"bk pull"を行ったときにダウンロードされます。作者は、これらのサマリーを"bk push -nl <parent> 2>&1"を使って自動生成させ、全ての保留になっている変更セットのリストとコミットメッセージを取得することができます。
  5. あなたの変更を分割します。各メンテナ<->Linusの状況は、ここで少し異なるので、一般的なアドバイスとして捕らえてください。作者は、Linusによりマージされるときのある「テーマ」に沿って変更を分割します。ローカルでの開発から同時にpushされるものは、Linusのために"queued"される単独で存在する特別なツリーに行きます。たとえば、

    	net-drivers-2.5 -- on-going net driver maintenance
    	vm-2.5 -- VM-related changes
    	fs-2.5 -- filesystem-related changes
    

    そして、Linusは変更を取得するのに、さらに自由度があります。彼は、(たとえば)彼らの変更セットをマージするのに、"bk pull"をvm-2.5やfs2.5ツリーに発行することができます。しかし、net-driver-2.5はいじりません。これは、変更にもっと議論が必要なためです。

    他のメンテナは、単一のlinus-pull-fromツリーが、彼にBKの変更セットを送るには、適当であることを知るでしょう。

よくある質問

  1. 変更ログのe-mailアドレスを変更したいんだけど?
    A. "bk citool"または"bk commit"を実行するときに、環境変数BK_USERとBK_HOSTを指定したいユーザとホスト名にするといい。
  2. タグを使ったり二つのカーネルバージョンのdiffをとるには?
    A. Linusが使っているタグを'bk export'に渡す。

    変更セットは処理順になっており、ある時点の2つの任意の点の開始と終わりでスナップショットをとるのは実に容易です。Linusは書くリリースやプレリリースにタグをつけており、この例のように、タグを使えばいいのです。

        bk export -tpatch -hdu -rv2.5.4,v2.5.5 | less
            # creates patch-2.5.5 essentially
        bk export -tpatch -du -rv2.5.5-pre1,v2.5.5 | less
            # changes from pre1 to final
    

    タグは、単に特定の変更セットのaliasになっています。そして、変更セットは順序が守られるため、タグはある時点の特定の点を(あるいは、ツリーの特定の状態を)指し示すことになります。

新しいコメントの投稿

  • Allowed HTML tags: <a> <p> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • 行と段落は自動的に分けます。

フォーマットのオプションに関する詳細情報

© 2010 Your Name. m