■第1章 CVSとは? ■■1.1 CVSって何? ■■■1.1.1 CVSのお仕事 「CVSという言葉は、Concurrent Versions Systemの略です」といわれても、よくわからないですね。日本語に直訳すると、並列版管理機構でしょうか。複数の人と共同でファイルを編集する場合に、ファイルの版を管理するシステムという意味です。順を追って説明しましょう。 CVSはもともとプログラム開発のためのツールとして開発されました。みなさんはプログラムを書かれたことはありますか? プログラムというのは徐々に成長していきます。ちょっとコードを書いて動かして、動いたら次へという形で作業が進んでいきます。そして、動かしてみてうまくいかなかったら、ある程度動いていた以前の状態へ戻ってまた別の方法を試すということもちょくちょくあります。このとき、今までのプログラム作成の履歴が残っていなかったら不便ですよね。かといって、途中のファイルを別々に名前を変えて残しておいたら、それだけですごい量になってしまいますし、混乱してしまいます。このような途中のファイルの状態をバージョン(version=版)と呼びます。しかし、これはソフトウェアのリリースのバージョンと紛らわしいので、リビジョン(revision=改訂版)と呼ぶこともあります。RCS(Revision Control System)やSCCS(Source Code Control System)と呼ばれるツールは、このようなバージョンの間の「違い(差分といいます)」だけを取り出し、1つのファイルの形で管理するツールとして開発されました。差分のイメージを【図1.1】に示しましょう。 【図1.1】差分を管理する(RCS) 第1版から第2版、第2版から第3版へと変化したとき(図の左)、それぞれの違いが差分として出てきます(図の真ん中)。RCSでは、この差分をどんどん1つのファイルに追加していきます(図の右側)。RCSは利用者からあるファイルのある版を求められるとこのファイルから必要な分の差分を取り出し、その版を構成する作業をおこないます。 CVSは、RCSをもっと使いやすくするために開発されました。どう使いにくかったかというと、プログラムが大きくなりいくつかのディレクトリに分かれたたくさんのファイルから構成されるようになると、バージョンを管理するファイルがばらばらになってしまいややこしくなったのです。また、そうした大きなプログラムは一人だけで開発するのではなく複数の人間が協力して開発することが多く、RCSの機能であるファイルの排他制御(ある人が編集中は他の人は編集できない)だけでは問題が発生するようになったからです。CVSではリポジトリ(repository=貯蔵庫)という場所にバージョン情報を保管しておいて、開発者は各自そこからコピーをとりだしてそのコピーに対して作業を行い、気が済んだら新しいバージョンとして登録(commitといいます)することができます。これで、他の人の作業とぶつかることがかなり避けられます。図1.2にその作業の様子の概念図を示します。なんとなく分かって頂けたでしょうか。 【図1.2】CVSのイメージ図 ■■■1.1.2 CVSの歴史 ★編注:/usr/doc/cvs-1.11.0/READMEのCredits:という箇所により詳しい記述がある。 ★編集:参考にしてください。 CVSの原型を開発したのは、Dick Gruneさんという人です。 インターネットは今でこそWWWの別名のようになってしまいましたが、WWWが普及するずっと前からNetNewsという巨大な掲示板機構がありました(もちろん今でもあります)。そのNetNews上にプログラムを投稿するためのcomp.sources.unixという場所があります。Gruneはこの場所に現在のCVSの元となるシェルスクリプト群を投稿しました。1986年12月のことです。彼の書いたシェルスクリプト群は今のCVSの内部にはまったく残っていませんが、衝突回避などのアルゴリズムは継承されています。このGruneの投稿をもとに、開発がずっと続いてきました。 1989年4月、Brian BerlinerさんがCVSを設計・コーディングし、その後、Jeff PolkさんがCVSのベンダー枝とモジュールというCVSの機能(後段で説明します)の設計を助けました。1990年代初期には当時Cygnus Solutions社にいたJim Kingdonさん(のち、Cyclic Solusion社に所属)がCVSをネットワークに対応させました。現在では、CVSHome.orgを中心に世界中の有志開発者により、このプログラムの保守・管理がなされています。 ちなみに、UNIXの世界にはRCSが開発される前にdiffというファイルの差分を抽出するツールが出回っていました。RCSはこのdiffを利用しています。CVSはRCSを利用し、CVSはさらにcvswebやCVSupなどというツールから利用されています。このようにオープンソースの世界では、積み重ねが着実に大きな成果になっていきます。とても面白いですね。 ■■1.2 何の役に立つの? ■■■1.2.1 CVSのできること ■■■■プログラムの開発・利用に使おう! 元が、プログラム開発のためのツールなので、当然プログラム開発には、すばらしく役に立ちます。特に、オープンソースの世界では無くてはならないツールとなっており、オープンソースソフトウェアの開発に参加・協力したり、参加・協力しないまでも最新のソースコードを利用したいだけという場合にも利用でき、たいへん便利です。 たとえ、最新のソースコードを利用するというだけでも、「人柱として参加・協力している」ことになるので、ぜひ利用してください。 ■■■■テキストファイルの管理に使おう! その他に、テキストファイルの管理一般に利用することはできるでしょう。例えば、Webページなどです。diffが元々テキストファイルを対象としていたので、画像などのバイナリファイルの扱いにはあまり向いていませんが、リポジトリに登録することはできます。CVSを日々のバックアップとして運用する分には問題ないでしょう。 ■■■■大事なデータのバックアップに使おう! CVSを日々のバックアップとして利用する場合、特に次のような場合に役に立つと思われます。移動が多く、移動先で仕事をする人や、家と会社に作業環境がある人など、いくつかのコンピュータで同じファイルを編集する必要がある場合、つまり、一人で複数環境を持つ人は、自分でおこなった並列作業の管理をCVSですると楽になるでしょう。無論、複数の人が関わる作業でその真価を発揮することは言うまでもありません。 Column オープンソースソフトウェアとは ソースコードを広く公開し、ユーザ自身がバグ修正や改良をおこなえるようにしているソフトウェアのことです。FreeBSDに代表されるBSDライセンスのソフトウェアやこのCVS自身が属するGPLというライセンスのソフトウェアなど様々なものがあります。 ■■■1.2.2 CVSのできないこと できないとこも書いておきましょう。CVSの付属マニュアルで挙げられている項目について、筆者なりに説明してみます。 ■■■■CVSは構築システムではありません 主にプログラミングでの話なのですが、複数のファイルからなるプログラムの場合、コンパイルをして1つのプログラムに組み上げる「構築(ビルド)」という作業が必要になります。CVSはこの構築作業を助けてくれたりはしません。構築作業を助けてくれるツールとしてはmakeというプログラムが有名です。これもGNUのフリーウェアにありますので、興味があれば触られてみるとよいでしょう。なお、makeの文献としては、本書の姉妹書となる『入門Make&RCS』を挙げておきます。 一般的に、プログラムの中のソースコードファイルは別のファイルに依存しています。この依存関係の端からコンパイルをおこなって、マシン語に変換し、最終的に1つのプログラムに組み上げるのです。あるファイルが変更された場合、全てのファイルをコンパイルするのではなく、変更されたファイルとそれを組み込む部分のみをコンパイルする方法が取られます。そのために必要な作業をCVSがすることはありません。このようなときに、makeを使います。makeは、「依存関係」と、「依存関係に沿ってプログラムを構築するために何をすればよいか」を記述したMakefileというファイルを参照しながら動作します。 このMakefileはプログラマがえっちらおっちら書かないといけないのですが、依存関係についてはまた別のツールを用いて生成することもできます。例えば、Cのプログラムだと、makedependというプログラムが、includeしているファイルを調査し、開発者に教えてくれます。 このようなMakefileがいろいろなディレクトリに作られ、それらが相互に関連した状態にあると、何をするにもプログラム全体を取り出さなければなりません。シェルスクリプトなどを利用する場合も同じです。ディレクトリの独立性を高めて、一部だけ取り出すようにすることも可能ですが、何にしろそんな風に作り込んだりそれを維持するのは結構大変です。CVSはやはりそのへんには全く無関係です。ただ、そうしたMakefileやスクリプトを作った場合にはソースコードと一緒に管理しておくと楽です。 CVSと連係して構築をおこなうための情報は、付属マニュアル(UNIXではinfo cvsと実行し、WinCvsでは「ヘルプ」メニューから「cvs-1.10のヘルプ」を選択することで参照できます)の「構築システムとCVSの関係方法」という章に書かれています。必要な方は参照してください。 ■■■■CVSは管理者の代わりはしません プログラム開発では通常、管理者がいて、プログラムの期日や何をいつおこなうかをプログラマと相談しながら開発を進めていきます。管理者のそうした仕事をCVSがやることはありません。CVSは管理のための道具にはなりますが、道具自身が管理をすることはありません。付属マニュアルでは、CVSを楽器、プログラマを演奏者にたとえています。 ■■■■CVSは開発者の間の意思疎通をとりもったりしません あるファイルを複数の人が編集しているとコンフリクト(conflict=競合)が起こることがあります。競合という言葉自体の意味は、同じファイルに加えられた二つの変更がとても近くにあるために、CVSがどちらを選んでよいかわからない状態になっているということです。細かいことをいえば、mergeコマンド(つまりdiff3コマンド)が混乱しちゃうほど変更が近くにあるということです。CVSは競合を検出しますが、その競合のどちらが正しいのかは結局、関係した人が話し合って調整しないと解決できません。せっかく自分がおこなった変更を、誰か他の人が勝手に元に戻してしまったら、普通怒りますよね。 さらに競合としてCVSが検出しないものもあります。同じファイルもしくはいくつかのファイルに同時に加えられた変更の中に、人間が考えると矛盾すると思うような点があっても、CVSにはわかりません。つまり、プログラムだったら論理的に矛盾しているような変更についても、十分に離れていればCVSにはわからないということです。 例えば、以前からあるファイルの中のある関数Xの引数をある人が変更したとしましょう。同じ時に、他の誰かが他のファイル(同じファイルでも構いませんが...)を編集して、古い引数を使ってXを呼び出したとします。CVSにはその変更の意味はわかりませんし、競合としても検出しません。きっとコンパイル時にエラーが出てびっくりすることでしょう。 競合であれ、そうでない矛盾であれ、CVSが人間に教えることができるのは、変更があったということと変更の内容だけです。このような問題は関係のある人と日頃から良く話し合って解決する必要があるということです。 ■■■■CVSは変更管理(change control)はしません まず、バグ追跡というのを変更管理と呼ぶことがあります。これはプログラム内に発見されたバグの報告とそれらのバグの状態(修正されたか? どのリリースか? 報告者は修正を確認したか?)をデータベースとして管理することです。CVSは、このバグ追跡を行いはしません。バグ追跡システムと連係したい場合には、CVSの管理用ファイルであるrcsinfoとeditinfoまたはverifymsgファイルを利用します。これらのファイルについては後で説明します。 一方、複数のファイルが同時に変更されたことを覚えておくことも変更管理と呼ばれます。例えば、関数への変更とその関数を利用したコードの変更を別々のファイルに対して行ったとき、これは意味的には一つの変更と考えられます。この変更を一括して管理する能力はありません。それらの複数のファイルの変更を一回のcvs commitにより登録したとしても、CVSはそれらのファイルを同時に登録したことを忘れてしまうのです。そして、それらのファイルを同時に登録したことを示す事項は、それらが同じログ・メッセージを持つことだけになります。GNUのChangeLogの形式でそれらをまとめておくという手段は有効です。ちなみに、perlで書かれたcvs2cl.plで同じログメッセージをひとまとめにして取り出し、ChangeLogを生成することができます。このツールについては、別途紹介します。 さらに、各変更の状態(どの変更がどの開発者によって加えられたかとか、その変更が他の開発者によって追試であるとかいった状態のこと)を覚えておく能力を、変更管理と呼ぶこともあります。一般的にCVSでこのようなことをするには、まず、一人patchを当てて登録する人を決めておき、変更した人は(cvs diffやdiffを用いて)差分を生成してその人にメールとして送るということをするようです。これは非常に融通のきく方法ではありますが、CVSの外部で行われるためCVSとしては何の保証もできません。 ■■■■CVSは自動的にテストてくれたりはしません ですが、CVSの管理ファイルである、「commitinfo」ファイルを使えば、どうしても必要だと思われる項目を強制的にテストするように設定できます。commitinfoの設定方法などについては、第6章で詳しく説明します。でも、それが本当に役に立つのかは不明ですけれど。 ■■■■CVSは特定のプロセスモデル(process model)には基づいていません プロセスモデルというのは、ソフトウェアの開発をどのようにおこなっていくかというモデルのことです。プロセスモデルにはウォーターフォールのような伝統的なものから、特殊なものまでさまざまなものがあります。詳しく知りたい人はソフトウェアプロジェクト管理というキーワードで検索してみてください。プロセスモデルにはソフトウェアの変更やリリースにおいておこなわれないといけない、様々な手順や承認事項が定義されます。いくつかの統合開発環境では特定のプロセスモデルに基づいて、その手順を確実におこなうようにしています。 CVSは特定のプロセスモデルに基づいてはいません。CVSを用いてなんらかのプロセスモデルを実現することはできるでしょうが、ちょっと面倒だと思います。commitinfo, loginfo, rcsinfo, verifymsg等の管理ファイルを用いて、ある変更を登録する前には必ずそのプロセスモデルに必要な動作を、おこなうように設定できはするということです。 なお、ブランチ(branch=枝)やタグ(tag)といった機構を用いて、開発用のブランチを用意してその上で実験を繰り返し、十分安定性が証明された変更だけを安定化指向のブランチに統合することは実際良くおこなわれています。例えば、Linuxのカーネル、あるいはFreeBSDはそのシステム全体が、開発ブランチと安定(stable)ブランチにわけられて開発が進められています。 プログラム開発のための話が多かったのでわかりにくかったかもしれません。でも、今から少々大きなプログラムを開発をしようとしてCVSの利用を検討している人にはだいぶイメージが湧いたのではないでしょうか。ひとまず、ここではCVSというものを漠然とイメージして頂ければ幸いです。具体的な使い方については第2章で説明します。 ■■1.3 私でも使えるの? WindowsのGUIしか使ったことのない方の利用は難しいかも知れません。 UNIXのコマンドラインがそこそこ使えるならば、多分大丈夫でしょう。「環境変数」、「サーバ/クライアント」といった言葉がわからない方は、他の本で勉強されてからの方がよいかと思います。 この本では、一応UNIXの基礎知識は持っているという前提の上で、CVSのコマンドラインでの使い方を中心に説明していきます。WinCVSなどのGUIも基本はコマンドラインの命令を利用しているわけですので、コマンドラインの命令が理解できれば、自ずと使い方がわかるかと思います。 あと、これはGNUやLinuxなどのオープンソースには一般的にいえることなのですが、英語のドキュメントに慣れておく必要もあるでしょう。日本語化についても触れますが、CVSのベースは英語です。コマンドもそうですが、エラーメッセージなどどうしても英語が使われています。何かの拍子に突然わらわら英語のエラーメッセージがでてくると、引いてしまうかもしれません。でも、ちょっと我慢してそのメッセージを眺めてみてください。実際、そんなに大したことは書かれていないのです。いつもほとんど同じ単語が使われています。なるべく早く慣れて、面白いツールで遊べるようになってください。