uni/indexCVS

●CVSとは?
 Concurrent Version Systemの略。バージョン管理システムの一種。RCSやMS Visual SourceSafeの仲間。 最近ではSubversionに勢いを奪われつつある。
●バージョン管理システムとは?
 ファイル(主にテキストファイル)の変更履歴・修正内容を保存しておいてくれる。 最先端で開発中にそこそこ古い版のバグ修正の仕事が舞い込んできたときなどに、古い版のソースファイルを取得して修正することができる。いつバグが紛れ込んだかを調べることもでき、さらに修正を最新の版に更新させることもできる。 現代のプログラム開発では使用するのが常識となっている。
●リポジトリ
 プログラムの変更履歴をすべて保持してあるデータベース。 CVSの場合は1ファイルにつきひとつRCSファイルが記録される形になっている。
●リポジトリの作成
cvs -d リポジトリを置く場所 init

Windows上でCygwin版CVSを使う場合は、改行コードに気を使った方がいい(後述)。

●リポジトリの指定
 CVSROOT環境変数か、-d グローバルオプションで指定する。一度チェックアウトすると CVS/Root というファイルにリポジトリが記録されるため、-d を使ってCVSROOT以外の場所からチェックアウトした場合、以後の操作ではチェックアウト時に指定したリポジトリが使用される。
●作業コピーの操作
 実際のファイルの編集は「作業コピー」で行う。 既存のリポジトリを使う場合はそのリポジトリからファイル一式をチェックアウトする。 新しいリポジトリを使う場合はファイルを追加していかなければならない。 インポートと追加があるが、個人的には追加の方が好き。

 追加の場合は最初にディレクトリをチェックアウトしておく必要があるが、リポジトリにディレクトリがなければそもそもチェックアウトができない。 こんなときはリポジトリ側にディレクトリをmkdirで作ってしまってチェックアウトするとよい。 リポジトリを直接操作できれば、の話だが。

 チェックアウトしたら、普通に編集し、終わったらチェックイン cvs ci する。 これでリポジトリに反映され、他のマシンから更新することで変更されたファイルを取得できる。 逆に、他のマシンでチェックインされたファイルを取得したい場合は更新 cvs up を行う。

 詳しくは CVS - よく使うコマンドを参照。

●キーワード展開
 ファイル中に $Id$ などと書いておくと、それを自動でいろいろなものに展開してくれる。 $Id$ の例はこのページの一番下を参照のこと。

 他によく使うのは $Log$ だが、これは少し特殊で、例えば // $Log$ と書いておくと、その行から下にチェックインするたびにずらずらとログが入る。 そのときに各行の先頭に $Log$ の前に書いてある文字列が入る。 つまり、この例だと各行の先頭が // になる。 C++などのコメントとしてソースに埋め込む場合に便利である。

●バイナリファイル
 バイナリファイルでキーワード展開が行われてしまうと、当然ファイルが壊れてしまう。 キーワード展開を抑制するためにはファイルを追加するときに -kb を指定する。後からも変えられたと思うけど、忘れた。 Cygwinの場合は -kb をつけると改行コードの変換も行われなくなる。 Unix系とソースファイルを共有している場合、Cygwinではテキストマウントされたディレクトリにチェックアウトすれば改行コードは勝手にCR+LFになるが、追加時に -kb が指定されていればそのファイルだけ変換が行われなくなるので、バイナリファイルも正しく扱えるようになる。
●リモートアクセス
 cvsサーバを使う方法やrshを使う方法があるが、sshが使えているならsshをトンネルとして使える。 サーバーの設定も不要でセキュリティ的にも有利である。 リポジトリパスを :ext:user@server.host:/path/to/repository の形で指定すると server.host 上の /path/to/repository をアクセスするようになる。 デフォルトでは rsh が使われるのだが、環境変数 CVS_RSH に ssh を指定しておくとsshをトンネルとして使うようになる。 Cygwinのsshも使えるが、PuTTYのplinkを使った方がいろいろと楽である。

page topTips

●リポジトリのパーミッション
 ファイルを新たにaddしてciすると、リポジトリ側では444か555なファイルができる。444になるか555になるかは、チェックインしたファイルがu+xになっているかどうかによる。オーナー・グループは普通にファイルを作った時と同じになる(と思う)。この場合、sは保存されない。

 ここからパーミッションをいぢってもよい。意味があるのはr/x/sビット。wは何をやっても意味がない。CVSはRCSファイルを読み、消し、新しく書き込む(だけらしい)ので、ディレクトリにwがあれば、RCSファイルにwがなくてもチェックインはできる。tは試してない(し、使えたとしてもあんま意味がない気がする)。パーミッションはその後のciでも保存される。

 ディレクトリをaddすると、リポジトリ側では常に775でできあがるので、アクセスに制限をかけたい場合はあとで適宜変更する必要がある。リポジトリをCVSで読む場合でもディレクトリへの書き込み権限が必要(ロックファイルを作るから)なことに注意。これはつまり、読み出し専用のアカウントは普通にやったのでは作れないということも意味している。

 ちなみに、LinuxとBSDでは新たにディレクトリを作った場合のグループが違うので注意。Linuxでは作った人(プロセス)の実効GIDで作成される。setgidした場合は親ディレクトリのGID。BSDは常に親ディレクトリのGIDになる。さらにさらに、BSDの場合はディレクトリがsetuidされていると以下のファイル・ディレクトリは全部親ディレクトリのUIDで作成される(いろいろ制限があるようですが)。LinuxでCVS使ったことないからCVSで実際にどうなるかは知らん。

●作業コピーのパーミッション
 リポジトリのRCSファイルがu+rの場合はu+rw、g+rの場合はg+rw、o+rの場合はo+rwが仮定され、さらにumaskが適用されてファイルが作成される。普通はumask 022だろうから、644なファイルができあがることになる。xとsはリポジトリのものがそのまま使われる。tは知らん。だから、750なファイルをaddしてどこか他でcoすると、リポジトリ上では勝手に555になるから、チェックアウトすると755なファイルができあがる。750のままcoしたい場合は、addした後にリポジトリを直接いぢってパーミッションを550に変える必要がある。

 その後のciやupなどでは、作業ファイルの変更が生じた時にパーミッションが上記のルールで変更される。だから、$Id$ などのRCSキーワードが入っていなければチェックインしてもパーミッションは元のまま。入っているとキーワード展開時にパーミッションが変更される。

 ディレクトリの場合は777にumaskを適用したものになる。リポジトリのパーミッションは一切無視。770や750な作業ディレクトリを作りたい場合は、チェックアウト後に手でパーミッションを変更する必要がある。

●リポジトリの場所が変更された
 リモートで使っている場合、DNSや/etc/hostsの力を借りて、cvs.example.jp のようなホスト名(エイリアス)を作っておけば、サーバーが変わってもそのまま使える。

 こういう細工をしてなかった場合や、リモートからローカル・ローカルからリモートに変更になった場合:

$ for i in `find . -name CVS`; do echo 新しいリポジトリの位置 > $i/Root; done

 リポジトリのパスが変わった場合:

$ for i in `find . -name CVS`; do echo 新しいリポジトリパス > $i/Repository; done

 この作業をやってくれるcvschrootというコマンドがあるらしい(使ったことないけど)。 (27 Dec 2015)

●既にファイルのあるディレクトリに重ねてチェックアウト
 やろうとすると、「it is in the way」とか文句を言われてコンフリクト状態になり、ciもupもdiffもできない状態になる。こういう場合は一度CVSディレクトリを削除して、どこか他の場所でチェックアウトし、そのCVSディレクトリを持って来ればよい。
$ for i in `find path/to/dst -name CVS`; do rm -rf $i; done
$ cvs co -d path/to/tmp module
$ cd path/to/tmp
$ for i in `find . -name CVS`; do mv $i path/to/dst/$i; done
$ cd path/to/dst

 あとは普通にup・diff・ciができる。リポジトリと作業コピーで内容が違うファイルはupするとタイムスタンプに関係なくM表示になる。全部リポジトリの内容にしたい場合は cvs up -C する。

page topWindowsからのアクセス

●使用するCVSクライアント
 Cygwinのcvsが利用できる。WinCVSなどのGUI版クライアントもある(ようだ)。
●使用するSSHクライアント
 Cygwinのsshの他、PuTTYが利用できる。PuTTYはplink.exeを利用する。plinkではホスト名にPuTTYセッション名が利用できるため、環境変数CVSROOTもホスト名部分にセッション名を書くことができる。PuTTYの場合、標準エラー出力(というかTTYかな?)の扱いがあいまいなため、パスフレーズ入力不要の状態(通常はエージェントを利用)にしておく必要がある。
●改行コード
 Unixの改行コードは一般的に0x0aの1バイト(通称LF)である。Windowsでは0x0d 0x0aの2バイト(通称CRLF)である。リポジトリ内では原則として0x0aの改行コードを使うので、改行コードを変換する必要がある。Cygwinのcvsを使っている場合、ソースファイルを置くディレクトリをテキストマウントすることで解決できる。mount -t Win32パス Cygwinパス でマウントできる。Admin権限がない場合、-uオプションも追加する。Unixシェルから実行する場合、Win32パスは\を二重に書くか、クオートする必要がある。
c:\> mount -t c:\cvs\src /home/cvs/src (Cygwin 1.5・コマンドプロンプトの場合)
c:\> mount -t -u c:\cvs\src /home/cvs/src (同上。Admin権限なし)
$ mount -t c:\\cvs\\src /home/cvs/src (Unixシェルの場合)
 マウント状態はレジストリに保存される。umountしない限り電源を切っても保持されている。 Cygwin 1.7からマウントのルールが変わったので、Cygwinのページを参照のこと。 特に、コマンドプロンプトからのマウントは意味をなさなくなったので注意。

 テキストマウントしたパス以下では、fopenなどでモードを指定しなかったファイルに対し改行コードの変換が行われる。モードを指定すればモードに従う。Cygwin版のcvsは、-kbを指定すると明示的にバイナリモードを使うようになり、そうでなければモード指定をしないようになっている。したがって、バイナリファイルは -kbを指定してリポジトリに登録すれば正しく扱える(忘れるとファイルが壊れる)。

●文字コード
 Unixでは日本語をEUCで表現する。WindowsではMS漢字(別名シフトJIS)で表現する。cvs的にはどちらの漢字コードを使っても大丈夫。コンパイルする環境に合わせればよい。ソースを共有する場合、コメント文字列をどちらかに統一しておいた方がよいだろう。文字定数・文字列はそもそも共通には使えないので、この部分はソースを分けるなどの工夫が必要である。EUC/SJISの変換を自動で行ってくれるパッチもあるようだ。コミット時のログメッセージはプロジェクトごとに統一した方がよい。統一しておかないとcvswebで困ったことになる。

 JISは文字列展開マークの$が文字コード空間内にあるため使用しない方が無難。

●ログメッセージ入力
 文字コードは適当にルールを作って統一しておいたほうがよい。EUCかSJISになるだろう。-mオプションでは日本語を入力しにくい。-mオプションを指定しないとエディタを立ち上げようとするが、エディタはCVSEDITOR環境変数で指定する。改行コードが0x0aなので、/tmpをテキストモードマウントするか、改行コード自動変換が可能なエディタを使用する。

 エディタは /tmp/ほげほげ という引数を伴って立ち上げられるため、Windows上のプログラムにはオプションに見えてしまう。また、このパスはCygwin内のパスなので、これをWindows内のパスに変換する必要がある。Cygwinにはcygpathというコマンドがあり、-wオプションを付けてCygwinのパスを与えると、Windowsのパスに変換してくれる。例えば、cygpath -w /tmp/test とすると、c:\cygwin\tmp が返ってくる。これをUnixシェルのバッククオート置換で使えばOKである。たとえば、こんなシェルスクリプトを作る。

#!/bin/sh
"/cygdrive/c/program files/hidemaru/hidemaru.exe" `cygpath -w $*`
 これをパスの通った位置にcvs-hidemaruなどという名前で置き、CVSEDITOR環境変数にcvs-hidemaruを設定すればよい(ちなみにこのスクリプトだとエディタが終了するまでスクリプトは待たされる=cvsは作業を先に進めない)。文字コードの統一については、rcsinfoで指定したテンプレートに意図的に日本語を仕込んでおき、文字コードを自動判別できるエディタを使えばよい。Windowsのメモ帳を使っている場合はSJISに統一することになるだろう。
●諸注意
 Cygwinのテンポラリディレクトリ(通常 /tmp、Win32パスだとc:\cygwin\tmp)がcvs使用ユーザーの権限で書き込み可能になっていないと特定のコマンドが利用できない(デッドロックする)模様。
●秀丸とCVS
 秀丸は「その他」→「プログラム実行」という機能があり、秀丸から任意のプログラムを実行できる。プログラムを実行する秀丸が何かファイルを編集している場合、プログラム実行時のカレントディレクトリはそのファイルがあるディレクトリになっている(秀丸から「ファイル」→「新規作成」した場合は元の秀丸のカレントディレクトリを引き継いでいる)。また、プログラムが32ビットプログラムで、標準出力に実行結果を書き出す場合、その結果を新しい秀丸に吐き出してくれる(選択範囲があった場合そこが置換される)。

 これを利用するといろいろ便利に使える。

 例えば、一時的に古いレビジョンのファイルを見たい場合、古いレビジョンを見たいファイルを秀丸で開く(もちろんこれは最新のファイル)。次に、見たいレビジョンを確認する。$Log$キーワードを使ってログメッセージを展開している場合、ログメッセージを見れば分かるだろう。

 分かったら、今ファイルを開いている秀丸で「その他」→「プログラム実行」とし、「コマンドライン」に「cvs up -p -r 取得したいレビジョン 取得したいファイル」と入力する。CVSはカレントディレクトリのリポジトリを使うので、今見ているファイルと同じリポジトリを見に行く。-pを付けると取得結果は標準出力に書き出されるよになる。つまり、結果は新しい秀丸の窓に吐き出される。コマンドプロンプトやリダイレクトのお世話にならず古いレビジョンのファイルを見ることができるので非常に便利である。

 あとはお好みで「その他」→「ファイルタイプ別の設定」でファイルタイプを選んで「保存しないで更新」すると見やすくなるだろう。さらに、「ウィンドウ」→「他の秀丸と内容比較」を使うと簡易diffにも使える。秀丸マクロの内部値キーワードbasenameを使い以下のようなマクロを組むとさらに便利になる。

$rev = input("レビジョンを指定してください");
run "cvs up -p -r " + $rev + " " + basename;

 diffの場合は、cvs -Q diff -u を実行すると diff の結果を新しい秀丸の窓に吐き出してくれる。強調表示を併用して、ハイフンで始まる行をグレー表示、+で始まる行を強調表示にするとdiff表示が非常に見やすくなる。

 また、

golinetop2;
beginsel;
golineend2;
copy;
right;
beginclipboardread;
run getclipboard;
こんなマクロをexec.macという名前で作っておくと、マクロを実行したときにカーソルがある行をコマンドとみなして実行してくれる。例えば、cvs -q up を実行すると追加されていないファイルが ? で表示されるので、これをコピペして編集して、頭に cvs add を付けてさらに exec.mac に突っ込むと、必要なファイルだけを一気に追加できる。Mが出てるファイルのうち一部だけをチェックインしたい場合も同様にできる。

page topWindowsだけで使う

 リポジトリをタダの共有ファイルにすれば、UnixマシンがなくてもCVSは使える。Unixマシンからこのリポジトリを見たい場合は、smbmountするか、そもそもUnixマシンが使えるのだから、リポジトリ全体をUnixマシンに移せばよい。

●準備
 とにかくCygwinを入れる。クライアント機だけでよい。もちろんcvsをインストールしておく。サーバー機でファイル共有の設定をし、リポジトリ用のディレクトリを作り、適切にアクセス権を設定する。
●マウント
 作業ディレクトリをテキストマウントするのはUnixがサーバーの場合と同じ。もう一つ、サーバーのリポジトリ用フォルダをマウントする必要がある。クライアント機にマウントポイント用のディレクトリを掘り(c:\cygwin\mnt\マシン名 あたり、Cygwin的には /mnt/マシン名 あたり、がよい。実は掘らなくても使えるがmountが警告を出す)、ここにバイナリモードでマウントする。一度ドライブを割り当ててドライブ名を使ってマウントしたり、さらにその上で/cygdrive/ドライブ名/ を使ったり、あるいはドライブを割り当てずに直接URN形式(\\hostname\sharename の形式)でマウントしたり、いろいろバリエーションがあるので、お好きな方法で。
●リポジトリを作る
> cvs -d /mnt/マシン名/cvsdb init

 この後、サーバーフォルダを確認するとよかろう。あとは普通に使える。

●おまけ
 ネットワークドライブをコマンドラインから割り当てる:
> net use ドライブ名: \\マシン名\資源名 /user:Winドメイン名\ユーザ名

 Winドメインを運用していない場合はユーザー名だけでよい。ローカルとリモートのパスワードが一致していれば、自動で割り当てが行われる。

page top応用

●ファイルの同期
 すべてのホストで cvs co しておき、あとはどこか適当なホストでファイルを編集し、cvs ci した後、同期を取りたいホストで cvs up すれば同期終了。WWWサイトの更新にも使える。好きなクライアントで編集・cvs ci したら、WWWサーバーへログインして cvs up とやるとサイトの更新が完了する。CVSという余計なディレクトリができる欠点がある。WWWサーバーなどの場合、CVSディレクトリがクライアントから見えないようにするとよい。
●cvsweb
 運用してみたこともあったけど、秀丸が便利なんでやめちゃった(笑)。 page top

Copyright (C) 1997-2015 akamoz.jp

$Id: cvs.htm,v 1.13 2018/10/27 05:42:25 you Exp $