パッチの作成と応用


コマンドの概要
使用する2つのコマンドはdiffとpatchです.
diff
diffは2つのものを比較し、両者の違いを同時に記録することができる.パッチを作成する際の一般的な使用方法と一般的なオプションは、次のとおりです.
diff 【  】    ( )     ( )
-r再帰.設定後、diffは2つの異なるバージョンのソース・コード・ディレクトリのすべての対応するファイルをサブディレクトリ・ファイルを含むすべて比較します.-Nオプションでは、作成または削除されたファイルがパッチファイルで正しく処理されることを確認します.-u修正前後の各3行を出力し、-u 5などでより多くのコンテキストを出力するよう指定することもできます.-E,-b,-w,-B,--strip-trailing-crは各種の空白を無視し、ドキュメントを参照し、必要に応じて選択することができる.
patch
patchの役割はdiffレコードの結果(すなわちパッチ)を対応するファイル(クリップ)に適用することである.最も一般的な使い方は次のとおりです.
patch -pNUM <patchfile>
-pNumは、いくつかのフォルダを無視し、詳細に説明します.-Eオプションは、空のファイルが見つかった場合、-Rが適用したパッチを削除することを示します.
-pパラメータを説明するには、次のpatchファイルクリップを参照します.
--- old/modules/pcitable       Mon Sep 27 11:03:56 1999 +++ new/modules/pcitable       Tue Dec 19 20:05:41 2000

パラメータ-p 0を使用すると、現在のディレクトリからoldというフォルダを探し、その下にmodules/pcitableファイルを探してpatch操作を実行します.パラメータ-p 1を使用すると、第1階層ディレクトリ(すなわちoldにかかわらず)を無視し、現在のディレクトリからmodulesのフォルダを探し、その下にpcitableを探すことを意味します.
適用
次のコマンドを使用して、単一のファイルパッチを処理します.
#      diff -uN from-file to-file >to-file.patch
  #     patch -p0 < to-file.patch
  #      patch -RE -p0 < to-file.patch

フォルダ全体にパッチを適用する場合:
#      diff -uNr from-docu  to-docu >to-docu.patch
  #     cd to-docu patch -p1 < to-docu.patch
  #      patch -R -p1 <to-docu.patch

また、バージョン管理ツールを使用する場合は、svn diffまたはgit diffでパッチファイルを直接生成できます.
なお,パッチ適用時のターゲットコードとパッチ生成時のコードが必ずしも同じとは限らないため,パッチ適用操作が失敗する可能性がある.パッチに失敗したファイルは.rejの最後に、次のコマンドはすべてのrejファイルを見つけることができます.
find . -name '*.rej'

patchファイル構成
パッチファイルにはいったいどんな情報が格納されているのでしょうか.この例を見てみましょう.
--- test0       2006-08-18 09:12:01.000000000 +0800 +++ test1       2006-08-18 09:13:09.000000000 +0800 @@ -1,3 +1,4 @@ +222222 111111 -111111 +222222 111111

パッチヘッダは、パッチを適用するファイルを表すために---/++で始まる2行です.---先頭は古いファイル、+++先頭は新しいファイルです.1つのパッチファイル内の複数のパッチ1つのパッチには、1つのパッチを適用するために使用される---/++で始まる多くのセクションが含まれます.したがって、1つのパッチファイルに複数のパッチを含めることができます.ブロックはパッチで修正する場所です.それは通常、一部の修正されていないものから始まり、終わります.彼らは修正する位置を表すだけです.彼らは通常@で始まり、別のブロックの開始または新しいパッチヘッダで終了します.ブロックのインデントブロックは列をインデントします.この列は、行が増加するか削除されるかを示すために使用されます.ブロックの最初の列+番号は、この行が追加されることを示します.-番号は、この行が削除されることを示します.プラス記号もマイナス記号もないのは、ここでは参照されているだけで、修正する必要はありません.
インスタンス分析
シングル・ファイル・パッチ
現在のディレクトリにファイルtest 0があるとします.
111111 111111 111111

およびファイルtest 1:
222222 111111 222222 111111

diffを使用してパッチtest 1を作成する.patch
diff -uN test0 test1 > test1.patch

単一のファイルなので、-rオプションは必要ありません.このコマンドには、次のパッチが適用されます.
--- test0       2006-08-18 09:12:01.000000000 +0800 +++ test1       2006-08-18 09:13:09.000000000 +0800 @@ -1,3 +1,4 @@ +222222 111111 -111111 +222222 111111

パッチを適用するには、次の手順に従います.
$ patch -p0 < test1.patch
patching file test0

このときtest 0はtest 1と同じです.
パッチの変更をキャンセルする場合は、次の手順に従います.
$ patch -RE -p0 < test1.patch
patching file test0

フォルダパッチ
以下の環境があります.
--prj0/
     test0
     prj0name
--prj1/
     test1
     prj1name

prj 0/prj 0 nameの内容は次の3行です.
--------
prj0/prj0name
--------

prj 1/prj 1 nameの内容は以下の3行である.
--------
prj1/prj1name
--------

diff-uNRでパッチを作成し、
diff -uNr prj0 prj1 > prj1.patch

得られたpatchファイルは:
diff -uNr prj0/prj0name prj1/prj0name --- prj0/prj0name       2006-08-18 09:25:11.000000000 +0800 +++ prj1/prj0name       1970-01-01 08:00:00.000000000 +0800 @@ -1,3 +0,0 @@ --------- -prj0/prj0name --------- diff -uNr prj0/prj1name prj1/prj1name --- prj0/prj1name       1970-01-01 08:00:00.000000000 +0800 +++ prj1/prj1name       2006-08-18 09:26:36.000000000 +0800 @@ -0,0 +1,3 @@ +--------- +prj1/prj1name +--------- diff -uNr prj0/test0 prj1/test0 --- prj0/test0  2006-08-18 09:23:53.000000000 +0800 +++ prj1/test0  1970-01-01 08:00:00.000000000 +0800 @@ -1,3 +0,0 @@ -111111 -111111 -111111 diff -uNr prj0/test1 prj1/test1 --- prj0/test1  1970-01-01 08:00:00.000000000 +0800 +++ prj1/test1  2006-08-18 09:26:00.000000000 +0800 @@ -0,0 +1,4 @@ +222222 +111111 +222222 +111111

このパッチを適用する場合は、次の手順に従います.
$ ls prj0  prj1  prj1.patch
$ cd prj0
$ patch -p1 < ../prj1.patch
patching file prj0name
patching file prj1name
patching file test0
patching file test1

パッチ適用後の結果はlsで表示できます.
$ ls prj1name  test1

同様に、パッチ操作をロールバックする場合は、次のようになります.
$ patch -R -p1 < ../prj1.patch
patching file prj0name
patching file prj1name
patching file test0
patching file test1
$ ls prj0name  test0