[目次へ][3章本体へ][3.6へ][3.8へ]

3.7をバイナリファイルの節として新規に挿入。(2002/08/07)

題名変更


■■3.7 バイナリファイルの扱いについて(-kb)

前にも書いたように、CVSはバイナリファイルを扱えはしますが、得意ではありません。これは、CVSのバージョン管理では、もともとテキストファイルの差分を管理するようになっているためです。バイナリファイルの場合、CVSは同じように差分で管理しようとしますが、それほど量は減らないのメリットは少ないです。

しかしながら、画像ファイルやWindowsの各種文書など、バイナリファイルを日常的に扱うことは非常に多くなっています。ですので、ここでちょっとコマンドに割り込む形にはなりますが、バイナリファイルの扱いについて説明しておきたいと思います。具体的にはファイル追加時とインポート時、および後からのバイナリファイルへの変更について説明します。

importやadd、またちょっと高度なコマンドであるadminコマンドのオプションにはRCSキーワード置換モードを指定するためのオプション-kというものがあります。詳しくは5.3節で説明しますが、CVSはコミット時に、RCSキーワードというものを展開します。これをバイナリファイルに対しておこなったらどうなるでしょう。つまり、偶然に$Id$という文字列(RCSキーワードの一種です)がバイナリファイルに含まれていたら、CVSは問答無用に、$Id: ...という文字列に展開します。とすると、バイナリファイルはそこで壊れてしまいます。

これを制御するのが、-kオプションです。特にバイナリファイルを扱うためのbフラグの場合は、キーワードを展開しないようにするだけでなく、PC(WindowsおよびMacintosh)クライアントとのやりとりで通常行っている改行コード変換もおこないません。つまり、まったくファイルには変更が加えられません。

■■3.7.1 バイナリファイルを追加してみる

試しに何かバイナリファイルを登録してみましょう。画像ファイル(JPEGファイル)のfish.jpgというファイルを用意してみます。皆さんは、好きなファイルで試してみてください。

addコマンドに-kbをつけて登録します【図3.7.1】。addコマンドではリポジトリには登録されず、コミットが必要なところ【図3.7.1 7行目】は3.6節でのテキストファイルの追加と同じです。

【図3.7.1】バイナリファイルの追加
▼
% cvs add -kb -m "JPEG File" fish.jpg
cvs add: scheduling file `fish.jpg' for addition
cvs add: use 'cvs commit' to add this file permanently
% cvs update
cvs update: Updating .
A fish.jpg
% cvs commit -m "JPEG File Commit" fish.jpg
RCS file: /home/cvsroot/cvstest/fish.jpg,v
done
Checking in fish.jpg;
/home/cvsroot/cvstest/fish.jpg,v  <--  fish.jpg
initial revision: 1.1
done
▲

ここで、fish.jpgを編集して、新たに1.2として登録してみます。このときリポジトリの中のRCSファイル/home/cvsroot/cvstest/fish.jpg,vのサイズ(9095バイト)は最初のfish.jpgのサイズ(4190バイト)と新しいサイズ(4753バイト)を足したもの(8943バイト)より増加していますね…。バイナリでは減らすのはやはり難しいようです。

【図3.7.2】サイズを比較してみる
▼
% ls -l fish.jpg
-rw-r--r--    1 mika     wheel        4190  8月 20 21:58 fish.jpg
(編集、コミット)
% ls -l fish.jpg
-rw-r--r--    1 mika     wheel        4753  8月 20 22:11 fish.jpg
% ls -l /home/cvsroot/cvstest/fish.jpg,v
-r--r--r--    1 mika     wheel        9095  8月 20 22:11 /home/cvsroot/cvstest/fish.jpg,v
▲

ちなみに、ここで/home/cvsroot/cvsroot/fish.jpg,vを覗いてみると、なんとか差分で管理しようとしている様子がうかがえます。ずらずら書いてもうっとうしいので書きませんが、興味のある人は覗いてみてください。

■■■3.7.2 バイナリファイルが混ざったモジュールを登録しよう

importコマンドで、既にあるファイル群をまとめて登録する時に、その中にバイナリファイルが混ざっていたらどうしましょうか。

一旦登録して、後から次に紹介するadminコマンドで一つ一つ変えていくという手もありますが、気が遠くなりますね。そういうときは、wrappersの機能を使ってまとめるのが比較的簡単です。オプションで指定する方法、とcvswrappers(あるいは.cvswrappers)であらかじめ指定しておくという方法があります。

まず、オプションで指定する方法を紹介しましょう。登録したいファイル群の中に、.jpg、.JPG、.gif、.GIFというサフィックスを持つバイナリファイルが含まれているとしましょう。そういう時には、【図3.7.3】のようにファイルのパターンと-k'b'を並べた文字列を持つ-Wオプションを並べて指定します。このとき、-kbとしてはいけません。うまくいきません。【図3.7.3】ではそれぞれのサフィックスを持つ4つのファイルを用意しています。【図3.7.3 3行目】は長くなったので\で折り返していますが、続けて入力してもらって構いません。モジュール名は適当にbintestなどとしています。

【図3.7.3】-Wオプションでバイナリファイルのimportを簡単にする
▼
% ls
fish.gif  fish.jpg  fish2.GIF  fish2.JPG
% cvs -d /home/cvsroot import -W "*.jpg -k'b'" -W "*.JPG -k'b'" \
  -W "*.gif -k'b'" -W "*.GIF -k'b'" -m "Binary test module" \
  bintest mikamama BINTEST_1
N bintest/fish.gif
N bintest/fish.jpg
N bintest/fish2.GIF
N bintest/fish2.JPG
▲

これをチェックアウトして確かめてみる【図3.7.4】と、

【図3.7.4】checkoutして状態を確かめる
▼
% cvs -d /home/cvsroot checkout bintest
cvs checkout: Updating bintest
U bintest/fish.gif
U bintest/fish.jpg
U bintest/fish2.GIF
U bintest/fish2.JPG
▲

bintest/CVS/Entriesでちゃんと、-kbがついていることがわかります。

bintest/CVS/Entries
▼

/fish.gif/1.1.1.1/Tue Aug 20 13:22:48 2002/-kb/
/fish.jpg/1.1.1.1/Tue Aug 20 13:22:48 2002/-kb/
/fish2.GIF/1.1.1.1/Tue Aug 20 13:22:48 2002/-kb/
/fish2.JPG/1.1.1.1/Tue Aug 20 13:22:48 2002/-kb/
D
▲

正確にはリポジトリ内の,vファイル(RCSファイル)の中に設定されているので、そちらも確認してください。expandという文字列を含む行に設定されています。,vファイルの中からgrepで抜き出してみましょう【図3.7.5】。細かい話ですが、grepの-aオプションはバイナリファイルを強制的に検索するオプションです。

【図3.7.5】,vファイルの状態を確かめる
▼
grep -a expand /home/cvsroot/bintest/*,v
/home/cvsroot/bintest/fish.gif,v:expand   @b@;
/home/cvsroot/bintest/fish.jpg,v:expand   @b@;
/home/cvsroot/bintest/fish2.GIF,v:expand   @b@;
/home/cvsroot/bintest/fish2.JPG,v:expand   @b@;
▲

cvswrappers(あるいは.cvswrappers)を使う方法もあります。-Wオプションで指定した文字列を、管理ファイルcvswrappersあるいは個人環境ファイル.cvswrappersの中に一行ずつ並べるだけです。バイナリファイルの登録を頻繁におこなうようであれば、設定しておいた方が楽でしょう。ちなみに、Wordのファイルなど制御文字の入った文書もバイナリ指定しておく必要があります。Windowsを主に使っている人でCVSをバックアップに使いたい場合には、サフィックスをcvswrappersに登録しておいた方がよいでしょう。

例えば、【図3.7.6】のように指定した後は、importの時に-Wオプションで指定しなくても、また、addの実行時に-kbオプションをつけなくても、自動的につけられるようになります。

【図3.7.6】cvswrappersの記述例
▼
*.gif   -k'b'
*.GIF   -k'b'
*.jpg   -k'b'
*.JPG   -k'b'
▲

【図3.7.7】にaddの実行例を示します。commitコマンドの-mオプションの中はコメントですので関係ありません。CVS/Entriesからgrepで新規に追加したfish3.jpgファイルについての情報を抜き出してみると、確かに-kbがついていることがわかります。また、,vファイルの方も設定されているようです。

【図3.7.7】cvswrappersに書いておけば指定する必要がない
▼
% cvs add -m "New fish jpeg file" fish3.jpg
cvs add: scheduling file `fish3.jpg' for addition
cvs add: use 'cvs commit' to add this file permanently
% cvs commit -m "Cvswrappers -k'b' test for jpeg file" fish3.jpg
RCS file: /home/cvsroot/bintest/fish3.jpg,v
done
Checking in fish3.jpg;
/home/cvsroot/bintest/fish3.jpg,v  <--  fish3.jpg
initial revision: 1.1
done
% grep fish3.jpg CVS/Entries
/fish3.jpg/1.1/Tue Aug 20 13:28:03 2002/-kb/
% grep -a expand /home/cvsroot/bintest/fish3.jpg,v
expand  @b@;
▲

■■■3.7.3 しまったテキストファイルとして登録しちゃった?!

addやimportでリポジトリに登録するときに-kbを指定し忘れて困ることがあります。場合によっては、これは致命的なミスになってしまうことがあります。特にWindowsのクライアントでUNIX上のリポジトリに登録した場合には、バイナリファイルの一部が消失してしまうことを確認しています。登録時にはくれぐれも気をつけて、元データを安易に削除しないようにしてください。

UNIXのローカルファイル上や、ただのテキストファイルについてRCSキーワードを抑制するために使用している場合にはあまり問題はないようです。以下は、そうしたデータが消失しない場合についての小技です。

詳しくは、キーワード置換のところで書きますが、checkoutやupdateコマンドの実行時に-kbを指定することにより、作業コピー内だけでバイナリファイル扱いするように設定することもできます。この場合リポジトリ内の,vファイルの設定は変わらず、CVS/Entriesの設定だけが変わります。しかしこれだと、なんとなく冴えません。やはり、リポジトリ内の,vファイルにちゃんとバイナリファイル扱いするように指定したいです。

そういう場合には、adminコマンドを使用します。addと同じように、-kオプションでモードを指定することによって、リポジトリ内の,vファイルに記述された置換モードを設定し直すことができます。バイナリファイルにするには、-kbです。【図3.7.8】にfish4.pngというファイルをそのまま登録してしまった場合の再設定の様子を示します。まず【図3.7.8 1行目】で、fish4.png,vにexpandが設定されなかったということを調べた後、adminに-kbを指定して再設定します【図3.7.8 2行目】。次に【図3.7.8 5行目】でfish4.png,vを確認すると、確かにexpandが設定されていることがわかります【図3.7.8 6行目】。

【図3.7.8】置換モードの再設定
▼
% grep -a expand /home/cvsroot/bintest/fish4.png,v
% cvs admin -kb fish4.png
RCS file: /home/cvsroot/bintest/fish4.png,v
done
% grep -a expand /home/cvsroot/bintest/fish4.png,v
expand  @b@;
▲ 

■■■3.7.4 WinCvsでのバイナリファイルの取り扱い

WinCvsでバイナリファイルを追加したり、インポートしたりするのは、コマンドラインでやるよりも親切になっています。これはやはり間違うと致命的なせいかもしれません。さっそくやってみましょう。

■■■■ バイナリファイルを追加してみる

ファイルの追加をテストするために、testimage.gifというファイルを用意してみました。みなさんも、何か適当に用意してみてください。これを、今まで使ってきたwintestモジュールに追加すべく、wintest作業コピーに置きます。この状態でワークスペースには謎のファイルtestimage.gifがあるというように表示されているはずです【図3.7.9】。これをちゃんと選んでおいてください。

【図3.7.9】 謎のファイルtestimage.gifを用意

選ばれた状態で、メニュー[修正]→[バイナリファイルとして追加(Y)]【図3.7.10】を選ぶか、ファイルバーからバイナリ追加アイコンを選びます。

【図3.7.10】 [修正]→[バイナリファイルとして追加(Y)]メニュー

すると、アウトプット領域に【図3.7.11】のようなメッセージが出力され、

【図3.7.11】
▼
cvs add -kb testimage.gif (ディレクトリ C:\home\mika\workcopy\wintest\ 内)
cvs add: scheduling file `testimage.gif' for addition
cvs add: use 'cvs commit' to add this file permanently


*****CVS はコード 0 で終了しました*****
▲

【図3.7.12】のように謎な状態になっていたアイコンが赤く変化します。前節でのテキストファイルの追加と違うのはアイコンに「A(addの意味)」だけでなく、「01」が書かれていることです。この「01」がバイナリファイルの追加になってることを示しているわけです。

【図3.7.12】 お、やっぱり赤くなった。

次にコミットします。コミットの仕方を思い出してやってみてください。【図3.7.13】のようなメッセージがアウトプット領域に出力され、

【図3.7.13】コミットコミット♪
▼
cvs commit -m "Binary file addition test." testimage.gif (ディレクトリ C:\home\mika\workcopy\wintest\ 内)
RCS file: C:\home\cvsroot/wintest/testimage.gif,v
done
Checking in testimage.gif;
C:\home\cvsroot/wintest/testimage.gif,v  <--  testimage.gif
initial revision: 1.1
done

*****CVS はコード 0 で終了しました*****

【図3.7.14】のようにアイコンが白くなれば成功です。

【図3.7.14】 これで、リポジトリにも反映されました。

■■■■ バイナリファイルの含まれるモジュールをインポートしてみる

次に、追加ではなく、一挙にモジュールを登録するときのバイナリファイルの取り扱いについて、説明します。その前に、登録するファイル群がないとお話になりませんので、用意しましょう。バイナリファイルを2種類で2つほど、そして、比較のためにテキストファイルを1つ用意します【図3.7.15】。

【図3.7.15】 登録テスト用のファイルを用意しよう。

そして、3.3.4項でやった手順のとおりインポートを開始してください【図3.7.16】。

【図3.7.16】 インポートするぞ〜

と、途中で、【図3.7.17】のようなダイアログが出てくると思います。3.3.4項では簡単に流してしまいましたが、ここではちょっとじっくり眺めてみましょう。状態はあまり気にしなくてもいいのですが、説明と種類の部分が重要です。JPEGファイルの*.jpgおよびGIFファイルの*.gifファイルがバイナリとして認識されています。

【図3.7.17】 なんか出てきたぞ

もしこれが望んだ状態にない場合には、「編集」ボタンを押して、【図3.7.18】のダイアログを出してください。ここで、強制的に違うモードに切り替えることができます。このファイルを無視して登録しないようにすることもできます。

【図3.7.18】 ちょっと「編集」を眺めてみると…

ここでは、わざわざ変える必要はありませんので、「キャンセル」を選ぶか、このまま「OK」を選ぶかして【図3.7.17】のダイアログに戻り、「OK」でインポートを実行してください。実行すると、【図3.7.19】のようなメッセージがアウトプット領域に表示されるはずです。

【図3.7.19】
▼
'C:\home\mika\bintest' 内のファイルを調査しています...
cvs import -I ! -I CVS -W "*.jpg -k 'b'" -W "*.gif -k 'b'" -m "no message" bintest mikamama BINTEST (ディレクトリ C:\home\mika\bintest 内)
N bintest/bintest.gif
N bintest/bintest.jpg
N bintest/bintest.txt

No conflicts created by this import 

*****CVS はコード 0 で終了しました*****
▲

モジュールタブで眺めている領域にチェックアウトして登録されていることを確認しておいてください。

■■■■ バイナリ指定の変更をしてみる

次に、テキストで登録されてしまったファイルについて強制的にバイナリモードを適用する話をします。WinCvsを使用している限りあまりないことではありますが、たまにこの原稿のようにRCSキーワードを変換したくないときがあったりします。編集さんに文句を言われる前にバイナリとして登録しなおしておきましょう…なんてね。

さっき追加のときに使用したwintestモジュールに含まれる、tmp1.txtを対象にしてみます。残念ながら、これはボタンひとつですぐにとはいきません。具体的にはCVSコマンドを、コマンドラインのときのように打ち込む必要があります。

WinCvsコマンドを打ち込むには基本的にはメニュー[管理]→[コマンド入力(C)]【図3.7.20】を使用します。ちなみに、バージョン1.2でTclをインストールしている場合やバージョン1.3では直接アウトプット領域でコマンド入力を行うことができますが、ここでは割愛します。

【図3.7.20】 [管理]→[コマンド入力(C)]メニュー

このコマンド入力メニューを選ぶと、【図3.7.21】のようなダイアログが出てくるはずです。

【図3.7.21】 コマンドを入れろと言われている気がする

ここで、すぐコマンドを入力してもいいのですが、どこでコマンドが実行されるのか、今ひとつ不安なので、コマンドを実行するフォルダを指定しておきます。「特定のディレクトリでコマンドを実行する」チェックボックスを選択すると、自動的に【図3.7.22】のようなダイアログが現れます。

【図3.7.22】 フォルダを選べと言われているようだ…

ということで、コマンドを実行するフォルダC:\home\mika\workcopy\wintestを選択して「OK」を押します。すると、【図3.7.23】のように「フォルダの変更(F)」ボタンの横にこのディレクトリが表示されるようになりました。ここで、モードを変えるためのadminコマンドを「CVSのコマンドラインを入力(C)」という欄に書き込みます。

【図3.7.23】 コマンド打ち込みはちょっと面倒…

そして、「OK」ボタンを押して実行すると、アウトプット領域に【図3.7.24】のようなメッセージが表示されるはずです。

【図3.7.24】コマンド成功!多分ね
▼
cvs admin -kb tmp1.txt (ディレクトリ C:\home\mika\workcopy\wintest 内) RCS file: C:\home\cvsroot/wintest/tmp1.txt,v done *****CVS はコード 0 で終了しました***** ▲

これで登録されているはずですが、手元のワークコピーにはまだ反映されていません。更新をしてみてください。【図3.7.25】のようになれば成功です。

【図3.7.25】 更新しないと変更が反映されないぞ

■■■3.7.5 まとめ


●あるファイル(targetfile)をバイナリファイルとして登録するには

	作業コピー内に入る
	↓
	cvs add -kb targetfile


●あるモジュール(targetmodule)をその中のあるサフィックス(.x)を持つファイルについてはバイナリファイルとして登録するには


	cvs -d /home/cvsroot import -W "*.x -k'b'" targetmodule ベンダー名 バージョン名


●あるファイル(targetfile)を後からバイナリファイルに再設定するには

	作業コピー内に入る
	↓
	cvs admin -kb targetfile


※ただし、バイナリファイルとして復帰できるとは限らない。

次の3.8節ではリポジトリに登録した内容を削除してみます。3.8節の内容がマスターできればリポジトリを自由に扱うことができるでしょう。