CVS

CVS がどういうものか、ということは本編の序章で解説した。 このページではそれを踏まえてもう少し実戦的な話を単発形式で 並べていく。

参考URL

CVS に関する書籍『CVSによるオープンソース開発』は本編でも紹介した。 その原書が『Open Source Development with CVS』なのだが、この本は 一部が GPL のもとにウェブ公開されている。二つめの URL は 「たけうちかほり」さんによるその日本語訳である。

CVS 以外のバージョン管理システム

オープンソースのバージョン管理システムとしては何と言っても CVS が 有名だけども、CVS だけがバージョン管理システムというわけでは 全然ない。

例えば最近 Linux をホストしているのは BitKeeper という バージョン管理システムである。これは CVS よりも複数パッチの 管理に優れているのだそうだ。ちなみに商用ソフトウェアである。

オープンソースソフトウェアでポスト CVS の最右翼と言えば SubVersion だろう。 ファイルの移動やタグにもログが付けられたり、バイナリファイルを うまく扱えるというあたりが CVS よりも優れている。 筆者は本書の原稿も CVS で管理しているのだが、執筆中、 ファイル移動にログが付けられたらいいのに……と何度考えたかわからない。 SubVersion には期待している。なお、SubVersion のソースも archives/ に 収録した (archives/subversion-r3200.tar.gz)。

CVS のインストール

この CD-ROM には cvs のソースコード (archives/cvs-1.11.2.tar.gz) を 収録したが、たいていの OS にバイナリパッケージが用意されていると 思うので、それでインストールしてもいい。以下はコンパイルする場合に 関してだけ解説する。

と言っても、あまり言うことはない。最近の UNIX 系フリーソフトウェアの 例に漏れず cvs も autoconf 化されているので、定石通り onfigure; make; make install でインストールできるからだ。 ruby がコンパイルできるなら余裕だろう。

~/src/cvs-1.11.2 % ./configure
~/src/cvs-1.11.2 % make
~/src/cvs-1.11.2 % su
~/src/cvs-1.11.2 # make install

で OK だ。もちろん configure では --prefix などのオプションも使える。 詳しくどんなのがあるか知りたければ configure --help してみるとか、 README・INSTALL と言ったドキュメントを見ればいい。

Windows での CVS

オリジナルの CVS はいちおう Windows にも対応しているので、 それをコマンドプロンプトから使っても問題ない。いちおう バイナリも入れておいた (archives/cvs-win32-1-11-2.zip)。 これを使う場合には環境変数 PATH と HOME を設定しておかないと いけない。

あとは WinCVS というのを 使うと GUI も使える。試してみてもいいかもしれない。

それと Cygwin を使う方法もある。これは結構安全だ。

ただしいずれにしても CVS のログなどには日本語は使えないと 思ったほうがいい。管理されるほうのデータだけにすべきだ。 またその場合も文字コードを混ぜないように自分で注意する必要がある。

CVS レポジトリをローカルに持つ

最近は ADSL も随分普及してきたけども、まだダイヤルアップに苦しめ られている読者も多いだろう。アナログモデムで CVS アクセスしていると 速度が遅くて嫌になるし、ふと cvs diff したくなった、なんてときに 接続に時間がかかるのも嫌だ。

それを打開する方法として cvsup がある。cvsup を使うと、ワーキング コピーではなくレポジトリ自体をまるごとコピーしてくることができてしまう のだ。これはいい。なにしろレポジトリが手元にあるわけだからネットワーク アクセスは最初の cvsup の時だけで済む。 cvsup のソースコードは archives/cvsup-16.1f.tar.gz に収録した。

ところでこの cvsup を自分でコンパイルするには module-3 コンパイラが 必要なのだが、オープンソースの module-3 コンパイラ pm3 が洒落に ならないほどデカい。なんでか知らないが 300MB くらいある。これが 長いこと cvsup 導入のボトルネックになっていたのだが、 最近になって ezm3 というパッケージが登場した。 これは pm3 のうち cvsup に必要な部分だけをまとめたパッケージ であり、数メガの単位で済む。CD-ROM にはこの ezm3 も収録した。

だが、家の細い回線では 1 メガでも耐えられない、という読者もいるだろうし、 なにより cvsup には Windows 版クライアントがない。そこで次善の策として 2002-11-01 日付のレポジトリを収録してある。レポジトリ自身が 古いわけだから本当の最新ではなくなってしまうが、ソースコードを過去に 戻って調べたりするにはこれで十分だろう。CD-ROM のトップにある repository.tar.gz がそれである。 使いかたは単に展開するだけだ。以下、CD-ROM ドライブの マウントポイントを /mnt/cdrom として簡単な例を書いておく。

% mount /mnt/cdrom                        # 添付CD-ROMをマウント
% tar zxf /mnt/cdrom/repository.tar.gz -C ~/ruby-cvs  # レポジトリを~/ruby-cvs/に展開
% umount /mnt/cdrom                       # 添付CD-ROMをアンマウント
% cvs -d ~/ruby-cvs/ruby checkout ruby    # ワーキングコピーをチェックアウト

-d がレポジトリの指定である。

ruby でのブランチの使いかた

※ ブランチについては他の CVS の本やマニュアルを参照のこと。

現在はメイントランクで開発版、一本ブランチして安定版、 というよくあるパターンを使っている。もっとも ruby 1.2 あたり までは「ブランチのブランチのブランチ」くらいまであって厄介である。 実はこのへんは筆者もよく把握していない。それ以前の変更を調べる ときはリリース版を全部展開しておいて直接 diff していた。 (個人のレポジトリにチェックインしておくと便利かもしれない。)

CVS を使った調査

CVS を使うからには昔の姿を見たり「ここはいつ変わったんだ?」 ということを調べないと価値がない。ソースコードを調べていくうえで 役に立ちそうなコマンドだけ精選して書いておこう。

CVS コマンドは「cvs + サブコマンド」の形で通常のコマンドの ように使う。例えば「cvs diff」や「cvs update」のように。 そして長いサブコマンドには省略形が用意されている。 例えば「update」なら「up」でよい。

昔の版を取り出す

# 凡例
cvs update -rリビジョン [ファイル]    # 省略形は up

# 例
~/src/ruby % cvs up -r1.24 gc.c

これで gc.c がリビジョン 1.24 のものになる。 現在の版との違いを知りたいだけなら次の項の cvs diff を使うほうがよい。 また最新版に戻すときはリビジョンを -A を使えば リビジョンを指定する必要はない。

cvs up -A gc.c   # gc.cを最新版に戻す

昔の版との差分を取る

# 凡例
cvs diff -rリビジョン [ファイル]    # 省略形は di
cvs diff -D日付 [ファイル]

# 例
~/src/ruby % cvs di -r1.24 gc.c         # gc.c 1.24から現在までの差分を取る
~/src/ruby % cvs di -D2002-05-03 gc.c   # 2002年5月3日から現在までの差分を取る

昔の版同士の差分を取る

# 凡例
cvs diff -rリビジョン -rリビジョン [ファイル]    # 省略形は di

# 例
~/src/ruby % cvs di -r1.23 -r1.24 gc.c    # 1.23から1.24での変更を見る

ちなみに diff の省略形は di。

ファイルがいつ変更されたのか調べる

# 凡例
cvs annotate [ファイル]     # 省略形は ann

# 例
~/src/ruby % cvs ann gc.c

この例では次のような出力が得られる。 一番左の数字がその行が変更されたリビジョンを示す。

1.15         (matz     01-May-00): /**********************************************************************
1.1          (matz     16-Jan-98): 
1.1          (matz     16-Jan-98):   gc.c -
1.1          (matz     16-Jan-98): 
1.77         (matz     19-Nov-01):   $Author: aamine $
1.89         (nobu     07-Mar-02):   $Date: 2002/12/08 11:35:22 $
1.1          (matz     16-Jan-98):   created at: Tue Oct  5 09:44:46 JST 1993
1.1          (matz     16-Jan-98): 
1.84         (matz     11-Jan-02):   Copyright (C) 1993-2002 Yukihiro Matsumoto
1.15         (matz     01-May-00):   Copyright (C) 2000  Network Applied Communication Laboratory, Inc.
1.16         (matz     09-May-00):   Copyright (C) 2000  Information-technology Promotion Agency, Japan
1.1          (matz     16-Jan-98): 
1.15         (matz     01-May-00): **********************************************************************/
1.1          (matz     16-Jan-98): 
1.1          (matz     16-Jan-98): #include "ruby.h"
1.2          (matz     13-Aug-99): #include "rubysig.h"
1.1          (matz     16-Jan-98): #include "st.h"
1.1          (matz     16-Jan-98): #include "node.h"
1.1          (matz     16-Jan-98): #include "env.h"

由来を知りたいコードを見つけたら cvs ann でその行が変更された リビジョンを調べ、そのリビジョンで加わった変更を cvs diff で見る。 さらに同日の ChangeLog を見てみる。というのが履歴調査の定石である。

チェックインの粒度

最後に、CVS を使った開発の話についてもちょっとだけ触れたい。 CVS を使った開発と言っても話題はいろいろあるけけども、ここで 話すのはその中でもチェックインの粒度についての話だ。

バージョン管理システムというのは名前の通り、特定ファイルの いろいろなバージョン (普通は時系列順) を管理するシステムだ。 だがそのバージョンはこちらから明示的に「チェックイン」しなければ 変わらない。面倒だからと言って一ヶ月に一度しかチェックイン しなければ、例え毎日変更していてもバージョン管理システムにとっては 一ヶ月に一度しか変更していないのと変わらなくなってしまうわけだ。

では、どのくらいの頻度でチェックインすればいいのだろうか。 あまりチェックインを怠けすぎるとバージョン管理システムを 使っている意味がほとんどなくなってしまう。しかし逆に細か すぎても困る。例えば一文字追加するごとにチェックインしたら 何がなんだかわからなくなるだろう。

この細かさには個人によってかなり流儀が違うようだ。例えば一日の 最後に一つのプロジェクトのファイルをまとめてチェックインすると いう流儀がある。この方式はわりと気楽なわりにそこそこ実用的である。 しかし「キリの悪いところでチェックインされてしまうことがある」 「何を変更したのか思い出すのが面倒 (その結果、変更を記録し忘れる)」 という欠点がある。

また「少し変更したら即座にチェックイン」という流儀もある。 この方式を使う場合、後から変更を追うのが非常に簡単で、 バージョン管理システムの価値は最大になる。しかしバージョン 管理自体に人間がそれなりに手間をかけてやらなければならず、 それなりに几帳面な人でないとできないかもしれない。

その中間をとって「なんとなく変更がまとまったらチェックイン」 という流儀もある。なんだかんだ言ってたいていの人はここらへんに 収まるのではなかろうか。この方法だと利点も欠点も二つの極端の 中間くらいになる。

ちなみに筆者の場合は「可能な限り細かくチェックイン」派である。ただし それができるのは几帳面だからではなく、ちょっと特殊な事情のせいだ。 と言うのは、筆者はマルチバッファとかマルチウィンドウが嫌いなので、 しょっちゅう vi を起動したり終了したりする (してしまう)。そうすると、 プロセスを越えてアンドゥは効かないのでチェックインしておかないと 元に戻せなくなるのである。戻せないということは恐くて変更できないので、 ここらでチェックインしておこうかな、という心理が働く。

まあそんな筆者の特殊事情は参考にならないので置いておこう。 ずばり読者にはどれがお勧めかというと、「それができるならば、」 可能な限り細かくチェックインするのが一番よい。 ついでにそのタイミングでユニットテストを動かすともっといい。 「そんなの時間の無駄」と思われるかもしれないが、よくよく自分の やってることを観察すれば、その程度の時間は絶対余っているはずである。 それに、慣れればチェックインしまくるのが一種の快感になってくる。 XP の気持ちよさと少し似ているかもしれない。

Copyright (c) 2002 Minero Aoki <aamine@loveruby.net>