CVS と現実の世界 -----------------------
リファレンス -----------
この章は CVS を一度も使ったことが無く、おそらく以前にバージョン管 理ソフトを使ったことの無い人のためのものです。
既に CVS に親しんでいて、特定の機能を学んだり、特定の命令を覚えよ うとしているときは、ここは全て飛ばしてください。
CVS はバージョン管理システムであり、 あなたのソース・ファイルの変遷を記録するのに使用します。
例えば、ソフトウェアの修正に伴なってバグが入り込み、 発見されるまでに長い時間がかかったとします。 CVS を使っていれば、古いバージョンを簡単に復元し、 バグの原因となった変更点を正確に調べることができます。 この特徴に救われる時が必ずあります。
全てのバージョンの全てのファイルを保存しておくこともできますが、 ディスク容量の無駄使いでしかありません。 CVS は、バージョン間の差分のみを保存する方法により、 各ファイルの全バージョンを一つのファイルに記録します。
CVS は、複数の開発者が同じソフトウェアに 取り組む場合に、真価を発揮します。 このような場合にはよほど気を付けていないと、 他の人が変更したファイルを上書きしてしまいます。 GNU Emacs のようなエディタを使えば、 複数の人が同時に同じファイルを編集することはありません。 しかし不幸なことに、全員が同じエディタを使うとは限りません。 CVS は開発者を互いに隔離することにより、この問題を解決しました。 全ての開発者は自分のディレクトリで作業し、 その仕事を CVS が組み合わせます。
CVS は Dick Grune が作成し、
1986年 12 月に comp.sources.unix の volume 6 に投稿した、
シェル・スクリプトから始まりました。
現在の CVS は、
これらのシェル・スクリプトのコードを全く含みませんが、
衝突解決のアルゴリズムの大部分を受け継いでいます。
1989年 4 月に Brian Berliner が CVS を設計し、コーディングしました。 その後、Jeff Polk が CVS の ベンダー枝とモジュールの設計を助けました。
CVS をインターネットからの自由なダウンロードなど、いろいろな方法 で取得することができます。 CVS のダウンロードや、他の CVS の 話題の情報は、以下のところを参照してください。
http://www.cyclic.com/ http://www.loria.fr/~molli/cvs-index.html
info-cvs という CVS 専門のメーリング・リストがあります。
参加、又は脱退したい場合には、
info-cvs-request@gnu.org にメールを出して下さい。
Usenet グループの方を好むのであれば、正しいグループは
comp.software.config-mgmt で、CVS の議論を
するために適した場所です (他の構成管理システムと一緒で
すが)。 将来は comp.software.config-mgmt.cvs を
作ることも可能かもしれませんが、おそらく
comp.software.config-mgmt に十分な流量があるよう
になったときだけでしょう。
BUGS でより詳細に説明されている bug-cvs メーリン
グリストを講読するともできます。講読するためには、
bug-cvs-request@gnu.org にメールを送ってください。
CVS は多くのことができますが、全ての人に全てのことを するようにはなっていません。
Makefile) とは相互作用するかもしれませんが、本質的
に独立したものです。
CVS は、何かの作り方を指示したりはしません。 CVS はあなたの意思に従って、 ツリー構造から望むファイルを取り出すだけです。
CVS は、checkout 先の作業ディレクトリのディスク容量の使用
法について指示したりはしません。あなたが Makefile やスクリプトを
全てのディレクトリで書き、それらが各々全ての相対的な位置を知る必要があ
るとすると、リポジトリ全てを取り出す必要が生じます。
あなたが仕事をモジュール化し、(Makefile に link,
mount, VPATH等を使用して、)ファイルを共有するよ
うな構築システムを構成すれば、好きな様にディスクの利用
法を決めることが出来ます。
しかしこれら全てのシステムは、 構築と維持に多大な労力が必要なことに、 気を付けなければいけません。 CVS は、このような問題に関して考慮しません。
もちろん、これらの構築システムを支援するための道具
(スクリプト, Makefile 等) は、
CVS の管理下に置くと良いでしょう。
何らかの変更があった際に、再構築が必要なファイルを調べるのは、
やはり CVS の守備外です。
伝統的な手法の一例をあげると、
構築には make を用い、
make に必要な依存関係は自動化されたツールを用いて生成します。
CVS と結合して構築を行うための情報は Builds
を参照してください。
CVS は、あなたの調律に従ってソースを踊らせる楽器の
ようなものです。あなたは楽器奏者もしくは作曲者のような
ものです。どんな楽器も勝手に演奏をしたりしないし、音楽
が勝手に書かれたりもしません。
同じファイル (もしくはファイルの集合) に、
同時に加えられた変更に論理的な衝突があっても、
CVS には分りません。
衝突という概念は単に文字列の比較によるもので、
同じファイルを基に加えられた二つの変更が、
merge コマンド (つまり diff3) を驚かせるのに
十分なほど近接している場合にのみ生じます。
CVS は、 プログラムの論理に、文字列でない衝突や、散らばった衝突 があったとしても、警告を表示しません。
例:
あなたは A で定義された関数 X の引数を変更したとします。
同じ時に、誰かが B を編集して、
古い引数を使って X を呼び出したとします。
これは CVS の能力の範囲外です。
仕様書を読み、同僚と話し合う習慣を付けましょう。
rcsinfo と editinfo ファイルを見て下さい
(see Administrative files)。
論理的には一つと考えられる変更のため、
複数のファイルが同時に変更されたことを覚えておくことも、
変更管理と呼ばれます。
複数のファイルの変更を一つの cvs commit により格納した場合、
CVS はそれらのファイルが同時に格納されたことを忘れてしまいます。
そして、それらのファイルを結ぶ事柄は、
同じログ・メッセージを持つことだけになるのです。
GNU 形式の ChangeLog を用いれば何らかの助けになるでしょう。
各変更の状態を覚えておく能力を、変更管理と呼ぶシステムもあります。
開発者によって加えられた変更もあれば、
他の開発者によって追試中の変更もあるとか、そういったことです。
一般的に CVS でこのようなことをするには、
(cvs diff や diff を用いて) 差分を生成し、
patch を当てる人物にメールとして送ります。
これは非常に融通のきく方法ですが、
CVS 以外の機構に依存しているので、
問題が無いことを保証できません。
commitinfo ファイルを使えば、
強制的に必須の項目を検査することは可能だと思います。
しかし、
そんなことをしようとしたプロジェクトのことは聞いたことがありません。
commitinfo, loginfo, rcsinfo, verifymsg
等のファイルを用いて、変更点を格納する前に、
必要な手順を確実に踏むように設定できるでしょう。
また枝やタグといった機構を用いて、
開発用の枝で仕事を実行し、
安定性が証明された確実な変更だけを
安定化指向の枝に統合することも考えられます。
CVS を紹介する方法として、CVS を使って典型的な仕事をしてみま す。最初に理解すべきことは CVS は全てのファイルを中央に集められた リポジトリ (repository) (see Repository) に保存すると いうことです。この節ではリポジトリは準備されていると仮定します。
あなたの仕事は単純なコンパイラを作成することです。ソースは少しの C言語
で書かれたファイルでできていて、Makefile を含んでいるとします。
このコンパイラを tc (Trivial Compiler) と呼ぶことにします。そし
て tc というモジュール名でリポジトリに登録されています。
まず、tc のソースの作業コピーを取ってくることから始めましょう。
これには checkout コマンドを使用します:
$ cvs checkout tc
とすると tc という新しい作業ディレクトリが作られ、
その中にソース・ファイルがコピーされます。
$ cd tc $ ls CVS Makefile backend.c driver.c frontend.c parser.c
CVS というディレクトリは CVS が内部的に使用
します。普通はその中にあるどんなファイルでも修正したり
削除してはいけません。
で、あなたの好きなエディタを用いて backend.c をハックして、
数時間後にコンパイラの最適化経路を加えたとします。
RCS と SCCS の利用者への注意: 編集したいファ
イルをロックする必要はありません。その説明は、 See Multiple developers.
あなたはコンパイラが相変わらずコンパイル可能であることを確認し、
backend.c の新しいバージョンとすることに決めました。これは新し
い backend.c をリポジトリに格納し、同じリポジトリを使っている他
の人が使用できるようにします。
$ cvs commit backend.c
CVS はログ・メッセージを記すためにエディタを開きます。 そこで "Added an optimization pass." などと入力し、 一時ファイルに保存し、エディタを終了します。
どのエディタが開かれるかは環境変数 $CVSEDITOR により決定されま
す。$CVSEDITOR が設定されておらず、環境変数 $EDITOR が設
定されていれば、これを使用します。$CVSEDITOR と $EDITOR
の両方が設定されていなければ、オペレーティングシステムに依って違ったデ
フォルトが使われます。例えば、unix では viで、Windows NT/95 で
は notepad です。
加えて、CVS は $VISUAL 環境変数も調べます。この動作が望ま
しいか、また CVS の将来のリリースが $VISUAL を調べるべきか
どうか、という意見は人によって異なります。$VISUAL が設定されて
いないか、$EDITOR に設定されていることを確実にすることで、どち
らになっても対処することができます。
CVS がエディタを開始したときは、修正されたファイルのリストを含ん
でいます。CVS のクライアントでは、このリストはファイルの修正時刻
を、最後にファイルを得た時刻か更新された時刻と比較したものに基づいてい
ます。ですから、ファイルの修正時刻が変わっているけれど内容が変更されて
いないというときも、修正されたものとして表示されます。これに対する最も
簡単な対処法は単純に気にしないことです--それを commitすると、CVS
は内容は修正されていないことを発見し、無修正ファイルであるとして扱いま
す。次の updateはファイルが無修正であるという事実に基づき、将来
のセッションでファイルが表示されないように、タイムスタンプを保存されて
いるものに設定し直します。
わざわざエディタを開くのが嫌ならば、代わりにコマンド行の -m フ
ラグを使うことでログメッセージを以下のように指定することができます:
$ cvs commit -m "Added an optimization pass" backend.c
他の仕事に取りかかる前に、tc の作業コピーを消去することにしました。も ちろん、次のようにしても可能です
$ cd .. $ rm -r tc
しかし、release コマンドを使用するほうが良いでしょう
(see release):
$ cd .. $ cvs release -d tc M driver.c ? tc You have [1] altered files in this repository. Are you sure you want to release (and delete) directory `tc': n ** `release' aborted by user choice.
release コマンドは、あなたの修正が格納されているかどうか確認し
ます。ログを記録する設定ならば、ファイル history にメモします。
See history file.
release コマンドに -d フラグを使用すると、
確認と同時に作業コピーを削除します。
上の例では、release コマンドが何行か出力しています。
? tc は CVS が tc というファイルを知らないという意味です。
モジュール tc のことではなく、
生成したコンパイラ tc を指しており、
これはリポジトリに格納しなくて良いので無視して構いません。
この警告を消すための情報は cvsignore 参照。
release の出力の詳細な説明は release output 参照。
M driver.c の方は重要です。
これは、driver.c というファイルに加えた修正が、
格納されていないことを指摘しています。
release コマンドは、常に作業コピーの
修正が加えられたファイルの数を報告した後、
ファイルを削除したり履歴ファイルにメモする前に、
その確認を求めてきます。
ここでは大事を取って、最後に release が確認を求めたときに
n <RET> を入力しました。
あなたは driver.c に加えた修正を覚えていなかったので、
何をしたのか調べる必要があります。
$ cd tc $ cvs diff driver.c
このコマンドは diff を実行して、取り出した時と、あなたの作業コ
ピーの driver.c のバージョンを比較します。その出力を見て、最適
化経路を有効にするオプションを、コマンド行で指定できるようにしたことを
思い出しました。その変更を格納して、このモジュールに対する作業を終了し
ます。
$ cvs commit -m "Added an optimization pass" driver.c Checking in driver.c; /usr/local/cvsroot/tc/driver.c,v <-- driver.c new revision: 1.2; previous revision: 1.1 done $ cd .. $ cvs release -d tc ? tc You have [0] altered files in this repository. Are you sure you want to release (and delete) directory `tc': y
CVS のリポジトリ (repository) は、 バージョン管理の対象となる全てのファイルとディレクトリの、 完全なコピーを保管します。
通常、リポジトリ中のファイルを直接利用することはありません。 その代わりに CVS コマンドを使用して、 作業者自身のファイルのコピーを 作業ディレクトリ に取り出し、そのコピーを用いて作業します。
そして一連の変更が完了したときに、変更点をリポジトリに書き戻します (も しくは 格納 します (commit))。リポジトリは、変更を加えたも のと同じになり、また同時に変更点や、変更日時などの情報も正確に記録され ます。リポジトリは作業ディレクトリのサブディレクトリやその逆ではないこ とに注意してください。別の位置にあるべきです。
CVS は様々な方法でリポジトリを利用することができます。
リポジトリは、使用中のコンピュータ内であってもいいし、
別の部屋のコンピュータや、別の国のコンピュータであっても構いません。
リポジトリに接続する方法を区別するために、
リポジトリの名前の最初に接続経路 (access
method) を加えることがあります。例えば :local: は、リポジトリ
であるディレクトリを利用することを意味します。つまり
:local:/usr/local/cvsroot で表されるリポジトリは、CVS を実
行したコンピュータの /usr/local/cvsroot というリポジトリを意味
します。他の接続経路については Remote repositories 参照。
接続経路の指定が省略され、リポジトリに : が含まれない場合には、
:local: が仮定されます。
: が含まれていた場合には、
:ext: か :server: が仮定されます。
例えばリポジトリ /usr/local/cvsroot が同じコンピュータ内にある場合、
:local:/usr/local/cvsroot を省略して
/usr/local/cvsroot と記述しても構いません。
しかし(Windows NT などで)、
リポジトリが c:\src\cvsroot にある場合、
:local:c:\src\cvsroot として、
接続経路を明示する必要があります。
リポジトリは二つの要素から構成されます。
$CVSROOT/CVSROOT には CVS の管理用ファイルが置かれます。
その他のディレクトリには、使用者が定義したモジュールの実体が置かれます。
CVS にリポジトリの場所を教えるには、
いくつか方法があります。
一つ目はコマンド行で、
-d ("directory" を示します) オプションを用いて
指定する方法です:
cvs -d /usr/local/cvsroot checkout yoyodyne/tc
二つ目は、環境変数 $CVSROOT に、
絶対パスでリポジトリを指定する方法です。
例では /usr/local/cvsrootです。
csh や tcsh のユーザは各々
.cshrc や .tcshrc に次の行を加えて下さい:
setenv CVSROOT /usr/local/cvsroot
sh や bash のユーザは各々
.profile や .bashrc に次の行を加えて下さい:
CVSROOT=/usr/local/cvsroot export CVSROOT
-d によるリポジトリの指定は、
環境変数 $CVSROOT よりも優先されます。
一旦リポジトリから作業コピーを取得すれば、
リポジトリの場所が記憶されます
(この情報は、作業ディレクトリ内の
CVS/Root に記録されます)。
オプション -d とファイル CVS/Root は、
どちらも環境変数 $CVSROOT よりも優先されます。
また、-d と CVS/Root が一致しない場合は、
前者が使用されます。
もちろん、
二つともが同じリポジトリを参照するのが、まともなやり方です。
CVS がリポジトリに情報を保存する方法を知っていても、 たいてい何の役にも立ちません。 実際、過去に書式が変更されましたし、 将来変更されることもあるでしょう。 ほとんど全ての場合、 CVS コマンドを通してリポジトリを利用しますから、 書式を変更しても混乱は起きません。
しかし、リポジトリでのデータ保存方法の知識が必要な場合もあります。例え ば CVS のロック解除が必要な場合 (see Concurrency) や、リポジ トリのファイルの許可属性を適切に設定する必要がある場合などです。
リポジトリの全体構造は作業コピーに対応するディレクトリ木で構成されてい ます。例えば、リポジトリが
/usr/local/cvsroot
にあれば、次のようなディレクトリの木構造になります (ディレクトリだけを 表示しています):
/usr
|
+--local
| |
| +--cvsroot
| | |
| | +--CVSROOT
| (管理用ファイル)
|
+--gnu
| |
| +--diff
| | (GNU diff のソース)
| |
| +--rcs
| | (RCS のソース)
| |
| +--cvs
| (CVS のソース)
|
+--yoyodyne
|
+--tc
| |
| +--man
| |
| +--testing
|
+--(その他の Yoyodyne のソフトウェア)
ディレクトリの中身は、管理下にあるファイルの履歴ファイル
(history files) です。
履歴ファイルの名前は、各ファイル名の最後に ,v を付加したものです。
次に、ディレクトリ yoyodyne/tc のリポジトリ構造を示します:
$CVSROOT
|
+--yoyodyne
| |
| +--tc
| | |
+--Makefile,v
+--backend.c,v
+--driver.c,v
+--frontend.c,v
+--parser.c,v
+--man
| |
| +--tc.1,v
|
+--testing
|
+--testpgm.t,v
+--test2.t,v
履歴ファイルは、
どのリビジョンのファイルでも再構築できる情報を持ち、
また変更内容が格納された時のログ・メッセージと、
その時のユーザの名前も記録しています。
ファイルをこのような書式で保管した最初のプログラムが、
RCS というバージョン管理システムであったために、
履歴ファイルは RCS ファイル と呼ばれます。
ファイル書式の完全な記述は、RCS の配布セットにある
rcsfile(5) の man ページか、CVS のソー
ス配布のファイル doc/RCSFILES を参照してください。
このファイル書式は非常に一般的なので、
CVS や RCS 以外のシステムでも、
少くとも理解をすることができます。
CVS で使用されている RCS ファイルは標準の書式と少し違います。 最大の違いは魔法の枝です。詳細は Magic branch numbers を参照して ください。CVS では、有効なタグ名は RCS で使用できるもののサ ブセットになっています。CVS の規則は Tags を参照してくださ い。
全ての ,v ファイルは読み込み専用であり、
この使用許可を変えるべきではありません。
これに対し、リポジトリ中のディレクトリは、
ファイルの修正を行なう人物に対して、
書き込みを許可しなくてはいけません。
これはつまり、
ファイルの修正を行なう人物からなるグループを作って
(group(5)参照)、
そのディレクトリの所有グループとすることを意味しています。
従って、 ディレクトリ単位でしかファイルのアクセス権を 管理することができません。
CVS はロック・ファイルを作成する必要があるため (see Concurrency)、ファイルを取り出す使用者にも、書き込み許可が必 要であることに注意して下さい。
利用者は CVSROOT/val-tags ファイルに書き込み許可が必要なことも
注意してください。CVS はそれをどのタグが有効かを記録するために使
います (作成時と、ときどきタグが使用されたときに更新されます)。
それぞれの RCS ファイルは最後に書き込んだ利用者に所有されます。こ れはあまり重要ではありません。重要なのは誰がディレクトリを所有している かです。
木の中に新しいディレクトリを加える場合、
CVS はできるだけ適当な使用許可を与える努力をします。
しかし新しいディレクトリの使用許可が、
親ディレクトリのものと異なる必要がある場合には、
手動で変更する必要があります。
環境変数 CVSUMASK を設定すれば、
リポジトリに作成されるディレクトリやファイルの使用許可を管理できます。
CVSUMASK は、作業ディレクトリのファイル使用許可には影響しません。
作業コピーの使用許可は、
新たに作成したファイルに通常与えられるものと同じです。
但し、CVS が読み込みだけを許可することがあります
(監視時 Setting a watch, -r 使用時 Global options,
CVSREAD 設定時 Environment variables を各々参照)。
クライアント/サーバ CVS を使用すると (see Remote repositories)、CVSUMASK を設定する良い方法はありません。クライ
アントマシンでの設定は効果がありません。rsh で接続しているなら、
オペーレーティングシステムの説明に書いてあるように、.bashrc や
.cshrc で CVSUMASK を設定することができます。この振る舞
いは将来のバージョンの CVS では変更されるかもしれません。クライア
ントの CVSUMASK の設定には頼らず、それは無効になるでしょう。
pserver を使う場合は、一般的に、 CVSROOT ディレクトリと木構造でそ れより上のディレクトリには厳しい使用許可が必要です。Password authentication security を参照してください。
オペレーティングシステムには特定のプログラムが、プログラムの呼び手には できないような動作をする能力とともに実行される機能があるものがあります。 例えば、unix の set user ID (setuid) や set group ID (setgid) 機能や VMS の installed image 機能です。CVS はそのような機能を使用するように 書かれていませんので、そのような方法で CVS をインストールすると事故の 過失に対する保護しか提供できなくなります。方法を欺くことを試そうとして いる人は誰でもそうすることができ、設定に応じて CVS だけに留まらない使 用許可を得るかもしれません。代わりに pserver を使用することを考えるか もしれません。それは同じ属性のいくつかを共有していますので、間違ったセ キュリティの設定や、修正したいものよりも大きなセキュリティホールを提供 する可能性がありますので、このオプションを考えているなら、pserver の説 明文書を注意深く読んでください。(Password authentication security)。
ファイルの使用許可には Windows オペレーティングシステムに特有の問題も あります (Windows 95, Windows NT, とおそらくこの系統の将来のオペレーティ ングシステムです。以下の項目で OS/2 に当てはまることもあるでしょうが、 確かではありません)。
ローカルの CVS を使っていて、リポジトリが Samba SMB サーバによってネッ トワーク接続されたファイルシステムにあるときに、使用許可で問題がおこる ことがあることが報告されています。Samba の設定で WRITE=YES にすると修 正される/何とかなると言われています。 責任放棄: 私はそのオプションを使用可にしたときの副作用について十分な調 査をしていません。加えて、問題を避けるために CVS が違ったようにするこ とができるかどうかも調べていません。何か発見したなら、BUGS に書 かれているように我々に報せてください。
ときどき CVS は RCS ファイルを Attic に保存することが
あることに気付くでしょう。例えば、CVSROOT が
/usr/local/cvsroot でディレクトリ yoyodyne/tc のファイル
backend.c について話をしているとき、普通はファイルは以下のとこ
ろにあります
/usr/local/cvsroot/yoyodyne/tc/backend.c,v
しかし、attic に行けば、代わりに
/usr/local/cvsroot/yoyodyne/tc/Attic/backend.c,v
になります。利用者にとってはファイルが attic にあるかどうかは関係あり
ません。CVS はこれを記録し、必要なときは attic を調べます。詳細を
知りたい人のために書くと、幹の先頭リビジョンが dead の状態であ
るまさにそのときだけ、ファイルは attic に保存されます。dead の
状態とはそのリビジョンでファイルが消去されたか、一度も加えられたことが
ない、ということです。例えば、枝にファイルを加えると、幹のリビジョンは
dead の状態になり枝のリビジョンは dead ではない状態にな
ります。
それぞれのリポジトリのディレクトリの CVS ディレクトリはファイル
属性などの情報が収められています (CVS/fileattr というファイルで
す。)。将来はこのディレクトリには他のファイルが加えられる可能性があり
ますから、実装は追加のファイルを静かに無視するのが良いでしょう。
この動作は CVS 1.7 とその後のものだけで実装されています。詳細は Watches Compatibility を参照してください。
fileattr ファイルの書式は以下の形式の登録の連続したものです ({
と } は括弧の中のテキストを0回以上繰り返すことができるというこ
とです):
ent-type filename <tab> attrname = attrval {; attrname = attrval} <linefeed>
ent-type はファイルでは F で、その場合は登録はそのファイ
ルの属性を指定します。
ent-type が D で、filename が空であると、新しく追加
されたファイルへの既定属性を指定します。
他の ent-type は将来の拡張のために予約されています。CVS 1.9 とそ れ以前のものはファイル属性を書き込むときにいつでもそれらを消すでしょう。 CVS 1.10 とそれ以降はそれらを保存します。
行の順番は関係無いことに注意してください。 fileattr ファイルを書き込むプログラムは便利な様に再編成するかもしれま せん。
ファイル名でのタブとラインフィード、attrname での =,
attrval での ;、などを引用する方法は今はありません。
習慣では、attrname は CVS により特別な意味を持っている属性は
_ で始まります。他の attrname は使用者定義の属性のために
あります (もしくは、実装が使用者定義の属性のサポートを始めたときにそう
なるでしょう)。
作りつけの属性です:
_watched
_watchers
cvs
edit コマンド (もしくはそれと等価なもの) が発生したときで、
hostname と pathname は作業ディレクトリのためです。
例:
Ffile1 _watched=;_watchers=joe>edit,mary>commit Ffile2 _watched=;_editors=sue>8 Jan 1975+workstn1+/home/sue/cvs D _watched=
は file1 は読み込み専用で取り出されるべきだということです。加え
て、joe は edit を監視しており、mary は commit を監視しています。ファ
イル file2 は読み込み専用で取り出されるべきです。sue は 1975年1
月8日にマシン workstn1 のディレクトリ /home/sue/cs編集を
始めました。この例を表現するために、D, Ffile1,
Ffile2 の後に空白を表示していますが、実際は単独のタブ文字がそこ
にあり、空白があってはいけません。
利用者から見える部分の CVS のロックに焦点をあてた紹介は Concurrency を参照してください。次の部分は同じリポジトリをアクセ スする他のツールに干渉することなく CVS のリポジトリにアクセスするよう なツールを書きたい人を対象にしています。読み込みロック (read lock), 書き込みロック (write lock), デッ ドロック (deadlock) のような概念がよくわからなかったら、オペレー ティングシステムやデータベースの文献を参照すると良いかもしれません。
リポジトリ中の #cvs.rfl. で始まる全てのファイルは読み込みロック
です。リポジトリ中の #cvs.wfl で始まる全てのファイルは書き込み
ロックです。古いバージョンの CVS (CVS 1.5 以前) は #cvs.tfl で
始まる名前のファイルも作成していましたが、ここではそれらは議論しません。
ディレクトリ #cvs.lock はマスターロックとして働きます。すなわち、
他のロックを取得する前に、まずこのロックを取得しなければならない、とい
うことです。
書き込みロックを取得するためには、まず #cvs.lock ディレクトリを
作成します。この操作は原子的操作でなければなりません (これはたいていの
オペレーティングシステムで真のはずです)。 既にディレクトリが存在したた
めに失敗すれば、しばらく待ってもう一度試します。#cvs.lock ロッ
クを取得した後、#cvs.rfl. の後に選択した情報 (例えば、ホスト名
とプロセス番号) が続いた名前のファイルを作成します。それからマスターロッ
クを解放するために #cvs.lock ディレクトリを消去します。それから
リポジトリを読んで続行します。終った後、読み込みロックを解放するために
#cvs.rfl ファイルを消去します。
書き込みロックを取得するためには、読み込みロックと同様にまず
#cvs.lock ディレクトリを作成します。それから #cvs.rfl.
で始まるファイルが無いかどうかを調べます。もしあれば、#cvs.lock
を消去し、しばらく待って、もう一度試します。読み込み手がいないときは、
#cvs.wfl の後に選択した情報を続けた名前のファイルを作成します
(例えば、ホスト名とプロセス番号)。ロック #cvs.lock を続けます。
リポジトリへの書き込みを実行します。それが終わると、まず
#cvs.wfl ファイルを消去し、それから #cvs.lock ディレクト
リを消去します。#cvs.rfl ファイルと違って、#cvs.wfl ファ
イルは情報提供のためだけにあることに注意してください。#cvs.lock
そのもののロックを続ける以上のロック操作の効果はありません。
それぞれのロック (書き込みロック及び読み込みロック) は Attic と
CVS を含んだリポジトリの単独のディレクトリのみをロックしますが、
バージョン管理下の他のディレクトリは含まないことに注意してください。木
全体をロックするためには、それぞれのディレクトリをロックする必要があり
ます (必要なロックのどれかの取得に失敗したら、デッドロックを避けるため
に再挑戦の前に木全体を解放しなければならないことに注意してください)。
CVS は個々の foo,v ファイルへのアクセス制御のために書き込
みロックを期待するということにも注意してください。RCS には
,foo, ファイルがロックとして働く機構がありますが、CVS はそ
れを実装しておらず、CVS の書き込みロックを取り出すことが推奨され
ています。さらなる議論/合理性は CVS のソースコードの
rcs_internal_lockfile のところのコメントを読んでください。
$CVSROOT/CVSROOT ディレクトリにはいろいろな管理ファイルがありま
す。ある面ではこのディレクトリはリポジトリの他のディレクトリとよく似て
います。そこにはファイル名が ,v で終わる多くの RCS ファイ
ルがあり、多くの CVS コマンドは同じ方法でそれを操作します。しかし、
少しの違いはあります。
それぞれの管理ファイルには、RCS ファイルに加えて、ファイルの取り
出された版のコピーがあります。例えば、RCS ファイル
loginfo,v とそれの最新リビジョンであるファイル loginfo
があります。管理ファイルを格納したときは、CVS は
cvs commit: Rebuilding administrative file database
を印字し、$CVSROOT/CVSROOT の取り出された版のコピーを更新するよ
うになっています。もしそうならなければ、何かがおかしくなっています
(see BUGS)。自分自身のファイルをこのように更新されるファイル群に追
加するために、それらを管理ファイル checkoutlist に追加できます
(see checkoutlist)。
初期設定では modules ファイルは上で説明されているように振舞いま
す。modules ファイルがとても大きくなると、普通のテキスト・ファイルとし
て保存しているとモジュールの探索が遅くなるかもしれません (CVS が
最初にこの機能を追加したときほど関心があるかどうかは定かではありません。
ベンチマークは見ていませんので)。ですから、CVS ソースコードに適切
な修正を加えるとおで、modules ファイルを Berkeley db や GDBM のような
ndbm インターフェースを実装したデータベースで保存することができ
ます。このオプションが使用されると、modules データベースは
module.db, modules と/もしくは modules.dir に保存
されます。
いろいろな管理ファイルの意味に関する情報は Administrative files を参照してください。
しばしば表面に現れてくるかもしれない CVS の内部についての話をして
いる間に、CVS が作業ディレクトリの CVS ディレクトリに何を
入れるかも話した方が良いでしょう。リポジトリと同様に、CVS がこの
情報を扱い、普通は CVS のコマンドを通してだけそれを使用します。で
も、ときにはそれを覗くのも良いでしょうし、グラフィカル・ユーザ・インター
フェース の jCVS や emacs のための VC パッケージなどの他
のプログラムがそれを見る必要があるかもしれません。そのようなプログラム
は、上で書いたプログラムやコマンド行 CVS クライアントの将来のバー
ジョンを含む、そのファイルを使う他のプログラムと協調して動作しようと望
むなら、この節の推奨規格に従う必要があります。
CVS ディレクトリには複数のファイルがあります。このディレクトリ
を読むプログラムは、将来の拡張の余地を残すために、ディレクトリには存在
するけれどここで説明されていないファイルは静かに無視するのが望ましいで
す。
ファイルは使用しているシステムのテキストファイルの習慣に従って保存され ます。これはテキストファイルの補完の習慣が違うシステム間では作業ディレ クトリは可搬性が無いということです。これは意図的になされていて、おそら く CVS で管理されているファイル自体がそのようなシステム間では可搬性が ないであろう、という理由に基づいています。
Root
Repository
cvs -d :local:/usr/local/cvsroot checkout yoyodyne/tc
Root は以下のようになり
:local:/usr/local/cvsroot
Repository は
/usr/local/cvsroot/yoyodyne/tc
か
yoyodyne/tc
のどちらかになります。
特定の作業ディレクトリがリポジトリのディレクトリに対応しなければ、
Repository は CVSROOT/Emptydir になっているはずです。
Entries
最初の文字が / であれば、様式は:
/name/revision/timestamp[+conflict]/options/tagdate
で、[ と ] は登録の一部ではありませんが、その代わりに
+ と衝突の印は省略任意であることを示しています。name はディ
レクトリ中のファイルの名前です。revision は作業中のファイルの元
のリビジョンで、0 の場合は追加されたファイル、- の後にリ
ビジョンは削除されたファイルです。timestamp は CVS がファイ
ルを作成したときのタイムスタンプです。タイムスタンプがファイルの実際の
修正時刻と違えば、ファイルは修正されたということです。それは ISO C
astime() 関数で使われる様式で保存されます (例えば、Sun Apr 7
01:29:26 1996)。ファイルが常に修正されていると見なされるように、例え
ば、Result of merge のようにその様式とは違う文字列を書くかもし
れません。これは特別な場合ではありません。ファイルが修正されたかどうか
を調べるために、プログラムはファイルのタイムスタンプを単純に
timestamp と文字列比較をするべきです。衝突があれば、
conflict は、ファイルが衝突の印とともに書き込まれた後でファイル
の修正時刻に設定することができます (see Conflicts example)。 もし
conflict がその後も実際の修正時刻と同じであるなら、ユーザは明か
に衝突を解消していません。options は貼り付けられたオプションを保
持しています (例えば、バイナリ・ファイルのための -kbd)。
tagdate は T の後にタグ名が続いているか、日付 (date) の
D で、貼り付けられたタグか日付がつづいているかのどちらかを保持
しています。timestamp が単独のタイムスタンプではなく、スペースで
分離されたタイムスタンプの対であるなら、CVS 1.5 より前のバージョ
ンの CVS を扱っているということに注意してください (ここでは説明さ
れていません)。
CVS/Entries のタイムスタンプの標準時 (ローカルもしくは共通時) はオペレー ティングシステムがファイル自身のタイムスタンプとして保存するものと同じ である必要があります。例えば、Unix ではファイルのタイムスタンプは共通 時刻 (UT) ですので、CVS/Entries のタイムスタンプもそうなっているべきで す。VMS ではファイルのタイムスタンプはローカル時刻なので、 VMS 上の CVS はローカル時刻を使うべきです。この規則は、標準 時が変わったためだけでファイルが修正されたようにならないためです (例え ば、サマータイムになったり、それが終わったときなどです)。
Entries の行の最初の文字が D であると、それはサブディレ
クトリを現しています。行が D だけのときは、 Entries ファ
イルを書いたプログラムはサブディレクトリを記録したということを現します
(ですから、そのような行があって、他に D で始まる行がなければ、
サブディレクトリがないことがわかります)。そうでなければ、行は次のよう
になっています:
D/name/filler1/filler2/filler3/filler4
ここで name はサブディレクトリの名前であり、将来の拡張のために、
全ての filler 部分は暗黙の内に無視されるべきです。Entries
を修正するプログラムはこれらの部分を保存するのが望まれています。
ファイル Entries 中の行はどんな順番でも構いません。
Entries.Log
Entries に無いさらなる情報を記録することはありま
せんが、Entries ファイル全体を再書き込みすることなく、情報を更
新するための方法をもたらし、その中には Entries と
Entries.Log を書いているプログラムが不意に異常終了しても情報を
保護する機能もあります。Entries ファイルを読み込むプログラムは
Entries.Log も調べるべきです。後者が存在すれば、Entries
を読み込んで、Entries.Log にある変更を適用すべきです。変更を適
用した後で、Entries を再度書き込んで、Entries を消去する
習慣が推奨されています。Entries.Log の行の様式は、単独文字コマ
ンドがあり、その後にスペースが続き、その後は Entries の行に指定
された様式になります。単独文字コマンドは登録が追加されたことを示す
A と登録が消去されたことを示す R か、Entries の登
録行は暗黙に無視されるべきことを示す他の文字です (将来の拡張のため)。2
番目の文字が Entries.Log の行の2番目の文字がスペースでないと、
それは CVS の古いバージョンで書かれています (ここでは説明されてい
ません)。
読み込みではなく、書き込みをしているプログラムは、もし望むならば
Entries.Log ファイルを安全に無視することもできます。
Entries.Backup
Entries.Backup に書き、それから Entries に改名する (もし
可能なら原子的操作で) ことです。
Entries.Static
update コマンドを -d オプションとともに使っ
てください。そうすれば、追加のファイルを取得して、
Entries.Static を消去します。
Tag
T、枝でないタグは N、日付は D にな
り、他の文字は、将来の拡張のため暗黙に無視されるべきとなっています。こ
の文字の後にタグや日付が続きます。ディレクトリごとの貼り付きタグや日付
は新規に追加されたファイルに適用されること等に使用されることに注意して
ください。貼り付きタグと日付に関する一般的な情報は Sticky tags
を参照してください。
Checkin.prog
Update.prog
-i と -u
オプションで指定されたプログラムを保存します。
Notify
edit や
unedit のため) を保存します。書式はまだここでは説明されていませ
ん。
Notify.tmp
Notify の関係は Entries.Backup と
Entries の関係と同じです。即ち、Notify を書くためにはま
ず新しい内容を Notify.tmp に書き、それから (可能であれば自動的
に) それを Notify に改名します。
Base
edit コマンドはファイルの元のコピーを
Base ディレクトリに保存します。これで、サーバと通信できないとき
でさえ unedit コマンドが実行できるようになります。
Baserev
Base ディレクトリのそれぞれのファイルのリビジョ
ンを一覧にします。書式は:
Bname/rev/expansion
で、expansion は将来の拡張のために、無視されるべきものです。
Baserev.tmp
Baserev の関係は Entries.Backup と
Entries との関係と同じです。即ち、Baserev に書くために、
まず新しい内容を Baserev.tmp に書き、それから (もし可能なら自動
的に) それを Baserev に改名します。
Template
rcsinfo ファイルで指定された雛型が入っています
(see rcsinfo)。それはクライアントだけに使われます。非クライアント/
サーバ型 CVS は直接 rcsinfo ファイルを調べます。
$CVSROOT/CVSROOT には、いくつか 管理用ファイル
(administrative files) があります。完全な説明は
See Administrative files. これらのファイルが無く
ても CVS を使用することができます。しかし、少なくとも
modules というファイルが適切に設定してあれば CVS のコマン
ドはうまく働きます。
管理用ファイルの中で、
最も重要なファイルは modules です。
これはリポジトリの中の全てのモジュールを定義しています。
modules ファイルの例を次に示します。
CVSROOT CVSROOT modules CVSROOT modules cvs gnu/cvs rcs gnu/rcs diff gnu/diff tc yoyodyne/tc
modules ファイルは行ごとに意味を持つファイルです。
modules ファイルの各行はそれぞれ、
モジュール名, 空白, モジュールのあるディレクトリ名
という書式で記述されます。
モジュールのあるディレクトリ名は、
$CVSROOT からの相対パスです。
modules ファイルの各行はそれぞれ、
モジュール名, 空白, モジュールのあるディレクトリ名
という書式で記述されます。
モジュールのあるディレクトリ名は、
$CVSROOT からの相対パスです。
上の例の最後の4行はそのような行の例です。
モジュール modules を定義する行については、
ここでは説明しません。
より詳しい説明は modules 参照。
管理用ファイルは、
他のモジュールと同じ方法で編集します。
cvs checkout CVSROOT を用いて作業コピーを取り出して、
編集し、通常通り変更内容を格納します。
間違いのある管理用ファイルを格納することも可能です。 このような場合には、間違いを正して新たなリビジョンを登録します。 しかし管理用ファイルに深刻な間違いがあれば、 新たなリビジョンの登録さえも不可能になります。
特定の状況では一つ以上のリポジトリを持つことは良い考えです。例えば二つ
のプロジェクトがあり、全くコードが重複しないような場合です。複数のリポ
ジトリ持つためにはしなければならないことは、適切なリポジトリを、環境変
数 $CVSROOT で設定するか、CVS のオプション -d に指
定するか、もしくは、(一度作業ディレクトリを取り出せば) 単純に CVS
に作業ディレクトリ取り出しに使われたリポジトリを使わせる、ということだ
けです。
複数のリポジトリを持つ大きな利点は、各々を別のサーバに置けることです。 CVS バージョン 1.10 では、単独のコマンドは違うリポジトリのディレ クトリを再帰的に辿ることはできません。開発バージョンの CVS では、 複数のサーバから作業ディレクトリに取り出すことがでます。CVS は要 求されたコマンドを実行するために必要であれば、再帰的に動作し、対応する 数のサーバ・マシンに接続するという細い作業全部を扱います。 以下は作業ディレクトリを設定する例です:
cvs -d server1:/cvs co dir1 cd dir1 cvs -d server2:/root co sdir cvs update
cvs co コマンドは作業ディレクトリを設定し、それから cvs
update コマンドは server2 に接続し、dir1/sdir サブディレクトリを更新
し、その他のものを更新するために server1 に接続します。
CVS リポジトリを設定するために、まずソースファイルのリビジョン履 歴を保存したいマシンとディスクを選びます。CPU とメモリの要求は小さなも のですので、たいていのマシンは十分なはずです。詳細は Server requirements を参照してください。
ディスクスペースの必要量を見積もると、別のシステムから RCS ファイルを 移管しているのであれば、リポジトリの最初の大きさは大体そのくらいになり、 バージョンの履歴が全然無い状態で始めるのであれば、大雑把な大きさはリポ ジトリのCVS の管理下に置かれるコードのほぼ3倍をサーバで用意することに なります (最終的にはこれより大きくなるでしょうが、しばらくは大丈夫なは ずです)。開発者が作業するマシンでは各開発者に作業ディレクトリとほぼ同 じディスクスペースを用意すると良いでしょう (各開発者の利用に基づいて、 全体の木かそれの一部分のどちらかになります)。
リポジトリはサーバ経由からか直接 CVS を使う全てのマシンからか、 (直接もしくはネットワーク接続されたファイルシステム経由で) 利用可能に する必要があります。クライアントのマシンは CVS プロトコル経由以外 でそれにアクセス可能である必要はありません。CVS は、リポジトリに ロック・ファイルを作成する必要があるため (see Concurrency)、利用者 が読み込み許可しか持たないリポジトリを、CVS から使うことはできま せん。
リポジトリを作成するときには、cvs init コマンドを実行して下さい。
通常の方法で指定された CVS のルート (see Repository) 以下の、
空のリポジトリを利用できるように整えます。例えば次のようにします。
cvs -d /usr/local/cvsroot init
cvs init は注意深いので、リポジトリに存在するファイルを上書きし
ません。従って既に利用できる状態のリポジトリに対して cvs init
を実行しても、何の不都合もありません。
cvs init は、操作履歴を記録するように設定します。
もしこれを望まないのであれば、cvs init を実行した後に、
history ファイルを削除して下さい。See history file.
リポジトリ中のファイルに関して、特に魔法のような事はありません。ほとん どの場合、他のファイルと同様にバックアップできます。しかし、考慮すべき 点も幾つかあります。
最初の点は偏執的で、バックアップ中には CVS を使用しないか、バック
アップ中はバックアッププログラムに CVS をロックさせる必要がありま
す。CVS を使わないために、リポジトリを操作できるマシンへのログイ
ンを禁止したり、CVS サーバを停止したり、同様な機構を利用するかも
しれません。詳細はあなたのオペレーティングシステムと、CVS を設定
した方法に依存します。CVS をロックするためには、#cvs.rfl
ロックをそれぞれのリポジトリのディレクトリに作成するでしょう。このよう
に言ってきましたが、これらの事前注意をせずにただバックアップを行なって
も、結果が特に悲惨になる可能性はあまりありません。バックアップから復元
すると、リポジトリは不整合状態になるかもしれませんが、手で修正すること
が非常に難しいということは無いでしょう。
リポジトリをバックアップから復元し、リポジトリ中の変更がバックアップ時 から変更されていると仮定すると、失敗に影響を受けあかったディレクトリは 今やリポジトリに存在しなくなってしまったリビジョンを参照しているかもし れません。そのようなディレクトリで CVS を実行しようとすると、普通 はエラーメッセージを出力します。これらの変更をもう一度リポジトリに戻す 方法の一つに以下のようなものがあります:
CVS ディレクトリの内容をコピーしないでください)。
cvs update や cvs diff
のようなコマンドを使って何が変更されたかを見つけ、準備がでいたなら、変
更をリポジトリに格納します。
リポジトリ中のファイルのバックアップが他のファイルのバックアップと良く 似ているように、リポジトリを別の場所に移動する必要があるときも、それは 他のファイルの集合を移動するのと非常に良く似ています。
主に考慮することは、作業ディレクトリがリポジトリを指しているか、という
ことです。移動されたリポジトリを扱う一番簡単な方法は、移動後にただ新し
い作業ディレクトリを取得することです。もちろん、移動前に古い作業ディレ
クトリが格納されたかを確かめたいでしょう。もしくは変更を失わないような
何らかの他の方法を見つけているかもしれません。もし本当に既に存在する作
業ディレクトリを再利用したいなら、CVS/Repository ファイルを手で
手術することで可能です。CVS/Repository と CVS/Root ファ
イルの情報は Working directory storage で参照することができます
が、わずらいたいと本当に思っていないかぎりは、労力に見合わないでしょう。
ソースの作業コピーはリポジトリと別のマシンに存在することができます。 CVS をこの方法で使うことは クライアント/サーバ (client/server) 操作として知られています。クライアント と して、CVS を作業ディレクトリを mount できるマシンで CVS を実 行し、サーバ となる、リポジトリを mount できるマシンと通信するよ うに告げます。一般的に、遠隔リポジトリを使うことは、リポジトリ名の様式 が以下のようになることを除き、ローカルのものを使うのと同じです:
:method:user@hostname:/path/to/repository
どれが本当に設定する必要があるかは、サーバに接続している方法に依って変 わります。
method が指定されず、リポジトリ名に : が含まれる場合には、
使用するオペレーティングシステムに依って ext か server
が既定値とされます。詳しくは Connecting via rsh 参照。
rsh プログラムを利用する
cvs serverを使う
サーバとしてどんな種類のマシンが適切かという質問への手短な答は、要求は こじんまりとしたものであるということです--32M のメモリやそれ以下のサー バでさえ、かなり大きなソース木とかなりの量の活動を扱うことができます。
もちろん、本当の答はもっと複雑です。既知の大量のメモリ消費をする部分の 見積りは、メモリの要求を見積るのに十分でしょう。ここにはそのような部分 が2つ書いてあります。他のメモリ消費は比較的小さいはずです (もしそうで ないものがあれば、この説明文書を更新できるように、BUGS に書かれ ているように、我々に知らせてください)。
大量のメモリ消費をする最初の部分は、CVS サーバを使っているときの 大きな取り出しです。サーバは、扱っているそれぞれのクライアントのための 2つのプロセスからなります。子プロセスのメモリ消費は非常に少く抑えられ ているはずです。親プロセスのメモリ消費は、特にクライアントとのネットワー ク接続が遅ければ、一つのディレクトリのソースの大きさよりも少し大きくな るか、2メガバイトほどかどちらか大きいものになることが予想されています。
それぞれの CVS サーバの大きさを予想上の一度に活動するサーバ数で掛 けたものによって、サーバのメモリの要求の輪郭を得ることができます。たい ていの場合、親プロセスでのメモリ消費は物理メモリではなくてスワップメモ リでしょう。
大量のメモリ消費の2番目の部分は、大きなファイルを格納しているときの
diff です。これはバイナリ・ファイルでさえも必要です。大体の目安
は、格納したい最大のファイルの大きさの10倍を用意することですが、5倍が
適当でしょう。例えば、10メガバイトのファイルを格納したいときは、格納を
するマシン (クライアント/サーバ ならサーバマシン、クライアント/サーバ
でなければ、CVS を実行しているマシン) に100メガバイトのメモリがあ
るのが良いです。これは物理メモリでなく、スワップであるかもしれません。
メモリが必要なのは短時間だけなので、そのような格納が同時に2つ以上なさ
れるときのためのメモリを準備する必要は特にありません。
クライアントの資源消費はさらに少ないです--オペレーティングシステムを 動作させるために十分な能力のあるマシンなら、ほとんど問題はないでしょう。
ディスク容量に対する要求の情報は、Creating a repository を参照し てください。
CVS はこれらの操作を実行するために rsh プロトコルを用いますので、
遠隔側の使用者のホストはローカルの使用者の接続を許可する
.rhosts を持つ必要があります。
例えば、あなたがローカルマシン toe.example.com の利用者
mozart であり、サーバマシンは faun.example.org であると
しましょう。faun では、以下の行を bach のホームディレクトリ
の .rhosts ファイルに書いてください:
toe.example.com mozart
そして、rsh の動作を次の行で確認します。
rsh -l bach faun.example.org 'echo $PATH'
次に rsh が、
サーバを発見できるかどうか確認する必要があります。
上記の例で rsh が表示したパスの中に、
サーバである cvs のあるディレクトリが
含まれているかどうか確認して下さい。
.login や .profile でなく、
.bashrc, .cshrc 等に
パスを設定する必要があります。
代わりに、クライアント側で環境変数 CVS_SERVER に、
/usr/local/bin/cvs-1.6 などと、
使用したいサーバ名を設定できます。
inetd.conf を編集したり、
CVS のサーバ・デーモンを走らせる必要はありません。
rsh 経由で $CVSROOT を利用するときに
指定できる接続経路は二つあります。
:server: を指定した場合、
CVS が内部実装した rsh のクライアントが用いられますが、
移植版では利用できないものもあります。
:ext: を指定した場合、外部の rsh プログラムが用いられます。
rsh が既定となっていますが、
サーバを利用できる他のプログラムを呼び出す場合は、
環境変数 CVS_RSH に設定して下さい
(例えば HP-UX 9 では、
rsh は何か別のものなので remsh を用いて下さい)。
指定するプログラムは、データを変更しないで送受信できなくてはいけません。
例えば Windows NT の rsh は、
既定では CRLF を LF に換えるので不適当です。
CVS の OS/2 版はこれを回避するため、
rsh に -b を渡して切り抜けていますが、
標準的な rsh でないプログラムを黙認する形になるので、
将来は別のやり方になるでしょう。
CVS_RSH に SSH 等の rsh の代替物を設定した場合、
この節の残りの .rhosts の使用説明などは、
おそらく不適当でしょうから、
各 rsh の代替物の文書資料を参照して下さい。
例を続けます。仮に faun.example.org の
リポジトリ /usr/local/cvsroot/ 中の
モジュール foo を利用したい場合には、
もう準備はできています:
cvs -d :ext:bach@faun.example.org:/usr/local/cvsroot checkout foo
(クライアント側とサーバ側で、使用者名が同じ場合には、
bach@ を省略することが出来ます。)
CVS のクライアントは、
パスワード・プロトコルを用いて、
サーバと接続することもできます。
この方法は、
rsh の使用が可能でなく
(例えばサーバが防火壁の向こうにある場合)、
またケルベロスも利用できない場合に特に有効です。
この方法を使用するために、 サーバとクライアント双方での調整が必要になります。
まず最初に、$CVSROOT と $CVSROOT/CVSROOT ディレクトリの
使用許可をきつくすることを考えるでしょう。詳細は Password authentication security を参照してください。
サーバ側では /etc/inetd.conf を編集する必要があります。
正しいポートに接続を受けた時、
inetd がコマンド cvs pserver を実行する様に変更します。
ポート番号の既定値は 2401 ですが、
クライアントをコンパイルした時に、
CVS_AUTH_PORT に他の値を定義した場合には異なります。
あなたの使用する inetd が、
ポート番号を素のまま /etc/inetd.conf に書いて良いならば、
次の記述で十分でしょう
(inetd.conf には一行で記述して下さい):
2401 stream tcp nowait root /usr/local/bin/cvs cvs --allow-root=/usr/cvsroot pserver
-T オプションで一時ファイルを作成するディレクトリも指定できます。
--allow-root オプションは使用可能な CVSROOT ディレクトリを
指定します。違う CVSROOT ディレクトリの使用を試みるクライアントは
接続できません。許可したい CVSROOT ディレクトリが2つ以上あるなら、
オプションを繰り返してください。(不幸なことに、inetd の多くのバー
ジョンはコマンドと引数の両方、もしくはどちらかの長さ全体に対して非常に
小さくなるように制限を課しています。この問題に対する普通の解決は、
inetd に CVS を必要な引数と共に起動するシェルスクリプトを
実行させることです。)
あなたの使用する inetd が、
素のポート番号ではなく、サービス名を要求するならば、
/etc/services に次の行を追加して下さい:
cvspserver 2401/tcp
そして inetd.conf には、
2401 ではなく cvspserver と記述して下さい。
以上を注意して行なった後、
inetd を再起動するか、
初期設定ファイルを再読させるのに必要な処置を取って下さい。
これの設定に問題があるときは、Connection を参照してください。
クライアントはパスワードを平文のまま保存または伝送します
(ほぼそのように--詳細は Password authentication security)。
従って、リポジトリを利用する時に、
正規のパスワードを危険に曝さないために、
CVS では別のパスワードファイルを使用します。
このファイルは $CVSROOT/CVSROOT/passwd です。
その書式は、使用者名、パスワード、サーバが使用する任意に省略可能な使用
者名という二つか三つの欄しかない事を除けば、
/etc/passwd と同様です。
次に例示します:
bach:ULtgRLXo7NRxs cwang:1sOp854gDF3DY
パスワードは、標準 Unix の関数 crypt() によって暗号化されます。
従って、標準 Unix の passwd から直接コピーすることも可能です。
パスワード認証では、まずサーバが、
CVS の passwd ファイル中の、使用者のエントリを確認します。
使用者のエントリがあれば、入力されたパスワードと比較されます。
使用者のエントリが無いか、
あるいは CVS の passwd ファイルが存在しない場合には、
システムが使用者の調査機構に使用するパスワードと一致するか試されます
(cofig ファイルで SystemAuth=no を設定することで、システムの使
用者調査機構を使用不能にすることができます)。
サーバはエントリの三番目の欄にある使用者の権限で実行されます。
三番目の欄が無い場合には、最初の欄にある使用者の権限が使用されます
(つまり CVS の passwd ファイルに、
システムで有効な使用者を併せて記述すれば、
架空の使用者名を使用できます)。
どちらの場合でも、
(有効な) 使用者が持たない特権は付与されません。
$CVSROOT/CVSROOT/passwd ファイルのパスワードの後にコロンとシス
テムの使用者名を追加することで、CVS 専用の使用者名をシステムの使用者名
に "マップ" することが可能です。(例えば、システムのログイン名に)。例
えば:
cvs:ULtgRLXo7NRxs:kfogel generic:1sOp854gDF3DY:spwang anyone:1sOp854gDF3DY:spwang
こうやって、次のコマンド:
cvs -d :pserver:cvs@faun.example.org:/usr/local/cvsroot checkout foo
で faun.example.org のリポジトリに遠隔接続する人は、認証に成功
すると、システムの kfogel としてサーバを実行することになります。しかし、
遠隔使用者は、 $CVSROOT/CVSROOT/passwd ファイルに CVS のみ
が使用する違ったパスワードがあるかもしれませんので、kfogel のシステム
パスワードが必ず必要なわけではありません。そして、上記の例で示されてい
るように、複数の cvs 利用者名を単一のシステムの利用者名にマップするこ
とができます。
この機能はリポジトリへの接続をシステムへの完全な接続を行うことなく (特 に、Read-only access を参照してください) 可能にするために設計さ れています。しかし、Password authentication security も参照して ください。どんな種類のリポジトリ接続でも、ある程度の総合的なシステム接 続も含んでいる可能性が高いのです。
現在、
CVS の passwd ファイルにパスワードを加えるには、
他のどこかからコピーするしか方法がありません。
いつの日か cvs passwd コマンドができることでしょう。
$CVSROOT/CVSROOT の多くのファイルと違って、passwd ファイ
ルは CVS 経由ではなく、直接編集します。
サーバに接続する前に、
使用者はコマンド cvs login を用いて
ログインする必要があります。
サーバのパスワード確認と同時に、
後のサーバとの処理のためにパスワードを保存します。
コマンド cvs login は、
使用者名, サーバのホスト名, リポジトリへのフルパス等の情報が必要で、
リポジトリの引数もしくは環境変数 CVSROOT から取得します。
cvs login は対話的です--それはパスワード入力を促します:
cvs -d :pserver:bach@faun.example.org:/usr/local/cvsroot login CVS password:
サーバによりパスワードが照合され、
正しければ login が成功しますが、
誤りであれば失敗して、パスワードが正しく無いと文句を言います。
一度ログインに成功すると、CVS に保存されたパスワードを 使って認証し、直接サーバに接続するようにさせられます:
cvs -d :pserver:bach@faun.example.org:/usr/local/cvsroot checkout foo
CVS がサーバに接続する際、
:pserver: が無ければ、
rsh が用いられます (see Connecting via rsh)。
従って、必ず :pserver: を付加して下さい。
(一旦作業コピーを取り出した後、
作業ディレクトリ中で CVS を実行する場合には、
もう明示的にリポジトリの指定をする必要はありません。
CVS は作業コピーのサブディレクトリ CVS に、
引数のリポジトリを記録しているためです。)
パスワードは、既定ではファイル $HOME/.cvspass に保存されます。
ファイルは人が読める書式で書かれていますが、
十分な知識無しに編集してはいけません。
パスワードは平文ではなく、
"悪気無く"見られる事 (つまり、システム管理者が偶然そのファイルを見付け、
不注意に見るといった事) を防ぐために、
簡単な符号化がなされています。
現在選ばれている遠隔リポジトリのパスワードは cvs logout コマン
ドを使用すると CVS_PASSFILE から消去できます。
環境変数 CVS_PASSFILE は、この既定値に優先します。
この変数を使用するのであれば、
cvs login を実行する前に設定しなければいけません。
cvs login を実行した後に設定した場合、
その後の CVS コマンドは、
サーバに送るパスワードを見付けられません。
パスワードは、 平文を簡単に符号化してクライアント側に保存されており、 送信の際も同じ符号化が用いられます。 この符号化は、パスワードが偶然見られること (すなわちシステム管理者が 不注意に見てしまう事) を防ぐためのもので、 素人の攻撃からパスワードの取得を防ぐことさえ出来ません。
CVS 独自のパスワードファイルにより (see Password authentication server)、 リポジトリを利用する時には、 システムにログインする時とは別のパスワードが使用できます。 しかし、一旦リポジトリが読み込み専用でない状態で利用可能になれば、 多様な方法により、サーバ上でプログラムが実行可能になります。 つまりリポジトリの利用は、 かなり広範囲にシステムが利用できる事を暗示しています。 これを防止するように CVS を修正する事は可能でしょうが、 これを書いている時点までには誰もやっていません。
$CVSROOT/CVSROOT ディレクトリには passwd と他のセキュリ
ティを調べるために使われるファイルがあるので、このディレクトリの使用許
可をを /etc と同じくらいきつくしなければならないことに注意して
ください。同じことが $CVSROOT ディレクトリそのものと、木のそれ
より上の部分のすべてのディレクトリにもあてはまります。そのようなディレ
クトリに書き込み許可のある全ての人はシステムの任意の使用者になることが
できます。これらの使用許可は普通は pserver を使っていないときに使用す
るものよりもきついものであることに注意してください。
要約すると、 パスワードを得た人物は誰でもリポジトリを利用できます (これはまたある程度通常のシステム利用も可能になるということを含むかも しれません。) ネットワークのパケットを漁ったり、 保護された (つまり所有者のみ読み込み可能な) ファイルを読むことができる、 全ての人物がパスワードを入手可能です。 あなたが本物の安全を望むのならば、ケルベロスにしましょう。
GSSAPI は ケルベロス5のようなネットワークセキュリティシステムとの一般 的なインターフェースです。動作する GSSAPI ライブラリを持っているなら、 CVS を GSSAPI で認証して、直接 TCP 接続を通して接続すること ができます。
これをするためには、CVS が GSSAPI サポート付きでコンパイルされて
いる必要があります。CVS を configure しているときに、ケルベロス
version 5 を使う GSSAPI ライブラリが存在するかどうかを発見しようとしま
す。構築するために --with-gssapi も使用できます。
接続は GSSAPI を使って認証されますが、メッセージストリームは既定では認
証されません。ストリームの認証を要求するためには、広域オプショ
ン -a を使用する必要があります。
既定状態では、データ転送は暗号化されません。
クライアントとサーバ双方を、
暗号化を有効にしてコンパイルしておく必要があります。
構築時に --enable-encryption オプションを付加して、
暗号化機能を有効にして下さい。
また暗号化を要求するために、
使用時に広域オプション -x を付加する必要があります。
GSSAPI 接続はパスワード認証サーバを扱うのと同じサーバのサーバ側で扱わ
れます。Password authentication server 参照。ケルベロスのような
強い認証を提供する GSSAPI 機構を使用しているなら、平文のパスワードによ
る認証を使用不能にしたいと思うかもしれません。そのためには、空の
CVSROOT/passwd パスワードファイルを作成して、config ファイルで
SystemAuth=no を設定します (see config)。
GSSAPI サーバは cvs/hostname の主な名前を使い、hostname は サーバーホストの正式な名前です。あなたの GSSAPI 機構で要求されているよ うにこれを設定しなければなりません。
GSSAPI を使用して接続するには、:gserver: を使用します。例えば、
以下のようになります。
cvs -d :gserver:faun.example.org:/usr/local/cvsroot checkout foo
ケルベロスを使う一番簡単な方法は Connecting via rsh で説明されて
いるようにケルベロスの rsh を使用することです。
rsh を利用する際の主な欠点は、
全てのデータが他のプログラムを経由する必要があるため、
時間がかかるかもしれない事です。
もしケルベロスが導入されているならば、
ケルベロスの認証により、直接 TCP 接続する事が可能です
この部分はケルベロスネットワークセキュリティシステム、バージョン4 に関 するものです。ケルベロス バージョン5は前節で説明されているように、 GSSAPI 一般ネットワークセキュリティインターフェースを通して使用するよ うになっています。
このためには、
ケルベロスの支援を受けるように CVS をコンパイルする必要があります。
CVS は configre 時に
ケルベロスが利用できるかどうかを検出しようとしますが、
駄目ならフラグ --with-krb4 を用いて強制させることも可能です。
既定状態では、データ転送は暗号化されません。
クライアントとサーバ双方を、
暗号化を有効にしてコンパイルしておく必要があります。
構築時に --enable-encryption オプションを付加して、
暗号化機能を有効にして下さい。
また暗号化を要求するために、
使用時に広域オプション -x を付加する必要があります。
サーバの inetd.conf を編集する必要があります。
クライアントが使用する既定のポート番号は 1999 です。
他のポートを使用したい場合には、
クライアントの環境変数 CVS_CLIENT_PORT で指定して下さい。
CVS を利用する前に、
通常の方法で切符を取得して下さい (一般的には kinit です)。
この切符でサーバへのログインが許可されるはずです。
これで準備ができました:
cvs -d :kserver:faun.example.org:/usr/local/cvsroot checkout foo
ここで接続に失敗した場合、 以前のバージョンの CVS は rsh で再接続を試みましたが、 このバージョンでは再試行されません。
この接続方法で、ローカル・ディスクのリポジトリに遠隔プロトコルを使って
接続することができます。言い換えると、それは :local: とほとんど
同じことをしますが、変な振舞いや、バグやその他のものはローカルの
CVS のものではなく、遠隔 CVS のものです。
毎日の作業では、:local: か :fork: を好むかは個人の好みに
依ります。もちろん :fork: は cvs と遠隔プロトコルをデバッ
グしているときは特に役立ちます。特に、我々は他の遠隔アクセス方法のネッ
トワーク関連の設定、変更、時間切れ設定、認証全てを避けることができ、そ
の上で遠隔プロトコルを使う接続を作成することができるのです。
fork 方法を用いて接続するためには、:fork: とローカルのリ
ポジトリへのパス名を使用します。例えば、:
cvs -d :fork:/usr/local/cvsroot checkout foo
:ext: と同様に、サーバは既定値の cvs と呼ばれるか、
CVS_SERVER 環境変数の値になります。
パスワード認証サーバを使っている人に読み込み専用リポジトリ接続を認める ことができます (see Password authenticated)。 (他の接続方法は全て リポジトリマシンへのログイン接続を仮定していて、ローカルのファイル使用 許可が認めるものは何でもできるので、読み込み使用者のための明示的な援助 はありません。)
読み込み専用接続の使用者は、特定の "管理" ファイル (ロックファイルや 履歴ファイル) を除いて、リポジトリを変更しない CVS の操作のみを実 行できます。この機能を使用者の別名付けと一緒に使うことが望ましいでしょ う (see Password authentication server)。
以前のバージョンの CVS と違って、読み込み専用使用者はリポジトリを 読むことができるだけで、サーバのプログラムを実行できないようになってい るはずです。そうしないと、予期しないレベルの接続を得ることができてしま います。もしくは、より正確に言うと、既知の穴は塞がれました。こ の機能は新しく、包括的なセキュリティ審査がなされていませんので、セキュ リティへの関心に従って、どのような程度の注意も払うべきというのは正当の ようです。
使用者に読み込み専用を指定するためには、2つ方法があります: 包含と排除 です。
"包含" は、使用者を特別に $CVSROOT/CVSROOT/readers ファイルに一
覧表示するということで、それは単純な改行で分離された利用者の一覧です。
これは readers ファイルの例です:
melissa splotnik jrandom
(最後の使用者の後の改行を忘れないでください。)
"排除" は 書き込み 接続のできる人を全て明示的に一覧表示するとい うことです--もしファイル
$CVSROOT/CVSROOT/writers
が存在すると、それに挙げられている使用者だけが書き込み接続ができ、その
他の人は読み込み専用接続になります (もちろん、読み込み専用使用者も、相
変らず CVS passwd ファイルに挙げられている必要があります。)
writers ファイル は readers ファイルと同じ書式です。
注意: CVS passwd ファイルが cvs の使用者をシステムの使用者
にマップしているときは、cvs の使用者名を使って書き込み専用接続
を拒否したり認めたりしていて、システムの使用者名を使っていないことを確
認してください。すなわち、readers と writers ファイルに
cvs の使用者名があるということで、それはシステムの使用者名と同じかもし
れませんし、違うかもしれません。
これは読み込み専用接続か読み込み書き込み接続かを認めるかに関するサーバ の振舞いの完全な説明です。
readers が存在して、この使用者がそこに挙げられていれば、読み込
み専用接続になります。もしくは、writers が存在していて、使用者
がそこに挙げられていなければ読み込み専用接続になります (readers
が存在するけれど、そこには挙げられていないというときにもそのようになり
ます)。その他の場合では、完全な読み込み書き込み接続になります。
もちろん、使用者が両方のファイルに挙げられていれば、衝突が発生します。 これはより保守的な方法で解決されます。リポジトリの保護は少なすぎるより 多すぎるほどの方が良いですので: そのような使用者は読み込み専用接続にな ります。
CVS サーバは実行中に一時ディレクトリを作成します。それは
cvs-servpid
のような名前で、pid はサーバのプロセス番号です。それらは環境変数
TMPDIR (see Environment variables)、-T 広域オプショ
ン (see Global options)、で指定されるディレクトリもしくは、それら
がないと /tmp に置かれます。
ほとんどの場合は、通常終了か異常終了かに関わらず、サーバは終了時に一時 ディレクトリを消去します。しかし、サーバが一時ディレクトリを消去できな い場合がいくつかあります。例えば:
kill -KILL)。
このような場合は、手で cvs-servpid ディレクトリを消去する
必要があります。プロセス番号 pid で動いているサーバが無ければ、
その行為は安全です。
ファイルの改名とディレクトリ間の移動はうまくできないので、 新しいプロジェクトを始めるときには、 最初にファイルの構成をよく考えておく必要があります。 ファイルの改名や移動は、 不可能ではありませんが非常にやっかいです。 特にディレクトリの改名に関して、 CVS は癖のある動作をします (see Moving files)。
次に何をするかは、始める状況に依ります。
始めの一歩は、リポジトリ中にファイルを生成することです。 これには幾つか異なる方法があります。
CVS を使い始める場合に、
おそらく CVS を使用できるプロジェクトが
既に幾つかあるでしょう。
この場合 import コマンドを使用するのが最も簡単です。
例を挙げて説明します。
CVS に組み込みたいファイルが wdir にあり、
それを $CVSROOT/yoyodyne/rdir に置きたい時、
次のようにします。
$ cd wdir $ cvs import -m "Imported sources" yoyodyne/rdir yoyo start
-m フラグでログ・メッセージを与えなかった場合、CVS により
エディタが開かれ、メッセージの入力が促されます。文字列 yoyo は
ベンダー・タグと呼ばれるものであり、
start はリリース・タグと呼ばれるもの
です。この文脈では意味をなさないかもしれませんが、CVS はそれらの
存在を要求します。詳しくは See Tracking sources.
では実際に動作したことを確かめた後、元のソースディレクトリを削除します。
$ cd .. $ mv dir dir.orig $ cvs checkout yoyodyne/dir # 下で説明 $ diff -r dir.orig yoyodyne/dir $ rm -r dir.orig
誤って CVS を通さないで編集してしまわないように、下のソースを削除 すると良いでしょう。もちろん削除する前に、ソースのバックアップを取るの が賢明です。
checkout コマンドはモジュールの名前 (以前の全ての例のように)、
または $CVSROOT からの相対パス (上の例のように) を引数に取りま
す。
CVS が $CVSROOT 中のディレクトリに設定した
使用許可とグループ属性が、
適切かどうか調べると良いでしょう。See File permissions.
取り込みたいファイルの中にバイナリ・ファイルが含まれる場合、 wrapper 機能を用いて、どのファイルがバイナリなのか 明示するとよいでしょう。See Wrappers.
RCS 等の、 他のバージョン管理システムで保守されてきたプロジェクトがあり、 そのプロジェクトのファイルを CVS に移管する場合、 各ファイルの修正履歴の維持を望むでしょう。
foo.c という名前のファイルには、
RCS/foo.c,v という RCS ファイルが対応します
(他の場所にあるかもしれませんので、
詳細は RCS の文書を調べて下さい)。
次に、CVS リポジトリに適当なディレクトリを作成して下さい。
そして CVS リポジトリの当該ディレクトリに、
ファイルをコピーして下さい
(リポジトリ中のファイル名は、
ソース・ファイルに ,v が付加されたものでなくてはならず、
またファイルは RCS サブディレクトリではなく、
当該ディレクトリに直接置いて下さい)。
この例のように、CVS コマンドを利用せず、
CVS リポジトリを直接利用するほうが適当な場合が稀にあります。
以上で作業コピーを新たに取り出す準備ができました。
RCS ファイルを CVS に移動するときに、
ロックされていてはいけません。
ロックされている場合には、CVS での操作に支障を来します。
それが駄目なら、おそらく一番良いのは他のシステムのコマンド行のインター
フェースを使って一回に一つのリビジョンを取り出し、それを CVS に格
納するスクリプトを書くことでしょう。下の sccs2rs スクリプトはそ
のために役に立つ例でしょう。
contrib ディレクトリの中に、
sccs2rcs という名前のスクリプトがあります。
これを用いて SCCS ファイルを RCS ファイルに変換できます。
注意: SCCS と RCS の両方を持つマシンで実行する必要があり、
また contrib 内の他の全てと同様に動作保証はされません
(使用者によって評価は異なるでしょう)。
contrib ディレクトリの中に、
pvcs_to_rcs という名前のスクリプトがあります。
これを用いて PVCS アーカイブを RCS ファイルに変換できます。
PVCS と RCS のあるマシンで実行する必要があり、
また contrib 内の他の全てと同様に動作保証はされません
(使用者によって評価は異なるでしょう)。
詳細はスクリプト中のコメントを読んでください。
新しいプロジェクトを始める場合、 まず次のように空のディレクトリを作ります。
$ mkdir tc $ mkdir tc/man $ mkdir tc/testing
その後 import コマンドを使って、
リポジトリに各々の (空の) ディレクトリを登録(作成)します:
$ cd tc $ cvs import -m "Created directory structure" yoyodyne/dir yoyo start
そして add コマンドで、
ファイル (と新しいディレクトリ) を加えていきます。
その時、 $CVSROOT の中のファイルの使用許可が、
正しいものかどうかを確認すると良いでしょう。
二歩目は modules ファイルにモジュールの定義をする事です。
必ずしも必要ではありませんが、
関連するファイルやディレクトリをグループ化するのに便利です。
モジュールを定義する簡単な手順を示します。
$ cvs checkout CVSROOT/modules $ cd CVSROOT
tc を定義するには次の行を加えます:
tc yoyodyne/tc
$ cvs commit -m "Added the tc module." modules
$ cd .. $ cvs release -d CVSROOT
CVS の多くの利用ではあまりリビジョン番号について心配する必要はあ
りません。CVS は 1.1, 1.2 などのような番号を割当て、
それだけが皆が知る必要のあることです。しかし、CVS がリビジョン番
号を割当てる方法に関してより知識を持ち、より制御したい人もいます。
どのリビジョンが特定のリリースになったか、などの 1 つより多くのファイ ルを含むリビジョンの組を追いかけたいときは、タグ を使います。そ れはそれぞれのファイルの数字リビジョンに割当てることのできるリビジョン 名です。
各バージョンのファイルはそれぞれ一意なリビジョン番号
(revision number) を持ちます。
1.1, 1.2 とか 1.3.2.2 とか
1.3.2.2.4.5 なんてのもあります。
リビジョン番号はピリオドで分けられた偶数個の十進整数です。
初期設定ではファイルの最初のリビジョンは 1.1 で、
リビジョンが新しくなると一番右の番号が1つ増えます。
次の絵は、新しいリビジョンを右にして少しリビジョンを図示しています。
+-----+ +-----+ +-----+ +-----+ +-----+
! 1.1 !----! 1.2 !----! 1.3 !----! 1.4 !----! 1.5 !
+-----+ +-----+ +-----+ +-----+ +-----+
2 つ以上のピリオドを含む番号になることもあります。例えば、
1.3.2.2 です。そのようなリビジョンは枝のリビジョンを表します
(see Branching and merging)。そのようなリビジョン番号は
Branching and merging で詳しく説明されています。
上の説明のように、ファイルは複数のバージョンがあります。同様に、ソフト
ウェア製品も複数のバージョンを持つことができます。ソフトウェア製品はよ
く 4.1.1 のようなバージョン番号を付けられます。
バージョンには二つの意味があり、 最初のものはこの文書でリビジョンと呼ばれるものです。 二番目はリリースと呼ばれるものです。 混乱を避けるために、 この文書ではなるべくバージョンという単語は使わないようにします。
初期設定では、CVS は最初の番号を同じにして 2番目の番号を増加させ
ることにより数字リビジョンを割当てます。例えば、1.1,
1.2, 1.3 のように。
新しいファイルを加えるときは、2番目の番号は常に 1 で、最初の番号はその
ディレクトリの中のファイルの最初の番号の一番大きいものと等しくなります。
例えば、現在のディレクトリの一番大きい番号が 1.7, 3.1,
4.12 であると、追加されたファイルの数字リビジョンは 4.1
になります。
普通はリビジョン番号を気にかける必要はありません--それを CVS が
維持している内部番号のように扱う方が簡単で、タグは製品リリース 1 とリ
リース 2 のような間を区別するより良い手段です (see Tags)。 しかし、
数字リビジョンを設定したいのであれば、cvs commit の -r
オプションですることができます。-r オプションは -f オプ
ションを暗黙に仮定しますので、ファイルが修正されていなくても格納される
ということになります。
例えば、全てのファイルをリビジョン 3.0 にするためには (変更されていな いものも含めて)、次のように実行するかもしれません:
$ cvs commit -r 3.0
-r で指定する番号は存在するリビジョン番号より大きくなければなら
ないことに注意してください。すなわち、リビジョン 3.0 が存在していると、
cvs commit -r 1.3 とはできないということです。複数のリリースを
並行して維持したいときは、枝を使う必要があります (see Branching and merging).
リビジョン番号は開発に従って徐々に増えていきますが、 ソフトウェア製品のリリース番号とは全く何の関係もありません。 CVS の使い方にもよりますが、 異なる二つのリリースにおけるリビジョン番号は異なっているでしょう。 例えば RCS 5.6 を作るソース・ファイルは、 次のようなリビジョン番号を持ちます:
ci.c 5.21 co.c 5.9 ident.c 5.3 rcs.c 5.12 rcsbase.h 5.11 rcsdiff.c 5.10 rcsedit.c 5.11 rcsfcmp.c 5.9 rcsgen.c 5.10 rcslex.c 5.11 rcsmap.c 5.2 rcsutil.c 5.10
tag コマンドを使えば、
特定のリビジョンに名前 (タグ名) を付けることができます。
各ファイルに付けられた全てのタグと
対応するリビジョン番号を調べたい場合は、
status コマンドに -v フラグを付けて下さい。
タグには、大文字と小文字で始まる必要があり、大文字, 小文字, 数字,
-, _ が使用可能です。
BASE と HEAD の二つのタグ名は、
CVS が使用するために予約されています。
将来使われる CVS にとって特別な名前は、実際のタグ名との衝突を避け
るために BASE や HEAD などのような名前ではなく、例えば
. で始まるような特別な方法で命名されることが望まれています。
タグの命名にプログラムの名前とリリースのバージョン番号のような情報に基
いた何らかの習慣を選びたいでしょう。例えば、CVS 1.9 が cvs1-9
という名前でタグ付けされるように、まずプログラムの名前を使い、その直後
にバージョン番号の . を - に変更したものを続けるかもしれ
ません。同じ習慣を続ければ、常にタグが cvs-1-9 や cvs1_9
や他のものであったかを推測する必要はなくなります。taginfo ファイルでそ
の習慣を強制することさえ考えるかもしれません (see user-defined logging).
次の例は、ファイルにタグを付ける方法を示したものです。
コマンドはあなたの作業ディレクトリで実行して下さい。
すなわち、backend.c があるディレクトリでコマンドを実行すべきで
ある、ということです。
$ cvs tag rel-0-4 backend.c
T backend.c
$ cvs status -v backend.c
===================================================================
File: backend.c Status: Up-to-date
Version: 1.4 Tue Dec 1 14:39:01 1992
RCS Version: 1.4 /u/cvsroot/yoyodyne/tc/backend.c,v
Sticky Tag: (none)
Sticky Date: (none)
Sticky Options: (none)
Existing Tags:
rel-0-4 (revision: 1.4)
cvs tag の構文の完全なまとめと、いろいろなオプションの説明は
Invoking CVS を参照してください。
単独のファイルにタグを付けるべき理由はほとんどありません。 タグの主な使い途は、 モジュールを構成する全てのファイルに同じタグを付け、 開発の流れの重要点 (リリース時等) を示すことです。
$ cvs tag rel-1-0 . cvs tag: Tagging . T Makefile T backend.c T driver.c T frontend.c T parser.c
(CVS に対する引数にディレクトリを指定した場合は、 そのディレクトリに含まれる全てのファイルにタグが付けられます。 そのディレクトリ以下の全てのサブディレクトリに対しても (再帰的に) 動作します。See Recursive behavior.)
checkout コマンドの -r フラグに、
モジュールから取り出すリビジョンを指定します。
このフラグを用いて、
モジュール tc のリリース 1.0 を作るソースを、
将来のいつでも簡単に復元することができます:
$ cvs checkout -r rel-1-0 tc
リリース時にタグを付けるようにしておけば、 過去のリリースにバグが発見されたが最新版には無い、 という場合などに非常に便利です。
任意の時間を指定してモジュールを復元することもできます。
See checkout options. -r をこれらのコマンドのどれかに指定す
るときは、貼り付きタグに注意する必要があります。Sticky tags 参照。
複数のファイルに同じタグを付けるという事を、 「ファイル名とリビジョン番号の行列の中に線を引く」 と考えると良いでしょう。 以下のリビジョンの五つのファイルがあるとしましょう:
file1 file2 file3 file4 file5
1.1 1.1 1.1 1.1 /--1.1* <-*- TAG
1.2*- 1.2 1.2 -1.2*-
1.3 \- 1.3*- 1.3 / 1.3
1.4 \ 1.4 / 1.4
\-1.5*- 1.5
1.6
過去の何らかの時点で、
* の付けられたバージョンにタグが付けられています。
上図では * の付いたリビジョンにタグが付けられています。
仮にタグ名を「タグ付きリビジョンを結んだ紐」と考えると、
checkout の -r は
「紐を引くとタグ付きリビジョン全てが釣れる」などと解釈できるでしょう。
あるいはタグ付きリビジョンを水平に並べた方が、分り易いかも知れません:
file1 file2 file3 file4 file5
1.1
1.2
1.1 1.3 _
1.1 1.2 1.4 1.1 /
1.2*----1.3*----1.5*----1.2*----1.1 (--- <--- ここを見る
1.3 1.6 1.3 \_
1.4 1.4
1.5
前の節の例は、どのリビジョンにタグを付けるかを選ぶ一番普通の方法を表し
ています。つまり、引数無しの cvs tag コマンドでは、CVS は
現在の作業ディレクトリに取り出されたリビジョンを選択します。例えば、作
業ディレクトリの backend.c がリビジョン1.4から取り出されたので
あれば、CVS はリビジョン1.4にタグを付けます。タグはリポジトリのリ
ビジョン1.4にすぐに適用されることに注意してくさい。タグ付けはファイル
の修正とは違いますし、まず作業ディレクトリを修正してそれから cvs
commit を実行して修正をリポジトリに送信するような他の操作とも違います。
cvs tag がリポジトリに作用するという事実による、もしかすると驚
くかもしれない側面に、格納されたリビジョンにタグを付けていて、それは作
業ディレクトリにあるローカルで修正されているファイルと違うかもしれない、
というものがあります。間違ってそうしてしまわないようにするには、
cvs tag に -c オプションを指定します。もしローカルで修正
されたファイルがあれば、CVS はファイルをタグ付けする前にエラーを
出し、異常終了します:
$ cvs tag -c rel-0-4 cvs tag: backend.c is locally modified cvs [tag aborted]: correct the above errors first!
cvs rtag コマンドは特定の日付や時間のリポジトリにタグを付けます
(もしくは最新のリビジョンにタグを付けることに使うことができます)。
rtag はリポジトリの内容に直接作用します (コマンドの前に取り出す
ことを要求しませんし、作業ディレクトリを見に行きません)。
以下のオプションはタグを付ける日付やリビジョンを指定します。完全な説明 は Common options 参照。
-D date
-f
-D date や -r tag と一緒のときにだけ役に立ち
ます。合致するリビジョンが見つからなければ、(ファイルを無視する代わり
に) 一番新しいリビジョンを使います。
-r tag
cvs tag コマンドは同じ -r, -D, -f オプショ
ンを使って、ファイルをリビジョンや日付により指定することもできるように
なっています。しかし、この機能はおそらくあなたが望むものではないでしょ
う。その理由は、cvs tag は与えられたタグ/日付ではなく、存在する
作業ディレクトリに基づいてタグを付けるファイルを選ぶからです。ですから、
普通は cvs rtag を使う方がうまくいくでしょう。例外はこのような
場合です:
cvs tag -r 1.4 backend.c
普通はタグを修正しません。それはリポジトリの履歴を記録するために存在し ており、削除したり意味を変えたりすることは、普通は望むことではないでしょ う。
しかし、一時的にタグを使用したり、偶然に間違った場所に付けてしまったり する場合もあるでしょう。ですから、タグを削除、移動、改名するかもしれま せん。警告: この節のコマンドは危険です。それは履歴情報を永遠に捨て去り、 エラーからの復帰が難しくなるか、不可能になります。あなたが CVS の 管理者なら、これらのコマンドを taginfo で制限することを考えるかもしれ ません (see user-defined logging)。
タグを削除するには、-d オプションを cvs tag か
rtag に指定します。例えば:
cvs rtag -d rel-0-4 tc
はモジュール tc からタグ rel-0-4 を削除します。
移動 とは、同じ名前を違うリビジョンを指すようにすることです。例
えば、stable タグは現時点で backend.c のリビジョン1.4を
指しており、おそらくそれをリビジョン1.6を指すようにしたいと思っている
かもしれません。タグを移動するには、-F オプションを cvs
tag かcvs rtag に指定します。例えば、今書いた作業は以下のもの
で達成できます:
cvs tag -r 1.6 -F stable backend.c
タグの 改名 とは、違った名前を古いタグと同じリビジョンを指すよう
にすることです。例えば、タグ名の綴りを間違えて、修正したいと思っている
かもしれません (できれば他の人が古い綴りに頼る前に)。タグを改名するた
めには、まず -r オプションを cvs rtag に与えて新しいタグ
を作り、それから古い名前を削除します。これは新しいタグを古いタグと全く
同じファイルにつけることになります。例えば:
cvs rtag -r old-name-0-4 rel-0-4 tc cvs rtag -d old-name-0-4 tc
タグ付けがどのようにファイルの追加と削除と関連して動作するかの正確な議 題は少し複雑です。たいていの場合、CVS はファイルが存在したかどう かをたいして苦労することなく追い掛けることができます。既定では、タグは タグ付けされたリビジョンに対応するファイルだけに適用されます。ファイル がまだ存在していないか、既に削除されていると、単にタグを省略し、 CVS はタグが無いものは、そのタグではファイルが存在しないという意 味に扱うことを知っています。
ところが、これは少し情報を失います。例えば、ファイルが追加されて、それ
から削除されたとしましょう。そして、タグがそのファイルになければ、その
タグがファイルの追加前のときか、削除の後かどちらを参照するかを知る方法
はありません。-r オプションを cvs rtag に指定すれば、
CVS は削除されたファイルにタグを付け、この問題を回避することがで
きます。例えば、先頭のリビジョンにタグを付けるために -r HEAD を
指定するかもしれません。
ファイルの追加と削除という題に関して、cvs rtag コマンドには他の
方法ではタグ付けされない、削除されたファイルのタグを消去する -a
オプションがあります。例えば、タグを移動しているときに -F と共
に指定するでしょう。-a 無しでタグを移動すれば、削除されたファイ
ルはファイルが削除されたという事実を反映せずに、まだ古いリビジョンを参
照しているでしょう。私は上に書いてあるように -r が指定されてい
るときはこれは必要ではないと思います。
作業コピーのリビジョンには関連した追加のデータがあることがあります。例
えば、枝であったり (see Branching and merging)、checkout -D
か update -D によって特定の日時より前のバージョンに制限されてい
るかもしれません。このデータは永続しますので - すなわち、作業コピーの
残りのコマンドに適用されます - 我々はそれを 貼り付けられた と表
現しました。
たいていの場合、貼り付きは考える必要のない CVS の隠れた側面です。 しかし、この機能を使いたくないとしても、貼り付けられたタグに関して 何か 知る必要があるかもしれません (例えば、それを避ける方法!).
貼り付いたタグ (sticky tag) や日付を調べるには、
status コマンドを使用します:
$ cvs status driver.c
===================================================================
File: driver.c Status: Up-to-date
Version: 1.7.2.1 Sat Dec 5 19:35:03 1992
RCS Version: 1.7.2.1 /u/cvsroot/yoyodyne/tc/driver.c,v
Sticky Tag: rel-1-0-patches (branch: 1.7.2)
Sticky Date: (none)
Sticky Options: (none)
作業ファイルに貼り付いたタグは、
cvs update -A を使って削除するまで残ります。
オプション -A は、ファイルを幹の先頭のバージョンに戻し、
貼り付いたタグ, 日付, オプションを全て剥します。
貼り付けられたタグの一番普通の使用法は、Accessing branches で説
明されているようにどの枝で作業しているかを確認することです。しかし、枝
でない貼り付きタグにも利用法はあります。
ここでは、他人の変更が安定しているかどうか分らないので、
作業ディレクトリを更新したくない場合を例に挙げて考えます。
もちろんこの場合、cvs update の実行を控えれば済みます。
しかし、更新したくないのが大きなツリー構造の一部分だけならば、
そこにリビジョンを貼り付ければ良いのです。
ソースを取り出す際に (1.4 などと) リビジョンを指定すれば、
そのリビジョンを貼り付けることができます。
以後、cvs update -A によってタグを剥がすまで、
cvs update を実行しても
最新リビジョンに更新されることはありません。
同様にオプション -D を update や checkout に使うと、
貼り付いた日付 (sticky date) が設定され、
これ以降のコマンドにその日付が与えられます。
古いバージョンのファイルを取り出す際に、
タグを貼り付けたくない場合も多いと思います。
checkout や update にオプション -p を付けると、
ファイルの内容が標準出力に送られるので、これを利用します。
例えば:
$ cvs update -p -r 1.1 file1 >file1 =================================================================== Checking out file1 RCS: /tmp/cvs-sanity/cvsroot/first-dir/Attic/file1,v VERS: 1.1 *************** $
しかし、あなたの尋ねていることが前の格納に戻す (この例では、
file1 をリビジョン1.1であったときに戻す) 方法なら、これが一番簡
単な方法ではありません。その場合は update -j オプションを
update に付けるのが良いでしょう。さらなる議論は、Merging two revisions 参照。
CVS では変更を 枝 (branch) として知られる別の開発ラインに 分けることができます。枝のファイルを変更しても、その変更は幹や他の枝に は現れません。
後程、マージ (merging) によって変更をある枝から別の枝 (も
しくは幹) に移動することができます。マージはまず cvs update -j
を実行して、変更を作業ディレクトリに混ぜることから始まります。それから
そのリビジョンを格納することができ、こうして効果的に変更を別の枝にコピー
することができます。
tc のリリース 1.0 ができたとしましょう。tc の開発を継続していて、数ヶ 月の間にリリース 1.1 を作成する計画を立てています。しばらくして、顧客 が致命的なバグについて文句を言ってくるようになりました。リリース 1.0を 取り出し (see Tags)、バグを見つけました (結局些細な修正に終わりま した)。しかし、ソースの現在のリビジョンは流動的で、少くとも1ヶ月は安定 しない状態です。最新のソースに基づくバグ修正リリースはとても作成できま せん。
この様な状況でするべきことは tc のリリース 1.0 の全てのファイルのリビ ジョンツリーに基づく 枝 (branch) を作成することです。そう すれば幹の邪魔をすることなく枝に修正を加えることができます。修正が終わっ たときに、幹に取り込むか、枝に残しておくかを選択することができます。
tag -b で枝を作成することができます。例えば、作業コピーのところ
にいるとしましょう:
$ cvs tag -b rel-1-0-patches
これは作業コピーの現在のリビジョンに基づいた枝を別に作成し、その枝に名
前 rel-1-0-patches を割当てます。
枝はリポジトリに作成されているのであって、作業コピーに作成されているの ではないということを理解することは重要です。上記の例の様に、現在のリビ ジョンに基づいた枝を作成することは、自動的に作業コピーを新しい枝に切り 換えることは しません。それをする方法に関する情報は Accessing branches を参照してください。
rtag を使って、作業コピーへの参照無しに枝を作ることもできます:
$ cvs rtag -b -r rel-1-0 rel-1-0-patches tc
-r rel-1-0 はこの枝がタグ rel-1-0 に対応するリビジョンを
根とするということを指定します。最新のリビジョンである必要はありません
- 古いリビジョンから枝を生やすことが役に立つことがしばしばあります
(例えば、他の部分は安定していることが知られている過去のリリースのバグ
を修正するとき)。
tag と同様に -b フラグは rtag に枝を作成するよう
に指示します (単なるリビジョン名ではなく)。rel-1-0 に対応する数
字リビジョン番号はファイル毎に違うことを注意してください。
ですから、命令の完全な効果は新しい枝を作成することです - モジュール
tc で、rel-1-0 でタグ付けされたリビジョンツリーを根元と
する - rel-1-0-patches という名前のものを。
2 つの方法のどちらかで枝を取得することができます: リポジトリから新しく 取り出すか、存在する作業コピーをその枝に切り換える方法です。
リポジトリから枝を取り出すには checkout をフラグ -r と、
その後に枝のタグ名を続けて起動します (see Creating a branch)。
$ cvs checkout -r rel-1-0-patches tc
もしくは、既に作業コピーを持っていれば、update -r で任意の枝に
切り換えることができます:
$ cvs update -r rel-1-0-patches tc
もしくは、それと等価な:
$ cd tc $ cvs update -r rel-1-0-patches
作業コピーが元々幹にあったか他の枝にあったかは関係ありません - 上のコ
マンドはそれを指定された名前の枝に切り換えます。普通の update
コマンドと同様に、update -r は全ての変更をマージし、衝突がどこ
で起こったかを知らせます。
一度特定の枝に結び付けられた作業コピーを手に入れると、指示しない限りそ こに残り続けます。これは、作業コピーから格納された変更はその枝に新しい リビジョンを加えますが、幹と他の枝には影響を及ぼさないということです。
作業コピーがどの枝であるかを知るために、コマンド status を使う
ことができます。その出力で、Sticky tag という名前の場所を探して
ください (see Sticky tags) - それは現在の作業ファイルに、もし枝が
あれば、それを教える CVS の方法です:
$ cvs status -v driver.c backend.c ================