■第3章 CVSの基本的な使い方 ■■3.1 リポジトリの作成 コマンドのインストールが済んだだけでは、CVSを使うことはできません。CVSがファイルを保存しておく場所であるリポジトリを作成する必要があります。リポジトリを作成するには、まず、余裕のある十分な空き領域を確保できるボリュームを選んでください。もし、たくさんのファイルをリポジトリに保管するつもりであれば、それなりの領域が必要です。筆者は、/homeを多めにとるので、/homeに置くことにしています。/usr/localなどに置く人もいるようです。 リポジトリの設置場所は任意で構いませんが、ここでは、/home/cvsrootというディレクトリを作り、このディレクトリをリポジトリにします。Windowsユーザは、C:\home\cvsrootというように、適宜読み替えてください。 Caution! 半角かな文字の取り扱いについて ちなみに、UNIXを起源とするツールを使うときは、フォルダ名に空白文字や漢字を含めないようにします。特に半角かなは厳禁です。トラブルの元になります。 ■■■3.1.1 UNIXでリポジトリを作成する リポジトリを作成するには次のコマンドを実行します【図3.1】。 【図3.1】リポジトリを作成する ▼ % cvs -d /home/cvsroot init ▲ まぁ、とりあえずおまじないだと思って実行してみてください。 次に、UNIXの場合はディレクトリの所有権設定に注意が必要です。まず、初期化自体そのユーザの所有権がなければいけません。そして、更に複数のユーザでリポジトリを共有する場合は、そのユーザが所属するグループに書き込み権限を発行する必要があります。ひとまずは、自分の書き込み許可だけでも出しておいてください。/homeに書き込み権限をもたない場合には、自分の領域に作ってください。複数ユーザでの共有のための設定については第6章で詳しく説明します。 ■■■3.1.2 WinCvsでリポジトリを作成する WinCvsでは、メニュー[作成(Create)]→[新しいリポジトリの作成(Create a new repository)]で表示されるダイアログで、CVSROOTの指定にc:\home\cvsrootを、認証の方法に、Local mounted directoryをそれぞれ指定すれば作成することができます。[OK]ボタンをクリックすると、ログメッセージ領域に次のような文字列が表示されます。 ▼ cvs -d :local:c:\home\cvsroot init ▲ このメッセージ内の:local:はUNIXでは省略しても問題はないのですが、Windowsだと、C:の「:」が引っかかるので、MS-DOSプロンプトで実行する場合には、:local:をつけておいてください。 なお、これ以降はUNIXコマンドのみを使用して説明していきます。WindowsでUNIXコマンドを利用するにはCygwinというパッケージが使えますが、ここで詳細は説明しません。RedHat社のサイトの一部であるhttp://sources.redhat.com/cygwin/をあたってみてください。 ■■■3.1.3 管理ファイルと環境変数の設定 無事に初期化が成功すると、/home/cvsrootの下にCVSROOTというディレクトリができます。ちょっと、lsで調べてみましょう【図3.2】。 【図3.2】リポジトリが初期化されているかな? ▼ % ls -a /home/cvsroot/ . .. CVSROOT % ls -a /home/cvsroot/CVSROOT . .#notify commitinfo history rcsinfo,v .#checkoutlist .#rcsinfo commitinfo,v loginfo taginfo .#commitinfo .#taginfo config loginfo,v taginfo,v .#config .#verifymsg config,v modules verifymsg .#cvswrappers .. cvswrappers modules,v verifymsg,v .#editinfo Emptydir cvswrappers,v notify .#loginfo checkoutlist editinfo notify,v .#modules checkoutlist,v editinfo,v rcsinfo ▲ CVSROOTディレクトリの中にはいろいろなファイルができていますね。これらのファイルは管理ファイルといいます。管理ファイルを設定することで、他のツールと連携したりといったことができるようになります。管理ファイルに関する詳細は、第5章を中心に説明します。 また、このリポジトリを常に使用するという場合は、環境変数CVSROOT(管理ファイルの置いてあるディレクトリのことではなく、リポジトリの方を指定するためのもの)を設定しておくと便利です。CVSROOTを設定しておかないと、cvsコマンドの実行のたびに、次のように使用するリポジトリを手動で設定しなければなりません。 ▼ cvs -d /home/cvsroot ... ▲ ですが、いくつかのリポジトリを使い分けている人は、いちいち指定したほうがよい場合もありますのでこれも好きずきです。UNIXとWindowsで環境変数CVSROOTを設定するには、次のようにします。 ■■■■UNIXの場合 UNIXの環境変数の設定は、以下のようにおこないます。 ◎CSH系のシェルを利用している場合 ▼ setenv CVSROOT /home/cvsroot ▲ ◎SHシェル系のシェルを利用している場合 ▼ CVSROOT=/home/cvsroot; export CVSROOT ▲ これらのどちらか適切な方を.cshrcや.profileなどの自分の初期設定ファイルに書き加えておけば、計算機の使用開始の度に設定する必要がなくなり便利でしょう。 ■■■■WinCvsの場合 WinCvsは前述のメニューで設定しておけば、毎回それを指定してくれるようになります。Windows NT/2000でCVSを単体利用している場合にはコントロールパネルから、Windows 95/98/MEの場合にはAUTOEXEC.BATに次のような行を追加します。 ▼ set CVSROOT=:local:c:\home\cvsroot ▲ ■■3.2 日常的なルーチンワーク リポジトリの作成が済んだら、基本的なCVSの使い方をみていきましょう。ここで、基本的な使い方というのは、日常的なルーチンワークで利用する最低限の操作のことです。CVSを用いたルーチンワークは【図3.3】に示すような流れになります。CVSでは、ディレクトリへひとまとまりにして登録されたファイル群をプロジェクトもしくはモジュールと呼びます。本書では一貫してモジュールという呼び方を使います。また、リポジトリ内でのモジュールのことを、英語ではrepositoryと呼んでいますが、紛らわしいのでモジュールと呼ぶことにしましょう。 【図3.3】ルーチンワークの流れ CVS-routine.gif Column ファイルの漢字コードの変換の設定の仕方 せっかくknjwrpのインストールの方法を説明したので、ファイルの漢字コードを変換する設定方法を説明するべきですよね。実は、初期設定そのままでは、ファイルの漢字コードは自動的に変換されません。リポジトリCVSROOT内の管理ファイルの1つであるcvswrappersファイルを編集して、特定の種類のファイルに対して変更する必要があります。なお、このファイルの設定方法については、第5章で詳細を説明します。 まず、元となるファイル群をリポジトリにモジュールとして登録(import)します。これはCVSでの管理開始時の一度だけです。登録後はリポジトリから、作業用のコピーを自分の作業領域に取り寄せます(checkout)。そしてそれらのファイルに対して作業をおこないます。ファイルが増えた場合には、追加(add)し、いらなくなった場合には、削除(remove)します。この時点では、これらの変更は作業用コピーへの変更にすぎません。それらの変更をリポジトリのファイル群に反映させなければなりません(commit)。 次に作業を再開する時、特に他の人と共同作業しているとか、別に作業コピーを持っている場合には、それらの変更を自分の作業コピーに反映させる必要があります(update)。この後は、ひたすら、update→(編集/add/remove)→commitを繰り返すことになります もし、開発メンバーから外れるなどその作業コピーがいらない状態になった場合、そのコピーを放棄(release)するとゴミが少なくなります。というのは、CVSは誰がcheckoutしたか覚えているので、取り寄せたままにしていると、そのログが残ってしまうのです。それが気にならないなら放っておいても構わないのですが、なるべく、releaseで放棄する癖をつけておいた方がよいと思います。第6章で説明するwatchコマンドによる通知機能とも少し関係します。特に共同作業をおこなう場合は、紛らわしいので、放棄するようにしてください。 これらのコマンドの概要と使用のタイミングを、【表3.1】にまとめておきます。 【表3.1】 コマンド 説明 使用のタイミング import リポジトリに新しいモジュールを登録するために使う 管理開始時 checkout リポジトリから作業用コピーを取り出すために使う 作業用コピーが必要になった時(プロジェクト参加時など) add 作業用コピーの状態ファイルにファイルの追加を登録するために使い、リポジトリへ反映するにはcommitが必要 新しくファイルまたはディレクトリを追加したとき remove 作業用コピーの状態ファイルにファイルの削除を登録するために使い、リポジトリへ反映するにはcommitが必要 ファイル(ディレクトリ)を削除したとき commit 作業用コピーにおこなった変更をリポジトリに反映させるために使う 作業が一段落したとき update リポジトリにおこなわれた変更を自分の作業用コピーに反映させるために使う 作業を再開するとき release その作業用コピーをもう使わないことをリポジトリに通知するために使う その作業コピーを放棄するとき(プロジェクト脱退時など) これから、順に例をあげて使い方を説明します。これらのコマンドは、CVSのコマンドに引数として渡されます。例えば、次のように実行することになります。 ▼ cvs ... import ... cvs ... add ... cvs ... commit ... ▲ ...はオプションなどいろいろ指定できることを意味します。正確には、【図3.4】のような書式になります。 【図3.4】cvsコマンドの使い方 ▼ cvs [全体にかかるオプション]コマンド[コマンドのオプションと引数] [対象ファイル群] ▲ [ ]で括った部分はあったり、無かったりするという意味です。 [全体にかかるオプション]はグローバルオプションとも言って、さっき出てきた-dのようなものを指します。-dはリポジトリを指定するためのオプションですが、ほかにもいろいろ指定することができます。 コマンドは、上記のimportやadd、commitというような作業内容を指定する記述です。これらのコマンドはコマンドごとに特有のオプションを持ち、[コマンドのオプションと引数]として指定することができます。オプションというのは無くてもなんとかなるもののことで、一方、そのコマンドを実行するのに必須であるものについては引数と呼んでいます。最後にそのコマンドを適用するファイル群を指定することができます。ちなみに、対象ファイルを指定しないと、コマンド利用者が今いるディレクトリ(カレントディレクトリ)が対象として選ばれます。もちろん、コマンドの中には、対象ファイルを必要としないものもあります。詳しくは、マニュアル文書やリファレンスなどを活用してください。オンラインでは、man cvs、cvs --helpと実行することで参照できます。 次節からは、具体的に例をあげてCVSの使い方を説明します。前述の理由によりバージョン1.10.8に基づいていますが、このあたりの基本的なコマンドは以前からほとんど変わってませんし、将来的にも大きな変更はないと思います。ただ、オプションの形式は変更される可能性がありますので、バージョンが異なる場合には、man cvsもしくはcvs --helpコマンドで使い方を確認してください。 ■■3.3 テストモジュールの登録 【図3.5】importコマンドの書式 ▼ cvs import [-d] [-k展開方法] [-Iファイルパターン] [-mメッセージ] [-bブランチタグ] [-Wパターン動作]モジュール名 ベンダータグ リリースタグ... ▲ 【図3.5】がimportコマンドの書式ですが、オプションはコメント記述のための-m以外は今の時点では使いません。-kと-wについては、4.2.5項で説明します。3つの引数、モジュール名、ベンダータグ、リリースタグは必須ですが、まったく個人で新しいモジュールを作る場合は、最初のモジュール名はともかく、ベンダータグ(つまりモジュール作成者の識別子)とか、リリースタグ(つまり外部向けのリリースバージョン)に何をつけるのか悩んでしまいます。 筆者は、ベンダータグには、ネットワークでの自分のあだ名mikamamaを、リリースタグにはそのモジュールの最初のバージョンということで、hoge_1_0というように適当につけてます。よそのモジュールを自分のリポジトリに登録する場合にはもちろん、そのベンダータグ(例えば、GNUとか)とリリースタグ(GNU2_8_0とか)をつければよいわけです。 ■■■3.3.1 空のモジュールを登録してみよう はじめは、何もない状態からはじめる場合を考えてみましょう。 【図3.6】空のモジュールを登録する ▼ % mkdir cvstest % cd cvstest % cvs import -m "CVS Test" cvstest mikamama cvstest_0_1 No conflicts created by this import % cd .. % rm -rf cvstest rm: examine files in directory cvstest (yes/no)? y rm: remove cvstest/test.txt (yes/no)? y rm: remove cvstest: (yes/no)? y ▲ まず適当なディレクトリ「cvstest」を作っています【1行目】。次に、空のディレクトリですが、そこに移動し、何もない状態を新規モジュールとして、cvstestというモジュール名で登録します【2-3行目】。モジュールに対するコメントをオプション-mとその引数"CVS Test"で指定しています。ちなみに、このオプション-mで渡された文字列は、本来ならばファイルに対応する変更履歴に対象ファイルの説明文として、埋め込まれます。つまり、importコマンドで新しく開始された変更履歴のファイルには最初にこの文字列がメッセージとして埋め込まれることになるわけです。しかし、空の場合は、ディレクトリには記録できないので、このメッセージはどこかへ消えてしまって、無視されるようです。空のディレクトリでモジュール登録するのは邪道なのかもしれません。 登録が確認できたら、そのディレクトリ自体には用がないので、もとのディレクトリに移動し、消去してしまいましょう【8行目】。どうせ空なんですし。 Caution! importコマンド利用時の注意 登録するディレクトリに移動し、importコマンドを実行していますが、importコマンドはカレントディレクトリを対象とするので注意してください。うっかり、登録するファイル群が入っているディレクトリの1つ上のディレクトリで実行してしまうと、思ったような結果が得られません(いえ、以前うっかり/home以下を全部importしかけただけなんですけどね。とほほ)。このディレクトリの名前に制限はありません。なんとなく、登録するモジュール名と同じ名前にしてますが、特に影響はありませんでした。 ■■■3.3.2 空じゃないモジュールを登録してみよう 前3.1.1項では空のモジュールを登録することからはじめてみました。では、登録するディレクトリ中に、ファイルやディレクトリがあった場合にはどうすればよいでしょうか? 悩む必要はありません。同じように指定すればよいのです。カレントディレクトリ以下全てが再帰的に登録されます。【図3.7】に適当にファイルとディレクトリを作成した、cvstest2というモジュールの例を示します。 【図3.7】カレントディレクトリ以下を再帰的に登録する ▼ % ls -RF .: dir1/ tmp1.txt tmp2.txt ./dir1: dir2/ tmp3.txt ./dir1/dir2: tmp4.txt % cvs -d /home/cvsroot import -m "CVS Test 2" cvstest2 mikamama cvstest2_0_1 N cvstest2/tmp2.txt N cvstest2/tmp1.txt cvs import: Importing /home/cvsroot/cvstest2/dir1 N cvstest2/dir1/tmp3.txt cvs import: Importing /home/cvsroot/cvstest2/dir1/dir2 N cvstest2/dir1/dir2/tmp4.txt No conflicts created by this import ▲ このように、途中まで作ったファイル群でも、CVSで管理したいなと思い立ったときには、いつでも登録することができます。なおそのようなときには、そのファイル群を適当に整理してから登録した方がよいでしょう。ファイルについては、後でremoveコマンドを使えば消去できますが、ディレクトリについてはそうはいきません。ディレクトリは一度作ってしまうと、基本的に消えないので、あらかじめ最低限にするようにしておきましょう。また、それまでのファイルは消してしまわずに、どこかにまとめてバックアップしておいたほうがよいと思います。少なくとも、checkuoutして無事登録されたファイルが取り出せることを確認するまでは、そのままにしておきましょう。 ■■■3.3.3 一体何が起こっているの? この状態で、リポジトリ/home/cvsrootを覗いてみると、【図3.8】のようになっているはずです。 【図3.8】/home/cvsrootを覗いてみる ▼ % ls -RF /home/cvsroot /home/cvsroot: CVSROOT/ cvstest/ cvstest2/ /home/cvsroot/CVSROOT: Emptydir/ commitinfo,v cvswrappers,v loginfo notify taginfo checkoutlist config editinfo loginfo,v notify,v taginfo,v checkoutlist,v config,v editinfo,v modules rcsinfo verifymsg commitinfo cvswrappers history modules,v rcsinfo,v verifymsg,v /home/cvsroot/CVSROOT/Emptydir: /home/cvsroot/cvstest: /home/cvsroot/cvstest2: dir1/ tmp1.txt,v tmp2.txt,v /home/cvsroot/cvstest2/dir1: dir2/ tmp3.txt,v /home/cvsroot/cvstest2/dir1/dir2: tmp4.txt,v ▲ tmp1.txt,vなどと、おしりに「,v」のついたファイルが、そのバージョン情報を溜めていくファイルです。RCSファイルと呼ばれています。興味がある人は各作業の後で、該当する「,v」ファイルの中身を覗いてみてください。ひとつのファイルに色々な情報が押し込まれていて、それが作業の影響によって変化していく様子がわかると思います。また、-mで指定した文字列「CVS Test 2」は各「,v」ファイルの最初に記録されています。確認してみてください。 ■■■3.3.4 まとめ ここで、新規モジュール登録(import)の流れを整理しておきましょう。新しく自分のモジュールをリポジトリへ登録する場合には、次のような流れになります。 登録するファイルとディレクトリをtarget_dirへ整理 ↓ cd target_dir ↓ cvs import -m "メッセージ"モジュール名 自分の名前 リリース名 ↓ バックアップして消去 cd ..; tar cpf target_dir.tar target_dir; rm -rf target_dir 続く3.4節では、リポジトリに登録したモジュールを、自分の作業領域に取り寄せる作業をおこないます。リポジトリがローカルホストに存在していても、同じ作業が必要です。 ■■3.4 テストモジュールを取って来る 次に登録したモジュールを作業コピーとして取ってきます。以後、その作業コピーを放棄するまで、作業はその作業コピー上でおこないます。作業コピーはいくつあっても構いません。自分の便利なように作業コピーを取り出してください。作業コピーをリポジトリから取り出すには、checkoutコマンドを使用します。バージョン管理システムの歴史的な経緯から、この作業コピーを取り出すことをチェックアウト(=checkout)と言います。本書でもこれ以降はチェックアウトという言葉を使用します。 【図3.9】checkoutコマンドの書式 ▼ cvs checkout [-ANPRcflnps] [-r rev | -D date] [-d dir] [-j rev1] [-j rev2] [-k kopt]モジュール群... ▲ このコマンドにもオプションが沢山あるのですが、通常は使いません。たまに、古い日付のファイルが使いたい時に-Dで日付を指定したり、開発用のサブブランチを取り出すために、-rでタグを指定したりすることがある程度です。 ■■■3.4.1 登録したモジュールを取り寄せる とりあえず、3.3節で登録したモジュールcvstestをチェックアウトしてみましょう【図3.10】。 【図3.10】cvstestを取ってくる ▼ % cvs checkout cvstest % ls -RF cvstest/ cvstest/: CVS/ cvstest/CVS: Entries Repository Root ▲ 空のプロジェクトcvstestには何かCVSというディレクトリができています。 続いて、cvstest2の方もチェックアウトしてみます【図3.11】。 【図3.11】cvstest2をチェックアウトする ▼ % cvs checkout cvstest2 cvs checkout: Updating cvstest2 U cvstest2/tmp1.txt U cvstest2/tmp2.txt cvs checkout: Updating cvstest2/dir1 U cvstest2/dir1/tmp3.txt cvs checkout: Updating cvstest2/dir1/dir2 U cvstest2/dir1/dir2/tmp4.txt % ls -RF cvstest2 cvstest2: CVS/ dir1/ tmp1.txt tmp2.txt cvstest2/CVS: Entries Repository Root cvstest2/dir1: CVS/ dir2/ tmp3.txt cvstest2/dir1/CVS: Entries Repository Root cvstest2/dir1/dir2: CVS/ tmp4.txt cvstest2/dir1/dir2/CVS: Entries Repository Root ▲ こちらでは、CVSというディレクトリが各サブディレクトリにもできています。CVSの中にはそれぞれ、「Entries」「Repository」「Root」という3つのファイルが入っていますね。 ■■■3.4.2 作業コピーの中のCVSディレクトリとは? CVSディレクトリの中のファイルをちょっと覗いてみましょう。ここではcvstest2/CVSの中身を見てみます。 cvstest2/CVS/Entries ▼ /tmp1.txt/1.1.1.1/Fri Dec 15 09:18:31 2000// /tmp2.txt/1.1.1.1/Fri Dec 15 09:18:31 2000// D/dir1//// ▲ cvstest2/CVS/Repository ▼ cvstest2 ▲ cvstest2/CVS/Root ▼ /home/cvsroot cvstest2/dir1/CVS/Repository cvstest2/dir1 ▲ どうも、「Entries」はそのディレクトリの中にあるファイルとディレクトリの情報を、「Repository」はそのディレクトリのリポジトリの中での名前(つまり、モジュール名)を、最後に「Root」がこのモジュールが所属するリポジトリの名前を保持しているということのようです。また、ディレクトリが1つ下になると、Repositoryの中のモジュール名もcvstest2/dir1のようになることに注意してください。実は、checkoutでは、サブディレクトリをモジュールとして独立して取り出すこともできるのです。 ■■■3.4.3 まとめ ここで、作業コピーを取り出す(チェックアウトする)流れをまとめると、以下のようになります。好きな場所へ取り出して作業を開始してください。 作業コピーを置く場所へ移動する ↓ cvs -d /home/cvsroot checkout target_module 続く3.5節以降では、編集や追加・削除といった日常作業に必要なコマンドについて説明していきます。 ■■3.5 編集してみる 最も頻繁におこなう作業は、ファイルの編集後におこなう「コミット(=commit)」です。コミットは、作業コピーにおこなわれた変更をリポジトリに反映し、さらにその結果を作業コピーの方へ戻すという作業のことです。コマンドとしては、commitコマンドを使用します。ここで、commitコマンドの書式を書いておきましょう。 【図3.12】commitコマンドの書式 ▼ cvs commit [-nRlf] [-m メッセージ| -F メッセージファイル] [-r リビジョン] ファイル群... ▲ ファイルごと、または、いくつかのファイルをまとめてコミットすることができます。 ■■■3.5.1 編集してコミットしてみよう とはいえ、何かファイルがないと編集はできませんので、cvstest2の方のファイル、tmp2.txtと、dir/tmp3.txtを使います。何でもよいのですが、ともかく変更を加えてください。変更後次のようにupdateコマンドを実行してみます(おまじない。3.7節で説明します)。 【図3.13】tmp2.txtとdir1/tmp3.txtを編集してみました ▼ % cvs update cvs update: Updating . M tmp2.txt cvs update: Updating dir1 M dir1/tmp3.txt cvs update: Updating dir1/dir2 ▲ すると【図3.13】のように、頭にM(Modifiedの意味)という文字がつきました。これが、リポジトリのファイルから変更されたファイルにつくマークです。この変更をリポジトリに反映させるために、コミットします。 【図3.14】コミット ▼ % cvs commit -m "Commit Test" cvs commit: Examining . cvs commit: Examining dir1 cvs commit: Examining dir1/dir2 Checking in tmp2.txt; /home/cvsroot/cvstest2/tmp2.txt,v <-- tmp2.txt new revision: 1.2; previous revision: 1.1 done Checking in dir1/tmp3.txt; /home/cvsroot/cvstest2/dir1/tmp3.txt,v <-- tmp3.txt new revision: 1.2; previous revision: 1.1 done ▲ commitコマンドのオプションで頻繁に使うのは、ログメッセージを書き出すための-mオプションでしょう。importコマンドの-mオプションと同様に変更履歴の中に指定したログメッセージが埋め込まれます。加えた変更の内容を忘れないように簡潔なログメッセージをつけるようにしてください。この例のメッセージには、あまり意味はないのですけどね。この例では引数にファイルを渡さなかったので、カレントディレクトリを再帰的にチェックして、コミットをおこなっています。このとき発見された全ての変更について、ここで指定したのと同じコメントがつきます。【図3.14】のコマンドの出力を眺めてみると、tmp2.txtとdir1/tmp3.txtにそれぞれ対応するリポジトリ(home/cvsroot/cvstest2)側のファイルtmp2.txt,vとdir1/tmp3.txt,vのリビジョンが、1.1から1.2へ更新されていることがみて取れます。ここで、tmp2.txt,v、dir1/tmp3.txt,vを見てみれば、変化が記録されている様子もみることができます。自分のおこなった変更がどのように管理されているか、覗いてみるのも楽しいでしょう。 ■■■3.5.2 まとめ ファイルをコミットする手順は、次のようになります。 ファイルtarget_fileを編集 ↓ cvs commit -m "メッセージ" target_file 次の3.6節ではリポジトリにより管理するファイルを増やす方法を解説していきます。 ■■3.6 ファイルを追加する ファイルを追加するコマンドはaddです。ディレクトリの追加もaddでおこないますが、少し動作が違います。ディレクトリを追加する方法については、updateのところで詳しく解説します。 【図3.15】addコマンドの書式 ▼ cvs add [-k展開方法] [-mメッセージ]ファイル群... ▲ ■■■3.6.1 ファイルを追加してみよう cvstestにaddコマンドを使用して、ファイルを追加してみます【図3.16】。 【図3.16】ファイルを追加する ▼ % cat > test.txt hogehoge ^D ←Ctrlキーを押しながらDキーを押す % ls CVS test.txt % cvs update cvs update: Updating . ? test.txt % cvs add -m "Test File" test.txt cvs add: scheduling file `test.txt' for addition cvs add: use 'cvs commit' to add this file permanently % cvs update cvs update: Updating . A test.txt ▲ 無いものは登録できませんから、catコマンドでリダイレクトし、適当にファイルを作成してみます。text.txtという名前にしましょう【1行目】。できましたが【3-4行目】、このままでは、CVSにとっては謎のファイルのままです。つまり、今の状態でupdateコマンドを使うと「?」が頭についちゃいます【図3.16 8行目】。続いてaddコマンドで登録してあげましょう。addコマンドの書式は【図3.15】のようになりますが、-kオプションはあまり使いません。-mオプションはimportコマンドやcommitコマンドの-mオプションと同じで、登録時のコメントをつけるためのものです。ファイルの説明でもつけておいてください(実際、ファイルの説明というような意味合いの領域に保持されます。興味のある人は対応する,vファイルのはじめの方をチェックしてみましょう)。ここでは、文字どおり"Test File"としました。次にupdateしてみると、「?」が「A」に変わりました。何か変更されたようです。 実はこのとき、作業用コピーにあるCVSディレクトリに変化が起きています。つまり、test.txtのための情報が追加されたのです。Entriesに1行追加され、test.txt,tというファイルができています。このファイルの中身はさっき-mで指定したコメントです。しかし、これはまだリポジトリの方には反映されていません。Entriesの該当行では、バージョン情報が0(ゼロ)で、日付の情報もありません。 cvstest/CVS/Entries: add前 ▼ D ▲ cvstest/CVS/Entries: add後 ▼ /test.txt/0/Initial test.txt// D ▲ ■■■3.6.2 これでファイル追加はできたの? これでファイル追加はできたのでしょうか? 答えはいいえです。このファイルの追加という変更をリポジトリへ反映させるためには、コミットしないといけません。コミットしてみましょう【図3.17】。 【図3.17】ファイル追加をリポジトリに反映させる ▼ % cvs commit -m "First Commit for test.txt" test.txt RCS file: /home/cvsroot/cvstest/test.txt,v done Checking in test.txt; /home/cvsroot/cvstest/test.txt,v <-- test.txt initial revision: 1.1 done % cvs update cvs update: Updating . ▲ ■■■3.6.3 何が起こったの? コミットすると、CVSの下のtest.txt,tファイルが消え、Entriesの中身にバージョンと日付情報が加わります。ちなみに、リポジトリ/home/cvsroot/cvstestにはtest.txt,vが追加されています。実は、【図3.17】の5行目には追加したという旨のメッセージが表示されています。確認してみてください。 cvstest/CVS/Entries: commit後 ▼ /test.txt/1.1/Sat Dec 16 01:46:29 2000// D ▲ 【図3.18】リポジトリに新しいファイルが追加された ▼ % ls -RF /home/cvsroot/cvstest /home/cvsroot/cvstest: test.txt,v ▲ ■■■3.6.4 まとめ ファイルを追加する手順は次のようになります。 追加するファイルtarget_fileを作成 ↓ cvs add -m "メッセージ" target_file ↓ cvs commit -m "メッセージ" target_file |次の3.7節ではリポジトリに登録した内容を削除してみます。3.7節の内容がマスターできればリポジトリを自由に扱うことができるでしょう。 ■■3.7 ファイルを削除してみる ファイルを追加したいときもあれば、他のファイルと統合したりして、いらなくなってしまうこともあります。ファイルが必要なくなったら、CVSにそのことを教えてあげないと、いつまでも作業コピーにそのファイルを保持しようとします。これを回避するためには、removeコマンドを使います。removeコマンドの書式を【図3.19】に示します。 【図3.19】removeコマンドの書式 ▼ cvs remove [-flR] [ファイル群...] ▲ ■■■3.7.1 ファイルを削除するのは難しい? このコマンドは、少しだけ使い方が難しいかもしれません。とはいえ、作業が難しいわけではなくて、単にcvs remove tmp1.txtで削除しようとしても、文句をいわれて削除できないというだけです。メッセージでは、「作業領域にまだファイルがあるよん。まず、消してね」と警告されるわけです【図3.20】。 【図3.20】表示される警告メッセージ ▼ % cvs remove tmp1.txt cvs remove: file `tmp1.txt' still in working directory cvs remove: 1 file exists; remove it first ▲ そのメッセージにしたがって、先にファイルを消しておいてもいいんですが、面倒くさいですね。面倒な人は(実はかなり凶悪ですが)-fオプションを利用するとよいかもしれません。警告の原因となるファイルを同時に削除してくれます。 【図3.21】-fオプションを使って警告を回避する ▼ % cvs remove -f tmp1.txt cvs remove: scheduling `tmp1.txt' for removal cvs remove: use 'cvs commit' to remove this file permanently ▲ このオプションを凶悪だと言ったのは、ファイルを指定し忘れる【図3.22】と、カレントディレクトリ以下をすべて消してくださる【図3.23】のです。おっちょこちょいだという自覚のある人(私、わたし!)は使わないほうが無難なオプションでしょう。 【図3.22】ゲゲッ、ファイル指定しないで実行したよ ▼ % cvs remove -f cvs remove: Removing . cvs remove: scheduling `tmp3.txt' for removal cvs remove: Removing dir2 cvs remove: scheduling `dir2/tmp4.txt' for removal cvs remove: use 'cvs commit' to remove these files permanently % cvs update cvs update: Updating . R tmp3.txt cvs update: Updating dir2 R dir2/tmp4.txt ▲ 【図3.23】ああ、ない、無くなってしまった! ▼ % ls -RF .: CVS/ dir2/ ./CVS: Entries Repository Root ./dir2: CVS/ ./dir2/CVS: Entries Repository Root ▲ 消しちゃったらどうすればいいのでしょう。しばらくコミットせずに変更を加えていたとしたら悲惨です。その変更を加えたファイルは戻ってこないからです。しかし、前にコミットした状態には、updateコマンドを使用すれば戻すことができます。ただ、普通にupdateコマンドを実行しても「R」マークがついており、取り出せませんので、ここは一旦上のディレクトリに移動します。次に壊してしまったディレクトリを削除し、updateコマンドに-dオプションをつけて実行します【図3.24】。すると、少なくとも前にコミットした状態までには復旧します。updateコマンドの-dオプションについては3.8.1項で説明します。 【図3.24】とりあえず、前コミット直後まで復帰する ▼ % cd .. % rm -rf dir1 % cvs update -d cvs update: Updating . R tmp1.txt cvs update: Updating dir1 U dir1/tmp3.txt cvs update: Updating dir1/dir2 U dir1/dir2/tmp4.txt ▲ ■■■3.7.2 これでファイルは削除できたの? いえ、削除もコミットしなければ、リポジトリに反映されません。コミットしておきましょう。 【図3.25】ファイル削除をリポジトリにコミットする ▼ % cvs commit -m "File Removal Test" cvs commit: Examining . cvs commit: Examining dir1 cvs commit: Examining dir1/dir2 Removing tmp1.txt; /home/cvsroot/cvstest2/tmp1.txt,v <-- tmp1.txt new revision: delete; previous revision: 1.1.1.1 done ▲ これで、もう他の作業コピーをチェックアウトしても、このファイルは現れません。 ■■■3.7.3 前の状態の作業コピーを更新すると? 結論を先にいうと、削除したファイルは更新時になくなります。ちょっと前の日付で取り出してみて【図3.26】、今日の日付で更新してみます【図3.27】。日付を指定して特定のバージョンを取り出すときには、checkoutもupdateも-Dを使用します。ちなみに、today(今日)、yesterday(昨日)、tomorrow(明日)などについては、その英単語を直接指定することができます。「どうしても最新じゃないと...」、という人は、tomorrowあたりを使うとよいのでしょう。 【図3.26】ファイル削除前のモジュールをチェックアウトする ▼ % cvs checkout -D "Dec 16 2000" cvstest2 cvs checkout: Updating cvstest2 U cvstest2/tmp1.txt U cvstest2/tmp2.txt cvs checkout: Updating cvstest2/dir1 U cvstest2/dir1/tmp3.txt cvs checkout: Updating cvstest2/dir1/dir2 U cvstest2/dir1/dir2/tmp4.txt cvs checkout: Updating cvstest2/newdir ▲ ここで、【図3.27】のようにupdateコマンドを実行し【4行目】、その前後でファイルリストを比べてみると、確かにtmp1.txtがなくなっています【最終行】。 【図3.27】今日の日付で更新する ▼ % cd cvstest2 % ls -F CVS/ dir1/ tmp1.txt tmp2.txt % cvs update -D today cvs update: Updating . cvs update: warning: tmp1.txt is not (any longer) pertinent cvs update: Updating dir1 cvs update: Updating dir1/dir2 % ls -F CVS/ dir1/ tmp2.txt ▲ ■■■3.7.4 削除したファイルを取り出せるのはなぜ? ところで、ここで不思議に思いませんでしたか? 普通にcheckoutコマンドを実行すると、ファイルは削除されています。しかし、昔の日付を指定すると、削除したはずのファイルも取り出すことができます。もちろん、そうでないと古いバージョンのプログラムを組み上げられず困るわけですが、一体どうなっているのでしょう?  リポジトリを覗いてみましょう【図3.28】。【図3.28】と比較してみると、tmp1.txt,vがなくなっており、Atticというディレクトリができているのがわかります。このAtticというディレクトリの中を覗いてみると、tmp1.txt,vがこんなところに置いてあります。削除されるとこんなところに退避されるわけです。 【図3.28】リポジトリの変化をみてみる ▼ % ls -F /home/cvsroot/cvstest2 Attic/ dir1/ tmp2.txt,v % ls -F /home/cvsroot/cvstest2/Attic tmp1.txt,v ▲ ■■■3.7.5 まとめ ファイルを削除する手順は次のようになります。 ファイルtarget_fileを削除 ↓ cvs remove target_file ↓ cvs commit -m "メッセージ" target_file Column Atticだってよ、Attic Atticが屋根裏部屋の意味だと知ったときは、ちょっと意外でした。「墓場のことかな」とか思っていたので(不気味?)いや、死んじゃって埋められて、ときどき復活する…。ゾンビじゃないんだからってば(びしぃ!) >自分 ■■3.8 作業を再開する updateコマンドは、複数の人と協同して作業する時に真価を発揮しますが、まだ一人なので、それほどメリットを感じないかも知れません。ですが、作業の後、状態の確認のためだけにも、updateコマンドはよく使われます。 updateコマンドの書式を【図3.29】に示します。 【図3.29】updateコマンドの書式 ▼ cvs update [-APdflRp] [-k展開方法] [-rリビジョン|-D日付] [-jリビジョン] [-Iファイル] [-Wパターン動作] [ファイル群...] ▲ オプションで今の段階で使うのは-dと-Pの2つのオプションです。それぞれ、ディレクトリの追加と削除に関係していますので、詳しくみてみましょう。 ■■■3.8.1 ディレクトリの追加と-dオプション 一人で作業しているときは、あまり気が付きませんが、作業コピーを2つ以上持っていたりすると、一方で作成したはずのディレクトリが他のものには反映されないということが起こります。これは、updateコマンドが、何も指定しないと、今いる作業コピーに既にあるディレクトリについてのみチェックするという挙動をするためです。 挙動をみてみるために、「newdir」というディレクトリを、cvstest2ディレクトリに1つ加えてみましょう【図3.30】。追加手順は、ファイルとちょっと違います。作成し、addコマンドをするといきなりリポジトリに反映されます。特にコミットする必要はありません。ちょっとびっくりですね。この段階でリポジトリには新規に作成したnewdirが確かに追加されているのを確認することができます。 【図3.30】ディレクトリを追加する。 ▼ % mkdir newdir % cvs add -m "New Directory" newdir Directory /home/cvsroot/cvstest2/newdir added to the repository % ls -F /home/cvsroot/cvstest2 Attic/ dir1/ newdir/ tmp2.txt,v ▲ 次に別の作業コピー(3.3節で利用した作業コピーを再利用しましょう)に移動しupdateコマンドを実行してみます【図2.31】。 【図3.31】何もつけずにupdateコマンドを実行してみる ▼ % cvs update cvs update: Updating . cvs update: Updating dir1 cvs update: Updating dir1/dir2 % ls -F CVS/ dir1/ tmp2.txt ▲ が、さっき言ったように反映されてません【図3.31最終行】。こういうときには、-dを使います【図3.32】。 【図3.32】-dオプションをつけてupdateコマンドを実行してみる ▼ % cvs update -d cvs update: Updating . cvs update: Updating dir1 cvs update: Updating dir1/dir2 cvs update: Updating newdir % ls -F CVS/ dir1/ newdir/ tmp2.txt ▲ 無事、別の作業コピーにも作業結果が反映されました【図3.32最終行】。 ■■■3.8.2 ディレクトリの削除と-Pオプション ディレクトリの削除はちょっと特殊です。removeコマンドは、ファイルに対しては使うことができますが、ディレクトリを指定しても、何の意味もありません。リポジトリに一旦追加されたディレクトリは実は削除されることがありません。空であるかどうかだけが意味をもちます。 【図3.33】ディレクトリを(作業コピーから)削除する ▼ % cvs update -P cvs update: Updating . cvs update: Updating dir1 cvs update: Updating dir1/dir2 cvs update: Updating newdir % ls -F CVS/ dir1/ tmp2.txt ▲ -Pオプションは、別の作業コピーもそうですが、自分の手元の作業コピー内の空ディレクトリをいったん手元から削除するために用いるオプションです。実際、削除手順はディレクトリが既に空であるなら、-Pオプションをつけてupdateコマンドを実行するだけです。これにより、リポジトリ内のディレクトリは削除されるということはありません。このため、上で紹介した-dオプションをつけてupdateコマンドを再度実行すると、空のディレクトリができてしまいます【図3.34】。なんだかややこしいですね。 【図3.34】ディレクトリがまたやってきた。 ▼ % cvs update -d cvs update: Updating . cvs update: Updating dir1 cvs update: Updating dir1/dir2 cvs update: Updating newdir % ls -F CVS/ dir1/ newdir/ tmp2.txt ▲ ■■■3.8.3 空じゃないディレクトリだけ残す方法は? -dと-Pを同時に適用するとどうなるでしょう。テストしてみますが、その前に、ディレクトリnewdir2を作り、中にファイルを置いた状態をリポジトリに登録しておきましょう。そこで、空のディレクトリ、「newdir」が残っていてるが「newdir2」は存在しない状態の作業コピーに移動します。そこで、updateコマンドを-dと-Pの両方のオプションを同時に指定して実行してみます。 【図3.35】newdir2/test.txtを追加して-dと-Pを同時に指定する ▼ % cvs commit -m "Second directory addition" cvs commit: Examining . cvs commit: Examining dir1 cvs commit: Examining dir1/dir2 cvs commit: Examining newdir cvs commit: Examining newdir2 RCS file: /home/cvsroot/cvstest2/newdir2/test.txt,v done Checking in newdir2/test.txt; /home/cvsroot/cvstest2/newdir2/test.txt,v <-- test.txt initial revision: 1.1 done ...(別の作業コピーに移動)... % ls -F CVS/ dir1/ newdir/ tmp2.txt % cvs update -P -d cvs update: Updating . cvs update: Updating dir1 cvs update: Updating dir1/dir2 cvs update: Updating newdir % ls -F CVS/ dir1/ newdir2/ tmp2.txt ▲ すると、newdirがなくなり、newdir2が増えました。ちょっと、釈然としない気もしますが、両方指定すると具合がよいようですね。【図3.36】のように、リポジトリ内にディレクトリはずっと残り続けます。気持ち悪いかもしれませんが、CVSはそういう仕組みだと理解してください。 【図3.36】ディレクトリは永遠に残りつづける ▼ % ls -F /home/cvsroot/cvstest2 Attic/ dir1/ newdir/ newdir2/ tmp2.txt,v ▲ ■■■3.8.4 まとめ ディレクトリを追加または削除した後で、作業コピーに反映させるには次のようにすればよいでしょう。追加や削除が自分の意識しないうちにおこなわれるような場合は、-dと-Pを常につけるようにしておいたほうがよいでしょう。 ディレクトリtarget_dirを追加または削除 ↓ 別の作業コピーでの更新 cvs update -d -P ■■3.9 お掃除お掃除 開発チームから外れた、あるいは取って来た作業コピーでの作業をしばらくおこなわない場合などは、その作業コピーを放棄することをお勧めします。これは、CVSの中にゴミ情報を残さないためです。作業コピーを放棄するにはreleaseというコマンドを使います。コマンドの書式は、【図2.37】のとおりです。 【図3.37】releaseコマンドの書式 ▼ cvs release [-d] ディレクトリ群... ▲ 他のコマンドに比べると、オプションが少ないですね。1つしかありません。このオプション-dは、deleteの略だと思うのですが、実行時に作業コピーであるディレクトリを削除します。逆にいえば、-dオプションをつけなければ、作業コピーのディレクトリは残ります。残したいファイルがある場合は、-dをつけないようにしましょう。きれいさっぱり削除したい場合は、-dをつけましょう。 ■■■3.9.1 ゴミ情報って何? CVSはユーザがcheckoutや他の動作をしたことを記録しています。簡単にみるためにはhistoryというコマンドを使うといいでしょう。詳しくは第4章で説明しますが、例えば、【図3.38】のようなメッセージが出ます。 【図3.38】historyコマンドを実行してみる ▼ % cvs history O 12/15 09:35 +0000 mika cvstest =cvstest= ~/tmp/* O 12/18 09:50 +0000 mika cvstest2 =cvstest2= ~/tmp/* ▲ 【図3.38】の行の先頭にある「O」はチェックアウトされているという意味です。他のイベントは-eオプションをつけないと見ることができません。とりあえず、ここではチェックアウトされたかどうか見たいだけなので、これで構いませんね。2つのモジュールがチェックアウトされています。では、ちょっと削除してみましょう。 ■■■3.9.2 本当に放棄してしまっていい? 【図3.39】何か変更があるね ▼ % cvs release -d cvstest A test2.txt You have [1] altered files in this repository. Are you sure you want to release (and delete) directory `cvstest': n ▲ どうでしょう。このコマンド、特に-dオプションを使うときは慎重に。コミットのし忘れがあったりしたら、大変です。しかし、このあたりはCVSの方でもちゃんと考えてくれています。例えば【図3.39】のように、cvstestの方を消そうと思ったら【3行目】、「1つ変更ファイルが残っているよ」というメッセージが表示されました。releaseコマンドは必ず作業コピーディレクトリ内を、コミットされていない変更が残っていないか全部調べてくれます。 そして、何かあれば、メッセージを表示して、削除してよいか尋ねてきます【最終行】。ここでは、test2.txtが追加(A)されたまま、commitされていないようです。commitしたかったり、ちょっとファイルを取っておきたかったりするのであれば、最後の「Are you sure you want to release (and delete) directory `cvstest':」 (本当にディレクトリcvstestを放棄して(しかも、消しちゃって)いいですか)という質問にn(NOの意味)を入力してキャンセルしてください。 ■■■3.9.3 変更をコミットしたら消してもいい? 【図3.40】消しても大丈夫 ▼ % cvs release -d cvstest2 You have [0] altered files in this repository. Are you sure you want to release (and delete) directory `cvstest2': y % ls -F cvstest/ ▲ 心残り(commit忘れ)がない場合には削除して構いません。例えば、cvstest2を放棄してみようと試みると、こちらは特にcommit忘れはないようです【図3.40】。すべて削除してサッパリしてしまうことにしましょう。最後の質問にy(YESの意味)と答えます。これで作業コピーは本当になくなってしまいました。ここで、もう一度historyコマンドを実行してみると、このメッセージからも、cvstest2はなくなっていることがわかります【図3.41】。 【図3.41】チェックアウト情報が消えた ▼ % cvs history O 12/15 09:35 +0000 mika cvstest =cvstest= ~/tmp/* ▲ ■■■3.9.4 まとめ その作業コピーが必要ない、消去しようと決断したときは、releaseコマンドでその作業コピーを放棄しましょう。 作業コピーtarget_dirの上のディレクトリに移動 ↓ cvs release -d target_dir ↓ メッセージにリストアップされたファイルがあればチェックする。 心残りがなければyと答えて削除。 心残りがあれば、nと答えて作業をキャンセルし対処する。 そのあと再度releaseを実行する。 ■■3.10 この章のまとめ 以上が、基本的な作業の方法です。通常の作業は、本章でとりあげたコマンドでほぼ賄えます。続く第4章では、CVSをより高度に活用するための設定と、便利なコマンドについて説明します。