diff3 - 3つのファイルを比較・マージする

diff3

diff3コマンドは3つのファイルを比較するコマンドになります。一つのファイルを元に複数の人が作業したときにその作業内容の比較を行いたいときやその作業内容を一つのファイルにまとめたいときに利用できます。

スポンサーリンク

diff3コマンドの基本的な構文

diff3コマンドの基本的な構文

第1引数のMYFILEはOLDFILEから作成されたファイルで、ファイルのマージを考える場合、OLDFILEとYOURFILEの差分を取り込むファイルとして指定します。
ただし、実際のファイル編集はedコマンド等を使用します。

第2引数のOLDFILEはMYFILEとYOURFILEが作成されたときの元になったファイルを指定します。

第3引数のYOURFILEはOLDFILEから作成されたもう一つのファイルを指定します。

diff3コマンドの例で使用するファイル

diff3コマンドを使用する例として、C言語の3つの不完全なプログラムを使用します。1つはプログラムの仮組みの状態のもの、後の2つはその仮組みのプログラムから一部の機能を実装したものになります。以下の3つのプログラムを使用して、diff3コマンドを利用します。

base.c(第2引数のOLDFILEとして使用)

base.cは、後述のmyfile.cとyourfile.cを作成するときに元となっているファイルになっています。プログラムとして行いたいことは単純に数値の足し算と引き算になります。

base.cは不完全なプログラムで、myfile.cとyourfile.cでそれぞれ足し算と引き算の関数を作成します。

myfile.c(第1引数のMYFILEとして使用)

base.cを元にして、足し算の関数を作成したものになります。

yourfile.c(第3引数のYOURFILEとして使用)

base.cを元にして、引き算の関数を作成したものになります。

また、上の3つのファイルをマージしたときに、意図するマージファイルは以下のファイルになります。

merge.c

diff3コマンドの利用例

3つのファイルを比較

diff3コマンドは3つのファイルを引数に取って、利用すると3つのファイルでの差分をそれぞれ表示します。

コマンド例と実行結果

差分の見方を説明します。差分の始まりとして最初に「====」のような行が入ります。

それぞれのファイルの箇所で差分のかたまりを表示します。それぞれのファイルの差分については、差分の最初に「1:3,7c」のような行が出力されます。

これは1つ目の引数のファイルで、3行目から7行目までの行の範囲で差分のかたまりが存在することを示しています。そのあとの行は差分に該当する箇所になります。

同様に、「2:2a」のような行もあります。これは2つ目の引数のファイルで、2行目に差分のかたまりが該当して、その2つ目の引数のファイルには差分の行がないことを表しています。

次の「3:3,7c」は、最初の「1:3,7c」と同様で、3つ目の引数のファイルで、3行目から7行目までの行の範囲で差分のかたまりがすることを示しています。そのあとの行も同様に、差分に該当する箇所になります。

「====1」のように「====」の後に数字がある行から始まる差分もあります。
「====1」は、差分個所が3つのファイルの内の2つのファイルが共通で、1つ目の引数のファイルだけが異なることを表しています。

OLDFILEとYOURFILEの差分をMYFILEに適用するedスクリプトを出力
(-eオプション)

-eオプションは、MYFILEに適用するedスクリプトを出力します。また、このedスクリプトはOLDFILEからYOURFILEの差分(変更箇所)を出力します。

コマンド例と実行結果

-eオプションにさらに-iオプションを追加することで、ファイルを実際に編集するようなスクリプトになります(最後に書き込みのwと終了のqが追加されます)。

コマンド例と実行結果

このedスクリプトを適用した結果を表示すると以下のような結果を得ることができます。
実際に-eオプションで作成されたスクリプトをedコマンドで適用すると、MYFILEとYOURFILEで競合する箇所ではYOURFILEの変更が優先されます。

コマンド例と実行結果

また、edスクリプトを適用した結果は、-m(--merge)オプションを使用することで出力できます。
コマンド例と実行結果

全てのファイルでの競合箇所を含めるedスクリプトを出力
(-Aオプション)

-Aオプションは、MYFILEに適用するedスクリプトを出力します。このedスクリプトは全ての変更点に関して、競合している箇所にコンフリクトマーカーをつけて出力されます。

コマンド例と実行結果

コンフリクトマーカーはそれぞれの差分のかたまりについて、

のように表示して、全てのファイルの変更点に関しての競合(conflict)を表します。実際に意図したマージファイルを完成させたい場合は、この競合箇所をエディタなどで編集すると簡単にマージしたファイルを作成できます。

上の出力を競合箇所を編集して、merge.edを作成し、edコマンドを適用することでマージファイルの出力を得る事もできます。

merge.ed

編集個所として、コンフリクトマーカーのある個所を削除しています。

コマンド例と実行結果

上のコマンドは出力結果の表示のみを行い、実際にはファイルを編集していません。edコマンドの「1,$p」は1行目から最後の行までの表示を表しています。
実際にファイルへ編集を保存するには以下のようなコマンドを利用できます(edスクリプトにw(書き込み、write)とq(終了、quit)を追加しています)。
コマンド例と実行結果

ファイルのマージ
(-mオプション)

-m(--merge)オプションは、ファイルをマージした出力を表示できます。マージした出力とは、-Aオプション(-mオプションのデフォルト)や-eオプションのedスクリプトをMYFILEに適用した結果の出力になります。

コマンド例と実行結果

上の出力結果をファイルに保存し、viエディタ等で編集することでマージしたファイルを作成することもできます。

merge.c

MYFILEとYOURFILEの変更箇所の競合を含めるedスクリプトを出力
(-Eオプション)

-Eオプションは、-eオプションと同じようにMYFILEへ適用するedスクリプトを出力します。
OLDFILEからYOURFILEの差分をMYFILEに適用するためのスクリプトを出力します。

しかし、競合を表示する情報が-Aオプションと比べて少なくなり、このスクリプトを適用したときに、MYFILEから変更する箇所にコンフリクトマーカ―が表示されます。

コマンド例と実行結果

-mオプションを利用し、マージした結果は以下のような出力になります。

コマンド例と実行結果

-Eオプションの競合箇所については

のようになり、-Aオプションと比べて、OLDFILEについての差分個所が現れないのが特徴になります。

MYFILEでの競合しない個所のみを出力
(-3オプション)

-3オプションは、MYFILEに適用するedスクリプトを出力します。また、このedスクリプトはOLDFILEからYOURFILEの差分(変更箇所)で競合していない箇所のみを出力します。

コマンド例と実行結果

-mオプションを利用し、マージした結果は以下のような出力になります。

コマンド例と実行結果

MYFILEでの競合する箇所のみを出力
(-xオプション)

-xオプションは、MYFILEに適用するedスクリプトを出力します。また、このedスクリプトはOLDFILEからYOURFILEの差分(変更箇所)での競合する箇所のみを出力します。競合している箇所はYOURFILEの内容が優先になり、MYFILEの内容を上書きするスクリプトが出力されます。

コマンド例と実行結果

-mオプションを利用し、マージした結果は以下のような出力になります。

コマンド例と実行結果

MYFILEでの競合する箇所のみをコンフリクトマーカーをつけて出力
(-Xオプション)

-Xオプションは、MYFILEに適用するedスクリプトを出力します。また、このedスクリプトはOLDFILEからYOURFILEの差分(変更箇所)での競合する箇所のみを出力します。ただし、競合している箇所でMYFILEの内容が上書きされる個所はコンフリクトマーカーをつけて出力されます。

コマンド例と実行結果

-mオプションを利用し、マージした結果は以下のような出力になります。

コマンド例と実行結果

参考

GNU diffutils - Comparing and Merging Files

GNU 'ed' Manual

スポンサーリンク
スポンサーリンク