CVS について一言で説明するのは私の手に余るのと、Web 上には他にいくらでも良い解説が沢山見つかると思うので、ここでも申し訳程度の説明に留めておきます。
RCS などと同じく版管理のためのソフトウェアです。 RCS との違いは、CVS が複数の開発者の開発に便利な仕組を備えていることです。 これを応用すると、一人であっても、職場と自宅など複数の計算機で頻繁にファイルを書き換えたりする場合にファイルの整合性を保つのに使えたりします。
RCS との大きな違いは、ファイルの内容や差分などの情報をリポジトリ(貯蔵庫)と呼ばれるディレクトリに格納 (import) し、それを CVS を通じて管理する所です。 そしてそのプロジェクトの開発をする際には、リポジトリから必要なファイル群を作業ディレクトリ(これは他の計算機でも構わない)に checkout し、そこで修正を加えるなどした後、それを CVS を通じてリポジトリに反映させます (commit)。 従って RCS と違って、以後作業するには checkout が必要になりますし、そのディレクトリは当初 import した際の作業ディレクトリと違っても構いません。 なお、作業ディレクトリの内容は update で最新の状態にすることができます。
上のような仕組で、複数による開発が可能になるわけです。 従って異なる人が同時に同一ファイルを修正することもできるので、場合によっては衝突が起こり得ます。 この場合も CVS は可能な限りその衝突を解消しようとしてくれますが、 それが無理な場合は手作業で修正することになります。
また、CVS は RCS と違って基本的には cvs という単独の実行ファイルからなります。 これに cvs コマンドと呼ばれる引数を与えることで、様々な動作をさせることができます。 詳しくは以下の使用例を参照していただくとして、基本的には
cvs[global option]cvsコマンド[option][cvsコマンドの引数]
という感じで使うことになります。 各 cvsコマンドにどんなオプションがあるかは、
cvs--helpcvsコマンド
とすると表示されます。
cvs コマンドには次のようなものがあります。
| cvs コマンド | 動作 | 
|---|---|
| init | リポジトリ作成 | 
| import | 新規プロジェクトの作成 | 
| update | 作業ディレクトリを最新状態に | 
| commit | リポジトリへの修正反映 | 
| add | リポジトリへのファイルの追加予約 | 
| remove | リポジトリからのファイルの削除予約 | 
| diff | リポジトリと作業ディレクトリの差分表示 | 
| rdiff | パッチ用の差分作成 | 
| release | checkout のキャンセル | 
| export | 単なるリポジトリからのファイル抽出 | 
| history | リポジトリへの変更履歴 | 
| admin | リポジトリの管理 | 
| status | 状態を表示 | 
| log | ログ表示 | 
| tag | 標識タグ追加 | 
| rtag | 特別な版に標識タグ追加 | 
ここでは個人で CVS を使う際の例を書きます。 (私がそういう使い方をしたことしかないため。) 実際にはもちろん、複数の人がネットワークを通して共同作業するための便利な仕組が沢山あります。 それについてはもっと他のウェブサイトなり本なりをお読み下さい。
なお CVS のインストールなどは済んでいるものとします。
まずは cvs のルートディレクトリの場所を決めます。
ここには作成する各モデュールやその差分などが収められるので、
それに応じた容量を持つ領域を選んでおく必要があります。
例えば ~/cvs というディレクトリを作ってその下に置くことにしたとします。
後々のためにこのルートディレクトリを環境変数などで設定しておきましょう。
例えば bash を使っている場合は、.bashrc に
export CVSROOT=/home/foo/cvs
などと書いておくことになります。
この環境変数が設定されている状態で、init コマンドを使って
cvsinit
とすると cvs のルートディレクトリを作成することができます。
成功すれば ~/cvs の下に CVSROOT という名前のディレクトリが作成され、その下にいろいろなファイルができているはずです。
cvs -d ~/cvs init
みたいにすれば、環境変数が設定されていなくても直接場所を指定できます。
他のローカルな計算機でも作業する場合には、外部の計算機のディレクトリを指定することになります。 この場合、次のような感じで環境変数を設定することになるでしょう (bsh 系の場合)。
CVSROOT=:ext:foo@bar.org:/home/foo/cvs RCSINIT=-LT CVS_RSH=ssh export CVSROOT RCSINIT CVS_RSH
上は、ネットワーク上で bar.org という fqdn で表される計算機に foo というアカウントを持っていて、その計算機の /home/foo/cvs を CVS のルートにする場合です。
RCSINIT=-LT は rcs のオプションの指定で、
厳密なロックを使用し、各版でのタイムスタンプを保持するようにするものです。
また、CVS_RSH=ssh は、リモートシェルとして ssh を利用する指定です。
基本的には次のような感じで使うことになります。
cvsimportリポジトリ ベンダー名 リリースタグ
この場合、カレントディレクトリ以下の(サブディレクトリを含めた)全てのファイルの情報が、CVS のルート以下のリポジトリの下に保存されます。
      リポジトリには、cvs のルート以下のどのディレクトリにファイルや差分情報を保存するかを指定します。例えばここを  project_a とした場合は、もし cvs のルートが
      ~/cvs であれば、~/cvs/project_a というディレクトリにファイルの内容などが保存されます。
      
私の場合 foo/bar の様にディレクトリに階層を付けていることも多いです。 この場合 checkout する際に気をつけて下さい。
import して cvs の管理下に置いたプロジェクトに以後修正を加えていくには、cvs コマンドの checkout を利用して作業ディレクトリを作成しなければいけません。
基本的には
cvscheckoutモデュール
という感じで取り出すことになります。 モデュール名の所はリポジトリにおける cvs のルートからの相対パスで指定することもできるので、ここではそうします。 (いくつかのディレクトリをまとめて一つのモデュールを定義することもできると思うのですが、良く知らないので、ここではそういう話は省略します。)
このまま何も指定しない場合は、カレントディレクトリ以下に指定したリポジトリからファイルが展開されます。 例えば foo/bar というリポジトリを指定すれば、foo/bar というディレクトリができて、その下にファイルが書き出されることになります。
作業ディレクトリ名をリポジトリのパスと異なる名前にしたい場合は、
cvscheckout-d ディレクトリ名モデュール
のように -d オプションを使って作業ディレクトリ名を指定します。
複数の人が作業したり、あるいは一人であっても複数の計算機で作業したりした場合は、
リポジトリがその作業ディレクトリよりも新しい状態になっている可能性があります。
(cvs ではこういう状況は当たり前にあります。)
この場合、作業を始める際にはディレクトリの状態を最新の状態にしておくべきでしょう。
それには updateコマンドを使います。
cvsupdate[files | directory] ...
とします。
最後の所で file やディレクトリを指定しなければ、カレントディレクトリが対象になります。
すると、リポジトリと比較しての作業ディレクトリにあるファイルの状態がずらずらと表示されます。 状態は次のような記号で表示されます。
| 記号 | 状態 | 
|---|---|
| U | 最新状態(Up to date)に更新された | 
| P | Patchが当てられた(結果は U と同じ) | 
| M | 修正(Modify)された | 
| A | 追加(Add)された(必要なら commit すべき) | 
| R | 削除(Remove)された | 
| C | 衝突(Conflict)が起きている | 
| ? | リポジトリにないファイル | 
少し補足します。
C マークが付いている場合は、衝突が起きています。それは手で解消しなければなりません。
また ? マークですが、作業ディレクトリにある全てのファイルをリポジトリに反映させたいとは限りません。 そういう場合、上の表の ? がついたファイルが出てくるわけです。
これが欝陶しい場合は、.cvsignore が使えます。
これは、ホームディレクトリや作業ディレクトリに .cvsignore というファイルを作って無視したいファイルの名前を書いておくと、
cvs がそのファイルを無視してくれるというものです。
もちろんremove, addの所に書いたように add しなければ、勝手に新規ファイルが追加されることはないのですが、update の度に ? マークが並ぶと見づらいです。
こういう場合、
ワイルドカードも使えます。
もし add したファイルが commit でリポジトリに反映されないままになっていた場合は A が表示されます。
commit するよう促してくれるわけです。
作業ディレクトリで更新したファイルをリポジトリに反映させるには、commit コマンドを使います。
作業ディレクトリで、
cvscommit
とするか、引数で作業ディレクトリを指定すれば、修正内容がリポジトリに反映されます。
通常はエディタが開いて、修正内容の概略を入力するよう求めてきますが、
cvs commit -m "コメント" とすれば、コマンドラインでその内容を指定することができます。
作業中に特定のファイルを破棄したくなったり、逆に新規ファイルを追加したくなった場合は、remove や add コマンドを使います。
remove の方は既にファイルを削除した状態でないと使えません。
また、これらのコマンドだけではリポジトリには反映されません。
commit して初めてリポジトリから削除ないしは追加されます。
特定のリビジョンとの差分情報は diff コマンドで見ることができます。
cvsdiff-D "November 08, 2001"file1.tex
などとすれば、revision だけではなく日時でも指定できます。この日付の指定方法はいろいろあって、次のようなものが全て許されます。
2002-11-12 12:00 3/31/92 10:00:07 PST January 23, 1987 10:05pm 22:00 GMT 1 day ago 1 month ago 2 hours ago 400000 seconds ago last year last Monday yesterday a fortnight ago
作業のためではなく、単にファイルを取り出すには cvs コマンドの export を使います。
diff の場合と同様に、特定のリビジョンを指定することで、
過去のバージョンを取り出すこともできます。
日時でも指定できるので便利です。
日時の指定方法も diff と同じです。
作業を全て終了して commit も終えた場合、作業ディレクトリを全て削除してしまっても構わないですが、
このような場合この作業ディレクトリでの作業が終了しましたということを cvs に伝えるために、
release という cvs コマンドを使います。