[目次へ][4章へ][4.3へ][4.5へ] 最終更新:$Date: 2002/08/22 07:34:03 $
■第5章 もう少し便利なコマンドの使い方
rdiff -tでrhl7.3+cvs-1.11.2だとSegmentation Faultが…。ひとまず赤字でコメントを。
■■4.4 ファイルの差分を見てみよう(diff, rdiff)
今作業しているファイルとあるバージョン(リビジョン)がどのくらい違うのかとか、あるいは、あるリビジョンのファイルと他のリビジョンのファイルがどのくらい違うのかということがときどき気になることがあります。そういうことが知りたくなったときには、diffコマンドまたはrdiffを利用します。
diffの書式は、【図4.4.1】のようになります。一方、rdiffの書式は【図4.4.2】のようになります。
【図4.4.1】diffコマンドの書式 ▼ cvs diff [-lNR] [rcsdiffのオプション群] [[-r リビジョン1 | -D 日付1] [-r リビジョン2 | -D 日付2]] [ファイル群...] ▲
【図4.4.2】rdiffコマンドの書式 ▼ cvs rdiff [-lNR] [-c|-u] [-s|-t] [-V RCSバージョン] -r リビジョン1|-D 日付1 [-r リビジョン2 | -D 日付2] [モジュール群...] ▲
オプションは使いこなせると結構便利です。ここでは、特に便利と思われる(独断と偏見ですが…)ものについて紹介します。
■■4.4.1 diffとrdiffの違い
一番の違いは、diffは作業コピーが必要なのに対して、rdiffは作業コピーを使用せずに直接リポジトリを操作するようになっているということです。このため、rdiffではリビジョンもしくは日付で少なくとも一つは比較対象を指定しなくてはなりませんし、リポジトリも指定する必要があります。また、今作業コピーに加えた変更を比較することはできません。そのかわり-sオプションで差分のサマリーをみたり、-tオプションで最新の2つのリビジョンを比較することができます。
また、diffではrcsdiffのオプションとして自分の環境のdiffコマンドで指定できるオプションが使えますが、rdiffでは使えません。diffでは、インストールの章で説明したように、GNUのdiffutilsパッケージを導入している場合には、-cなどのオプションが使用できます。これらの動作の違いを考慮した上で、目的に合わせた使いわけをしていくとよいでしょう。以下にいくつか、状況の例をあげてみます。GNU diffのオプションはうんざりするほどあります。
■■■4.4.2 今作業しているファイルと最後のコミットとを比べる
一番ありがちな状況です。diffを使いましょう。diffコマンドはリビジョンや日付の指定がない場合には、手元にある現在のファイルを最後にコミットされた状態(ただし、以前のリビジョンを取ってきて作業している場合にはそのリビジョン)と比べます。rdiffではこれはできません。ファイルを指定しないと、作業コピー内全てを対象にしてわずらわしいので、ここでは、difftest.txtというファイルを例に使います。都合によりcvstest2の方にcvstest2/difftest.txtとして作成したいと思います。
まず、このファイルがどのように更新されてきたかを示しておきましょう。まず、最初のリビジョンは【図4.4.3】のようであったとします。
【図4.4.3】最初のリビジョン(1.1)の内容 ▼ This is a diff test file. Spaces ignoring test. Blank lines ignoring test. ▲
次に後で空白による違いをみるために、第2行に4つ空白を入れてみます【図4.4.4】。これがリビジョン1.2です。
【図4.4.4】リビジョン1.2の内容
▼
This is a diff test file.
Spaces ignoring test.
Blank lines ignoring test.
▲
次に同じく後で空行による違いを見るために、第3行の空行に2行空行を追加しておきます【図4.4.5】。これを1.3とします。
【図4.4.5】リビジョン1.3の内容
▼
This is a diff test file.
Spaces ignoring test.
Blank lines ignoring test.
▲
このような状態で、作業コピーを【図4.4.6】のように編集してみます。
【図4.4.6】作業コピーの現状 ▼ This is a diff test file. Which is modifiled? Spaces ignoring test. Blank lines ignoring test. This is an additional line. ▲
この状態で、特にオプションなしで実行した結果を【図4.4.7】に示します。なんだか、見づらい出力が出てきましたね。この出力は要するに1-2行目が1-4行目として変更されて【7行目の1,4c1,2】、6行目が5行目のところに追加された【15行目の6c5】ということを言っているだけです。
【図4.4.7】オプションを指定しないで実行 ▼ % cvs diff difftest.txt Index: difftest.txt =================================================================== RCS file: /home/cvsroot/cvstest2/difftest.txt,v retrieving revision 1.3 diff -r1.3 difftest.txt 1,4c1,2 < This is a diff test file. < Spaces ignoring test. < < --- > This is a diff test file. Which is modifiled? > Spaces ignoring test. 6a5 > This is an additional line. ▲
これをもっと人間に見やすい形式で出力することもできます。大体コンテキスト形式を使用することが多いですが、ユニファイド形式という形式もあります。GNUのdiffが入っていればこれらの形式はサポートされているはずです。コンテキスト形式は-cオプション、ユニファイド形式は-uというオプションで指定することができます。【図4.4.8】と【図4.4.9】にそれぞれの実行例を示します。コンテキスト形式の方が見やすいでしょうか。いつも特定の形式で出したい場合には、.cvsrcにdiffのオプションを設定しておくとよいでしょう。
【図4.4.8】-cオプションを指定して実行 ▼ % cvs diff -c difftest.txt Index: difftest.txt =================================================================== RCS file: /home/cvsroot/cvstest2/difftest.txt,v retrieving revision 1.3 diff -c -r1.3 difftest.txt *** difftest.txt 20 Aug 2002 14:20:24 -0000 1.3 --- difftest.txt 20 Aug 2002 14:20:58 -0000 *************** *** 1,6 **** ! This is a diff test file. ! Spaces ignoring test. ! ! Blank lines ignoring test. --- 1,5 ---- ! This is a diff test file. Which is modifiled? ! Spaces ignoring test. Blank lines ignoring test. + This is an additional line. ▲
【図4.4.9】-uオプションを指定して実行 ▼ % cvs diff -u difftest.txt Index: difftest.txt =================================================================== RCS file: /home/cvsroot/cvstest2/difftest.txt,v retrieving revision 1.3 diff -u -r1.3 difftest.txt --- difftest.txt 20 Aug 2002 14:20:24 -0000 1.3 +++ difftest.txt 20 Aug 2002 14:20:58 -0000 @@ -1,6 +1,5 @@ -This is a diff test file. - Spaces ignoring test. - - +This is a diff test file. Which is modifiled? + Spaces ignoring test. Blank lines ignoring test. +This is an additional line. ▲
■■■4.4.3 あるファイルについて任意の2つのリビジョンを比べてみる
比較対象がひとつのファイルで、UNIXコマンドのdiffを駆使した比較をおこないたい場合にはdiffを使いましょう。簡易な比較であれば、rdiffを使ってもかまいません。【図4.4.10】にdiffコマンドを使用した比較の例を示します。
【図4.4.10】diffコマンドで2つのリビジョンを指定して実行 ▼ % cvs diff -c -r1.1 -r1.2 difftest.txt Index: difftest.txt =================================================================== RCS file: /home/cvsroot/cvstest2/difftest.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -c -r1.1 -r1.2 *** difftest.txt 20 Aug 2002 14:19:10 -0000 1.1 --- difftest.txt 20 Aug 2002 14:19:58 -0000 1.2 *************** *** 1,4 **** This is a diff test file. ! Spaces ignoring test. Blank lines ignoring test. --- 1,4 ---- This is a diff test file. ! Spaces ignoring test. Blank lines ignoring test. ▲
rdiffで同じことをするためには、リポジトリの指定とモジュールの先頭からのパスが必要です【図4.4.11】。リポジトリの指定は環境変数でもオプションでも構いません。作業コピー内にいる場合にはそのCVS/Rootを見にいきます。ちなみに、rdiffの出力は何も指定しないと、コンテキスト形式で出てきます。
【図4.4.11】rdiffコマンドで2つのリビジョンを指定して実行 ▼ % vs -d /home/cvsroot rdiff -r1.1 -r1.2 cvstest2/difftest.txt Index: cvstest2/difftest.txt diff -c cvstest2/difftest.txt:1.1 cvstest2/difftest.txt:1.2 *** cvstest2/difftest.txt:1.1 Tue Aug 20 23:19:10 2002 --- cvstest2/difftest.txt Tue Aug 20 23:19:58 2002 *************** *** 1,4 **** This is a diff test file. ! Spaces ignoring test. Blank lines ignoring test. --- 1,4 ---- This is a diff test file. ! Spaces ignoring test. Blank lines ignoring test. ▲
■■■4.4.4 インデントの違いを無視した比較をおこなってみる
ソースコードの場合には、空白というのは人間の読みやすさや好きずきのためにあってプログラム的にはほとんど意味をなしません。よってインデントの空白が4個だったのが8個になったからといって差分として表れるのは煩わしい、ということになります。そういう場合に、空白を無視するためのオプション-B、-b、-wがよく使われます。-Bオプションは空行の挿入削除だけによる違いを無視し、-bオプションは空白の数の増減だけによる違いを無視します。-wオプションは-bオプションの強力バージョンで、空白が一方にあって、他方にはない場合でも無視します。
空行の違いが無視されているか見るために、リビジョン1.2と1.3を比較してみます。【図4.4.12】が-Bをつけなかった場合で、【図4.4.13】がつけた場合です。-Bをつけなかった場合には検出されていた空行が、確かに-Bをつけると検出されなくなっています。
【図4.4.12】-Bをつけなかった場合 ▼ % cvs diff -r1.2 -r1.3 difftest.txt Index: difftest.txt =================================================================== RCS file: /home/cvsroot/cvstest2/difftest.txt,v retrieving revision 1.2 retrieving revision 1.3 diff -r1.2 -r1.3 3a4,5 > > ▲
【図4.4.13】-Bをつけた場合 ▼ % cvs diff -B -r1.2 -r1.3 difftest.txt =================================================================== RCS file: /home/cvsroot/cvstest2/difftest.txt,v retrieving revision 1.2 retrieving revision 1.3 diff -B -r1.2 -r1.3 ▲
同様に、リビジョン1.1と1.2について空白の違いだけの場合の-bオプションの働きについて見てみます。-bをつけなかった場合については、【図4.4.11】で既に見たので、つけた場合のみについて見てみます【図4.1.14】。【図4.4.11】で検出されていた空白による違いが、-bをつけた【図4.4.14】では検出されなくなっています。
【図4.4.14】-bをつけた場合 ▼ % cvs diff -b -r1.1 -r1.2 difftest.txt Index: difftest.txt =================================================================== RCS file: /home/cvsroot/cvstest2/difftest.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -b -r1.1 -r1.2 ▲
ちなみに、この例では-bオプションでも-wオプションでも違いはみられません。ですので、作業コピーの方をリビジョン1.3に復帰して、先頭行のはじめに入れた場合について【図4.4.15】に示しましょう。別に先頭である必要はないんですが、なんとなく…。
【図4.4.15】作業コピーを復帰して変更したもの
▼
This is a diff test file.
Spaces ignoring test.
Blank lines ignoring test.
▲
-bと-wの違いを見てください【図4.4.16】。-bの方では違いとして認識されていた先頭の空白が、-wの方では認識されていません。
【図4.4.16】-bと-wの違い ▼ % cvs diff -b difftest.txt Index: difftest.txt =================================================================== RCS file: /home/cvsroot/cvstest2/difftest.txt,v retrieving revision 1.3 diff -b -r1.3 difftest.txt 1c1 < This is a diff test file. --- > This is a diff test file. % cvs diff -w difftest.txt Index: difftest.txt =================================================================== RCS file: /home/cvsroot/cvstest2/difftest.txt,v retrieving revision 1.3 diff -w -r1.3 difftest.txt ▲
diffのオプションは他にもたくさんあります。自分の目的に合ったオプションを選んでdiffを活用してください。
■■■4.4.5 最新の2つのリビジョンを比べてみる
モジュールの中に含まれる各ファイルについて最新のdiffやrdiffの-rオプションで指定するのは、実は結構めんどうです。あるファイルは最新が、1.11で違うファイルは1.2というようにバージョンがばらけている場合にいちいち指定するのは大変ですね。タグをつければ指定できますが、そこまでしたくないというのはあります。そんなときには、rdiffの-tオプションを使うのが便利です。
これまでお世話になってきたモジュールcvstest2について実行してみましょう。たくさん結果が出てくるので、【図4.4.17】ではちょっと省略しています。たくさん出てくる様子は実際にやってみてください。
【図4.4.17】rdiffを-tオプションつきで実行してみる
▼
% cvs -d /home/cvsroot rdiff -t cvstest2
cvs rdiff: Diffing cvstest2
Index: cvstest2/difftest.txt
diff -c cvstest2/difftest.txt:1.2 cvstest2/difftest.txt:1.3
*** cvstest2/difftest.txt:1.2 Tue Aug 20 23:19:58 2002
--- cvstest2/difftest.txt Tue Aug 20 23:20:24 2002
***************
*** 1,4 ****
--- 1,6 ----
This is a diff test file.
Spaces ignoring test.
+
+
Blank lines ignoring test.
Index: cvstest2/tmp2.txt
diff -c cvstest2/tmp2.txt:1.1 cvstest2/tmp2.txt:1.2
*** cvstest2/tmp2.txt:1.1 Tue Aug 20 21:30:27 2002
--- cvstest2/tmp2.txt Tue Aug 20 21:44:13 2002
(中略)
diff -c cvstest2/dir1/tmp3.txt:1.1 cvstest2/dir1/tmp3.txt:1.2
*** cvstest2/dir1/tmp3.txt:1.1 Tue Aug 20 21:30:27 2002
--- cvstest2/dir1/tmp3.txt Tue Aug 20 21:44:13 2002
***************
*** 1 ****
--- 1,2 ----
This is a third test file.
+ Commitment test.
cvs rdiff: Diffing cvstest2/dir1/dir2
cvs rdiff: Diffing cvstest2/newdir
cvs rdiff: Diffing cvstest2/newdir2
▲
残念ながら、この比較では-Bなどのこまごまとしたオプションは使えません。
注:筆者のRHL7.3+cvs-1.11.2の環境では-tオプションはうまく機能しませんでした。Solaris2.7+cvs-1.11.2では動作確認しています。
■■■4.4.6 ある時点から変更が加えられたかどうか調べる
意外と知られていないのが、ある時点以降に加えられた変更の概要をrdiffの-sオプションで見ることができるということです。どのようにするかというと、【図4.4.18】のようにします。
ここでは-Dオプションで日付を指定していますが、-rオプションでリビジョンを指定してもかまいません。モジュールcvstest2について、2時間10分前以降に加えられた変更の概要が一覧になって出てきているのがわかると思います。difftest.txtとcvstest2/newdir2/test.txtが新しく加えられそれぞれ現在1.3と1.1になっていること、cvstest2/tmp1.txtが削除されていること、cvstest2/tmp2.txtとcvstest2/dir1/tmp3.txtが変更されていて、両方ともリビジョンが1.1から1.2へと上がっていることが、このメッセージから読み取れます。
これを利用して、プログラムのビルドを自動化するということをしている人もいるようです(変更があった場合チェックアウトしてクリーンビルドする)。
【図4.4.18】rdiffを-sオプションつきで実行してみる ▼ cvs -d /home/cvsroot rdiff -s -D "2 hour 10 minutes ago" cvstest2 cvs rdiff: Diffing cvstest2 File cvstest2/difftest.txt is new; current revision 1.3 File cvstest2/tmp1.txt is removed; not included in current release File cvstest2/tmp2.txt changed from revision 1.1 to 1.2 cvs rdiff: Diffing cvstest2/dir1 File cvstest2/dir1/tmp3.txt changed from revision 1.1 to 1.2 cvs rdiff: Diffing cvstest2/dir1/dir2 cvs rdiff: Diffing cvstest2/newdir cvs rdiff: Diffing cvstest2/newdir2 File cvstest2/newdir2/test.txt is new; current revision 1.1 ▲
■■■4.4.6 WinCvsで差分を見る
WinCvsで差分を見る前に、まず上で利用したdifftest.txtをこちらにもwintest/difftest.txtとして作成しておきましょう【図4.4.19】。
【図4.4.19】
ここで、この差分を見たいファイルwintest/difftest.txtを選んだ状態で、メニュー[問合せ]→[比較(Diff)]【図4.4.20】を選ぶか、ファイルバー
の比較アイコン
を選ぶかします。
【図4.4.20】 [問合せ]→[比較(Diff)]メニュー

選ぶと、【図4.4.21】のようなダイアログが現われ、比較のやり方を指定するように促されます。初期設定は「ローカルのファイルと同じリビジョンのファイルを比較する(M)」にチェックが入っていて、このまま「OK」すると、手元のファイルとそのリビジョンを比較します。要するにオプションなしでのdiffコマンドの実行です。一般的には、最後のコミットと比べることになります。
【図4.4.21】 比較方法を選べと言われているようだ

ここで、「OK」を選ぶと、比較結果が表示されます【図4.4.22】。なんでかコードは1なんですよね…。
【図4.4.22】 ▼ cvs diff difftest.txt (ディレクトリ C:\home\mika\workcopy\wintest\ 内) Index: difftest.txt =================================================================== RCS file: C:\home\cvsroot/wintest/difftest.txt,v retrieving revision 1.3 diff -r1.3 difftest.txt 1,2c1,2 < This is a diff test file. < Spaces ignoring test. --- > This is a diff test file. Which is modified? > Spaces ignoring test. 4,6c4,5 < < < Blank lines ignoring test. \ No newline at end of file --- > Blank lines ignoring test. > This is an additional line. \ No newline at end of file *****CVS はコード 1 で終了しました***** ▲
「空白の違いを無視(W)」は-wオプション、「大文字小文字の違いを無視(C)」は-iオプションのことです。-Bや-bなどこまごまとしたオプションは指定できないようです。どうしても使いたい場合は、コマンド入力を利用するか、.cvsrcを利用してオプションの初期設定をしておくしかないと思います。例えば、diff -c -Bなどと.cvsrcに書いて$HOME領域に置いておくと、常時コンテキスト形式で空白行を無視するようになります。
■■■■ 外部の比較プログラムを利用してみよう
ここで特筆すべきなのは、外部のdiffプログラムを利用できるということでしょうか。Windows固有の比較ツールを使いたいという要望があるらしく、それに応えるために、外部の比較プログラムを呼び出すことができるようになっています。これを利用すると、よりビジュアルな表示の出来るプログラムを利用できたりするようになります。例えば、ExamDiffという比較ツールを利用する例を示してみます。
ExamDiff: http://www.prestosoft.com/examdiff/examdiff.htm
比較ツールの指定は、まずメニュー[管理]→[設定(E)]【図4.4.23】で行います。
【図4.4.23】 [管理]→[設定(E)]メニュー

設定メニューを選ぶと現われるダイアログの中から、WinCvsのタブを選びます。中央付近に、外部の比較ツールを使用する(D)というチェックボックスがあり、これをチェックすると右側のボックスにプログラムを指定することができるようになります。「…」ボタンから参照するなり、直にパスを打ち込むなりしてプログラムを指定すれば、完了です。たとえば、C:\Program Files\ed16f\ExamDiff.exeに置いているとすると、そのパスを指定します【図4.4.24】 。
【図4.4.24】 外部の比較ツールを指定してみよう

この状態で、比較ダイアログ【図4.4.21】で「外部のdiffプログラムを利用する」にチェックをつけて実行すれば、ExamDiffを呼び出すことができるようになります。

例えば【図4.4.6】の状態になっているdifftest.txtを用意して実行した例を【図4.4.x】に示します。
【図4.4.x】

ちなみに、日本語をうまく表示するには[View]→[Options...]→[Display]→[Change Font...]で「フォント名(F)」を日本語フォント(MS ゴシックなど)に、「文字セット(R)」を「日本語」にしておく必要があります。
【図4.4.x】
ExamDiffには固有の比較オプションが用意されています。このように外部プログラムを活用することが多いため、cvsのdiffのオプションのサポートがいまいちなのかも知れません。
■■■4.4.7 まとめ
●ファイル(targetfile)について現在の状態と最新リビジョンとの違いを見るには 作業コピー内に入る ↓ cvs diff targetfile ●ファイル(targetfile)について2つのリビジョン(1.xと1.y)との違いを見るには 作業コピー内に入る ↓ cvs diff -r1.x -r1.y targetfile ●作業コピーを使わずにファイル(module/targetfile)について2つのリビジョン(1.xと1.y)との違いを見るには cvs -d /home/cvsroot rdiff -r1.x -r1.y module/targetfile ●あるモジュール(targetmodule)内のファイルについて最新の2つのリビジョンの違いを見るには cvs -d /home/cvsroot rdiff -t targetmodule ●あるモジュール(targetmodule)についてある時点(mm/dd/yy)から加えられた変更の概要を見るには cvs -d /home/cvsroot rdiff -s -D "mm/dd/yy" targetmodule ●その他使うと便利なdiffのオプション -c 人間の見やすいコンテキスト形式で出力 -B 空行の追加削除を無視 -b 空白の増減を無視(前の状態に空白はあること) -w 空白の増減を無視(前の状態に空白は無くてもよい)