[目次へ][3章本体へ][3.8へ][3.9へ] 最終更新:$Date: 2002/08/20 16:26:58 $

セクションずらし中。忘れ物があるかも…。(2002/8/5)


■■3.8 ファイルを削除してみる(remove)

ファイルを追加したいときもあれば、他のファイルと統合したりして、いらなくなってしまうこともあります。ファイルが必要なくなったら、CVSにそのことを教えてあげないと、いつまでも作業コピーにそのファイルを保持しようとします。これを回避するためには、removeコマンドを使います。removeコマンドの書式を【図3.8.1】に示します。

【図3.8.1】removeコマンドの書式
▼
cvs remove [-flR] [ファイル群...]
▲

removeコマンドのオプションは3つしかありません。このうち重要なのは-fだけです。-fオプションについては以下で詳しく説明します。

■■■3.8.1 ファイルを削除するのは難しい?

このコマンドは、少しだけ使い方が難しいかもしれません。とはいえ、作業が難しいわけではなくて、単に「cvs remove ファイル名」として削除しようとしても、文句をいわれて削除できないというだけです。【図3.8.2】にcvstest2/tmp1.txtを削除しようとした場合の例を示します。ここで、「作業領域にまだファイルがあるよん。まず、消してね」と警告されて、消せない様子が見てとれると思います。

【図3.8.2】表示される警告メッセージ
▼
% cvs remove tmp1.txt
cvs remove: file `tmp1.txt' still in working directory
cvs remove: 1 file exists; remove it first
▲

そのメッセージにしたがって、先にファイルを消しておいてもいいんですが、面倒くさいですね。面倒な人は(実はかなり凶悪ですが)-fオプションを利用するとよいかもしれません。警告の原因となるファイルを同時に削除してくれます。ちょっとやってみましょう【図3.8.3】。

 【図3.8.3】-fオプションを使って警告を回避する
▼
% cvs remove -f tmp1.txt
cvs remove: scheduling `tmp1.txt' for removal
cvs remove: use 'cvs commit' to remove this file permanently
▲

このオプションを凶悪だと言ったのは、ファイルを指定し忘れると、カレントディレクトリ以下をすべて消してくださるからです。例えば、cvstest2/dir1にいて、tmp3.txtを消すつもりで手が滑ったとしましょう【図3.8.4】。

 【図3.8.4】ゲゲッ、ファイル指定しないで実行したよ
▼
% 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
▲

すると、dir1以下にあるファイルがみなさまお亡くなりになってしまわれます【図3.8.5】。きゃー。

【図3.8.5】ああ、ない、無くなってしまった!
▼
% ls -RF
.:
CVS/  dir2/

./CVS:
Entries  Repository  Root

./dir2:
CVS/

./dir2/CVS:
Entries  Repository  Root
▲

おっちょこちょいだという自覚のある人(私、わたし!)は使わないほうが無難なオプションでしょう。

しかし、うっかり消しちゃったらどうすればいいのでしょう。しばらくコミットせずに変更を加えていたとしたら悲惨です。その変更を加えたファイルは戻ってこないからです。

なお、前にコミットした状態にまでは、updateコマンドを使用すれば戻すことができます。ただ、普通にupdateコマンドを実行しても「R」マークがついていて取り出せません。方法としては2つあります。

1. CVS/Entrieの当該ファイルについての記述を書き換える。

2. または、ディレクトリごと削除して、取り直す。

1の書き換えは分かっていないと難しいかもしれないので、ここは2の方法でやってみます。一旦上のディレクトリに移動します。なお、コミットしていないファイルについては、この時点で退避しておいてください。そうしないと、傷が拡大します。次に壊してしまったディレクトリを削除し、updateコマンドに-dオプションをつけて実行します【図3.8.6】。すると、少なくとも前にコミットした状態までには復旧します。なお、updateコマンドの-dオプションについては3.8.1項で説明します。

 【図3.8.6】とりあえず、前コミット直後まで復帰する
▼
% 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.8.2 これでファイルは削除できたの?

いえ、追加と同様削除もコミットしなければ、リポジトリに反映されません。ちなみに現在のところ、CVS/Entriesは【図3.8.7】のようになってるはずです。ここでポイントなのはバージョンの記述部分です。元のバージョンに「-(マイナス)」がついています(3.4.2項のCVS/Entriesと比べてみてください)。これが削除状態にあるという印です。ですので、実は復帰させるには、このマイナスを取って更新(update)をかければ良いだけだったりします。

【図3.8.7】CVS/Entriesはどうなってるんだろう
▼
% cat CVS/Entries
/tmp2.txt/1.2/Tue Aug 20 12:44:13 2002//
/tmp1.txt/-1.1.1.1/Tue Aug 20 12:30:27 2002//
D/dir1////
▲

さて、削除を「永遠に」するために、コミットしておきましょう。

【図3.8.8】ファイル削除をリポジトリにコミットする
▼
% 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.8.3 前の状態にある作業コピーの更新

さて、新しく作業コピーを取ってくる場合はいいですが、他の場所で削除前の状態で作業しているコピーがあったらどうなるんでしょう。結論を先にいうと、削除したファイルは更新時になくなります。削除前の時刻(1 hour ago)を指定して取り出してみてましょう【図3.8.9】。

日付や時刻を指定して特定のバージョンを取り出すときには、checkoutもupdateも-Dを使用します。ちなみに、today(今日)、yesterday(昨日)、tomorrow(明日)などについては、その英単語を直接指定することができます。「どうしても最新じゃないと...」、という人は、tomorrowあたりを使うとよいのでしょう。 日付の書式については付録Cのコマンドリファレンスを見てください。

【図3.8.9】ファイル削除前のモジュールをチェックアウトする
▼
% cvs checkout -D "1 hour ago" 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.8.10】。 updateコマンドを-Dオプションをつけて実行し【4行目】、その前後でファイルリストを比べてみると、確かにtmp1.txtがなくなっています【最終行】。

【図3.8.10】今日の日付で更新する
▼
% cd cvstest2
% ls -F
CVS/  dir1/  tmp1.txt  tmp2.txt
% cvs update -D today
cvs update: Updating .
cvs update: tmp1.txt is no longer in the repository
cvs update: Updating dir1
cvs update: Updating dir1/dir2
% ls -F
CVS/  dir1/  tmp2.txt
▲
■■■3.8.4 削除したファイルを取り出せるのはなぜ?

ところで、ここで不思議に思いませんでしたか? 普通にcheckoutコマンドを実行すると、ファイルは削除されています。しかし、昔の日付を指定すると、削除したはずのファイルも取り出すことができます。もちろん、そうでないと古いバージョンのプログラムを組み上げられず困るわけですが、一体どうなっているのでしょう? 

リポジトリを覗いてみましょう【図3.8.11】。3.3.3項の【図3.3.11】と比較してみると、tmp1.txt,vがなくなっており、Atticというディレクトリができているのがわかります。このAtticというディレクトリの中を覗いてみると、tmp1.txt,vがこんなところに置いてあります。削除されるとこんなところに退避されるわけです。

【図3.8.11】リポジトリの変化をみてみる
▼
% ls -F /home/cvsroot/cvstest2
Attic/  dir1/  tmp2.txt,v
% ls -F /home/cvsroot/cvstest2/Attic
tmp1.txt,v
▲

■■■3.8.5 WinCvsでファイルを削除するには

WinCvsでファイルを削除してみましょう。まず、ワークスペースで【図3.8.12】のように削除するファイルを選んでおいてください。ここではtmp2.txtを選んでおきます。

【図3.8.12】どぉれっを削除しようかなっ

この状態でメニュー[修正]→「リポジトリから削除(Remove)]【図3.8.13】、またはファイルバーの削除アイコンを選択してください。

【図3.8.13】 [修正]→「リポジトリから削除(Remove)]メニュー(※要画像差し替え)

すると、【図3.8.14】のようなメッセージがアウトプット領域に出力されます。ここでよく見ると、WinCvsが独自に指定したファイルをごみ箱へ移動し、そのあと、removeコマンドを実行しているようです。ということはもし失敗した場合にはごみ箱から拾ってくればいいわけです。

【図3.8.14】
▼
'tmp2.txt' をごみ箱へ移動しました cvs remove tmp2.txt (ディレクトリ C:\home\mika\workcopy\wintest\ 内) cvs remove: scheduling `tmp2.txt' for removal cvs remove: use 'cvs commit' to remove this file permanently *****CVS はコード 0 で終了しました***** ▲

さて、この状態ではまだ作業コピーの内部でしか削除されていません。この状態でワークスペースを見てみると、【図3.8.15】のようになっているはずです。また、赤くなってるんですが、この本では黒いだけなので自分のPCのディスプレイ上で確認してみてください(白黒ディスプレイだったりして…)。そしてよくよくアイコンを見てみると、「バッテン」がついています。削除のコミット待ち状態、コマンドラインでのupdateでRが出る状態に対応しています。

【図3.8.15】 あれ、アイコンが赤くなっただけで、まだある…

ということで、リポジトリに「永遠に」この削除を覚えていてもらうために、コミットをしておきましょう【図3.8.16】。

【図3.8.16】コミットいけいけ
▼
cvs commit -m "Remove test." tmp2.txt (ディレクトリ C:\home\mika\workcopy\wintest\ 内) Removing tmp2.txt; C:\home\cvsroot/wintest/tmp2.txt,v <-- tmp2.txt new revision: delete; previous revision: 1.1 done *****CVS はコード 0 で終了しました***** ▲

例によって、コード0によって終了したら、ワークスペースが【図3.8.17】のようになるはずです。

【図3.8.17】 おお、ようやく無くなったぞ

これで無事に(永遠に?)無くなりました。

■■■3.8.6 まとめ

ファイルを削除する手順は次のようになります。

ファイルtarget_fileを削除

cvs remove target_file

cvs commit -m "メッセージ" target_file

Column Atticだってよ、Attic

Atticが屋根裏部屋の意味だと知ったときは、ちょっと意外でした。「墓場のことかな」とか思っていたので(不気味?)いや、死んじゃって埋められて、ときどき復活する…。ゾンビじゃないんだからってば(びしぃ!) >自分