Binary Dayに寄せて(2008年11月11日 高田 浩和)

はじめに

11月11日の Binary Dayに寄せて、何かコメントがあればとのことでしたが、Linuxカーネルの開発によく使われるいくつかのツール(git/gitk,sparse, etc.)のうち、ちょっとマイナーだけれど、とても便利なツールということで、Quilt[1]を紹介することにしたいと思います。

Quiltのススメ

Quiltとは?

Quiltは、-mmカーネルの開発者として有名な Linux kernel developerである Andrew Morton氏のパッチ管理用スクリプトを元に、Andreas Gruenbacher氏らによって開発された、パッチを管理するのに非常に便利なツールです(Javaプログラムのカバレッジ評価用の開発ツールに、Quiltという同名のツールがあるようですがそれとは別物です)。

もちろん、Quiltは汎用ツールなので、Linuxカーネルの開発にしか使えないというわけではありません。Linuxカーネル以外にも、例えばDebian GNU/Linuxのglibcパッケージなどで、upstreamに対する Debianプロジェクトのパッチを適用するのに Quiltが使われています。

Quiltを使ってみよう

Quiltには、Quiltのコンセプトや使い方をわかりやすく説明したAndreas Gruenbacher氏のドキュメント[2]が添付されていますので、詳しい使用方法については、ぜひそちらを参照下さい。 以下では、具体的な使用方法というよりも、これまでの経験をもとに、ちょっと便利な使い方や、使用上の注意点について、know-how的なものを簡単に紹介したいと思います。

パッチセットで変更内容を管理

プログラム開発で、ソースコードの管理に Subversionや gitを使っている方は多いことでしょう。かく言う私も、今や git/gitkを使わない生活は考えられなくなってしまいました。気がつけば、Linux kernelだけでなく、ホームディレクトリ上の設定ファイルにいたるまで、ありとあらゆるものをgitで管理するのが習慣になってしまいました。

もちろん、数個のファイルのバージョン管理をするだけならば、わざわざ gitを持ち出すまでもなく、RCSで十分でしょう。しかし、何かしらバージョン管理をしたくなるケースでは、得てして、後になってからファイル数が増えたり、ファイル名を変えたくなったりと、こういうことなら最初から gitにしておけばよかったと思うケースが多々あります。

git以外のソースコード管理ツールを使う機会が減ったとはいえ、開発プロジェクトによっては、他のメンバとリポジトリを共有する場合など、好むと好まざるとにかかわらず、CVSのようなツールを使わざるを得ない状況は依然としてあります。そのような場合でも、git-cvsimport,git-exportcommitを使ってリポジトリ間の同期をとることで、多少の手間がかかっても、gitリポジトリのコピーを持つ方がかえって効率的な場合も多いようです。

長々と gitの話をしてしまいましたが、ではなぜ gitは CVSより便利なのでしょうか? 最大の理由は、gitがパッチセット単位でソースコードの変更履歴を管理しているからです。タグづけされたCVSリポジトリから過去のバージョンを取り出すのは容易ですが、複数のファイルに対して詳細な変更履歴を追うのはとても大変です。

Quiltも gitと同様、パッチセット単位で変更内容を管理します。もともとパッチ管理用に作られた Quiltは、パッチセットの管理に威力を発揮します。

Quiltのいいところ

gitを使う前、一時期、かなり Quiltが気に入って、こればかり使っていた時期がありました。私が Quiltを使い始めたのは、LKMLにパッチを投稿[3]しはじめたときに、上述のAndrew Morton 氏から勧められたのがきっかけでした。いざ使い始めてみると、いくつかのファイルの変更をパッチセットで管理するというやり方は、実際、想像以上に新鮮かつ強力で、たちまちハマってしまった記憶があります。

Quiltの素晴らしいところは、やはり何といっても、パッチの取り外しが非常に楽というところでしょうか。

開発途中で試した変更が間違っていると分かった時、そのパッチを不採用にするのはとても簡単です。CVSではこううまくはいきません。cvsadmin -oで変更内容を消したり、あるいはリポジトリの中を直接いじれば可能ではありますが、危険を伴います。gitの場合でも、パッチのwithdrawingは、履歴を残したくない場合には、別なブランチを切ったりrebaseしたりと、結構面倒くさいことになります。

同様の操作は、Quiltの場合にはとても簡単です。patches/seriesにパッチの一覧が置かれていますが、不要なパッチを無効化するには、quiltpop -a した状態で、単にseriesファイル中の該当パッチの行を'#'でコメントアウトするだけで OKという手軽さです。

また、パッチの内容説明の編集が容易というのも、メリットの一つかも知れません。commit時に、かならずしも適切なコメントをつけられるとは限らないため、あとで編集するのは結構大変です。Quiltならばpatchesに置かれた各パッチのファイルをエディタで編集するだけで、いつでも修正が可能です。

Quiltのちょっと便利な使い方
行末の不要な空白を自動的に削除

Quiltを使うと、行末の不要な空白(trailing whitespaces)を簡単に取り除くことができるというメリットもあります。万一、変更したソースにこのような余分な空白(whitespace damages)が残っていても、quiltrefreshの実行時、行末の空白が見つかるとWarningメッセージが出力されるので、一目瞭然です。ここで、

$ quilt refresh --strip-trailing-whitespace

とすれば、行末の空白は quiltが自動的に削除してくれます。通常は、行末の空白は削除する方がよいので、~/.quiltrcのQUILT_REFRESH_ARGS に --strip-trailing-whitespaceを追加しておくのがよいでしょう。

QUILT_REFRESH_ARGS="--no-timestamps --backup --strip-trailing-whitespace"

このように .quiltrcに設定しておくことで、以後は quilt refreshで常に --strip-trailing-whitespaceが有効となり、行末の空白が自動的に削除されるようになります。

quilt editのエイリアスを定義しておく

パッチセットを新たに作った(quilt new)とき、変更対象のファイルを編集するためのコマンドが quilt editです。もしエディタとして viを使用している場合は、この quilt editコマンドを例えば qiのようにエイリアス登録しておくと便利かもしれません。

alias qi='quilt edit '     # sh/bash

こうしておくと、vi filenameと入力する代わりに qi filenameと入力することで普通に編集作業が行えます。あとは編集後に quilt refreshを一発実行するのみで、パッチ情報が自動的に作成されます。

Quiltのちょっと困ったところ

Quiltを使っていてあまり不都合な点はないのですが、いい点ばかり紹介するのではバランスを欠くので、あえてちょっとばかり困った点についても紹介しておくことにします。

唯一困ると言えば、パッチを適用した状態のソースツリーを tarでバックアップしようとすると、Permission deniedエラーが起きる場合があることでしょうか。

quiltが自動的に生成する、.pcという名前の管理用ディレクトリの中に、各パッチ適用前のファイル内容を保持したファイルが格納されます。新規にファイルが追加された場合には、以前のファイルが存在しないため、管理用ディレクトリには空のファイルが格納されますが、この空ファイルには rwx属性が全くつけられていません。そのため、tarで .pcディレクトリごと一緒にバックアップをとろうとすると、エラーになってしまうのです。

この問題を回避するには、quilt pop -aとして、すべてのパッチを適用前の状況にもどした状態にしてやる必要があります。もしパッチを適用した状態のソースツリーのスナップショットがとりたいときは、.pcを含めずにソースツリーだけを別途アーカイブしなくてはなりません。

おわりに

Binarianの読者の方々には、釈迦に説法、何をいまさらと言われるかも知れないとは思いつつも、ごく簡単に Quiltの紹介をしてみました。内容に関して、間違っている箇所もあるかもしれませんが、ご指摘いただければ幸いです。

もともと、Quiltはパッチの管理用スクリプトとして作られたため、本格的なバージョン管理ツールとして使うには無理があります。しかし、そこは適材適所。完全なパッチセットをつくるには、何度も試行が必要です。何でもかんでも gitに突っ込む前に、ササッとパッチを Quiltで試してみるというのも案外効率的かもしれません。

それでは、最後に、Binary Dayにちなんで、あの名言を引用しておきます。

0101010001101000011001010111001001100101001000000110000101110010
0110010100100000011011110110111001101100011110010010000000110001
0011000000100000011101000111100101110000011001010111001100100000
0110111101100110001000000111000001100101011011110111000001101100
0110010100100000011010010110111000100000011101000110100001100101
0010000001110111011011110111001001101100011001000011101000001010
0101010001101000011011110111001101100101001000000111011101101000
0110111100100000011101010110111001100100011001010111001001110011
0111010001100001011011100110010000100000011000100110100101101110
0110000101110010011110010010000001100001011011100110010000100000
0111010001101000011011110111001101100101001000000111011101101000
0110111100100000011001000110111101101110001001110111010000101110

リファレンス

[1] Quilt:
    http://savannah.nongnu.org/projects/quilt

[2] Andreas Gruenbacher,
    "How To Survive With Many Patches or Introduction to Quilt", June 12, 2005.
    http://www.suse.de/~agruen/quilt.pdf

[3] linux-2.6.23/Documentation/SubmittingPatches(和訳)
    http://www.linux.or.jp/JF/JFdocs/kernel-docs-2.6/SubmittingPatches

高田 浩和 (Hirokazu Takata)takata@linux-m32r.org
Linux/M32R Project: http://www.linux-m32r.org

Valid XHTML 1.0 Transitional

192.168.0.1は、私が使っている IPアドレスですので勝手に使わないでください --- ある通りすがり

処理中...