HAYAGUI

FreeBSD 4.5 + diff と patch

はじめに

パッチ(patch) を作成する方法とパッチを作成する過程の diff の使い方を説明します。 詳しくは、以下のページをご参考ください。

diff

hoge.c というファイルがあります。
> ls
hoge.c
> cat hoge.c
#include <stdio.h>

int main()
{
    /* hogehoge */
    printf("Hello World!\n");
    printf("End!\n");

}
このファイルを更新する為、ファイルのバックアップを作成します。
> cp hoge.c hoge.c.20020901
> ls
hoge.c          hoge.c.20020901
hoge.c を以下のように変更します。
> cat hoge.c
#include <stdio.h>

int main()
{
    int i;

    for (i=0;i<10;i++){
        printf("Hello World!\n");
    }

    printf("End!\n");

}
diff の書式は、以下の通りです。
diff FROM_FILE TO_FILE
実行します。
> diff hoge.c.20020901 hoge.c
5,6c5,10
<     /* hogehoge */
<     printf("Hello World!\n");
---
>     int i;
>
>     for (i=0;i<10;i++){
>         printf("Hello World!\n");
>     }
>
c オプションをつけて context 出力形式で出力します。
> diff -c hoge.c.20020901 hoge.c
*** hoge.c.20020901     Sun Sep  1 16:23:40 2002
--- hoge.c      Sun Sep  1 16:27:26 2002
***************
*** 2,9 ****

  int main()
  {
!     /* hogehoge */
!     printf("Hello World!\n");
      printf("End!\n");

  }
--- 2,13 ----

  int main()
  {
!     int i;
!
!     for (i=0;i<10;i++){
!         printf("Hello World!\n");
!     }
!
      printf("End!\n");

  }
u オプションをつけて unified 出力形式で出力します。
> diff -u hoge.c.20020901 hoge.c
--- hoge.c.20020901     Sun Sep  1 16:23:40 2002
+++ hoge.c      Sun Sep  1 16:27:26 2002
@@ -2,8 +2,12 @@

 int main()
 {
-    /* hogehoge */
-    printf("Hello World!\n");
+    int i;
+
+    for (i=0;i<10;i++){
+        printf("Hello World!\n");
+    }
+
     printf("End!\n");

 }
y オプションをつけて side-by-side 出力形式で出力します。
> diff -y hoge.c.20020901 hoge.c
#include <stdio.h>                                #include <stdio.h>

int main()                                        int main()
{                                                 {
    /* hogehoge */                              |     int i;
    printf("Hello World!\n");                   |
                                                >     for (i=0;i<10;i++){
                                                >         printf("Hello World!\n");
                                                >     }
                                                >
    printf("End!\n");                                 printf("End!\n");

}                                                 }

patch の作成

u オプションをつけた場合、以下のように作成します。
> diff -u hoge.c.20020901 hoge.c > hoge.patch
> ls
hoge.c          hoge.c.20020901 hoge.patch
これで、差分が記述されている hoge.patch が作成されることになります。 パッチを hoge.c に当てる為、hoge.c を古いファイルに戻しておきます。
> cp hoge.c hoge.c.new
> cp hoge.c.20020901 hoge.c
>
> ls
hoge.c          hoge.c.20020901 hoge.c.new      hoge.patch
>
このディレクトリ内で、次のようにパッチを当てます。
> patch < hoge.patch
Hmm...  Looks like a unified diff to me...
The text leading up to this was:
--------------------------
|--- hoge.c.20020901    Sun Sep  1 16:23:40 2002
|+++ hoge.c     Sun Sep  1 16:27:26 2002
--------------------------
Patching file hoge.c using Plan A...
Hunk #1 succeeded at 2.
done
>
hoge.c に hoge.patch のパッチが当たっていることを確認します。
> cat hoge.c
#include <stdio.h>

int main()
{
    int i;

    for (i=0;i<10;i++){
        printf("Hello World!\n");
    }

    printf("End!\n");

}

diff しても、当然同じです。
> diff hoge.c.new hoge.c
>
今後は、c オプションをつけた場合のパッチファイルを作成します。
> diff -c hoge.c.20020901 hoge.c > hoge.patch
同じように hoge.c を修正前に戻します。
> cp hoge.c.20020901 hoge.c
パッチを当てます。
> patch < hoge.patch
Hmm...  Looks like a new-style context diff to me...
The text leading up to this was:
--------------------------
|*** hoge.c.20020901    Sun Sep  1 16:23:40 2002
|--- hoge.c     Sun Sep  1 17:17:27 2002
--------------------------
Patching file hoge.c using Plan A...
Hunk #1 succeeded at 2.
done
> ls
hoge.c          hoge.c.20020901 hoge.c.new      hoge.c.orig     hoge.patch
変更前のファイルが、hoge.orig という名前で作成されています。

ディレクトリ毎の場合

これまでは、一つのファイルについて diff と patch を行ってきました。次に、複数のファイルを持つディレクトリ に対して diff と patch をやってみましょう。
まず、いかのようなディレクトリとファイル構成があるとします。
> pwd
/usr/home/kenz/test
> ls
hoge1.txt       hoge2.txt
> cat hoge1.txt
1234567890
> cat hoge2.txt
abcdefghijklmn
>
次に、このディレクトリを test.20020901 というディレクトリにコピーして変更前のものとします。
> cd ..
> ls
test
> cp -R test test.20020901
次に、test ディレクトリ内のファイルを変更します。
> cat hoge1.txt
1234567890
one,two
> cat hoge2.txt
abcdefghijklmn
hogehoge

上のディレクトリに移動して、diff します。
> cd ..
> ls
test            test.20020901
> pwd
/usr/home/kenz
> diff -crN test.20020901 test
diff -crN test.20020901/hoge1.txt test/hoge1.txt
*** test.20020901/hoge1.txt     Sun Sep  1 22:04:07 2002
--- test/hoge1.txt      Sun Sep  1 22:12:34 2002
***************
*** 1 ****
--- 1,2 ----
  1234567890
+ one,two
diff -crN test.20020901/hoge2.txt test/hoge2.txt
*** test.20020901/hoge2.txt     Sun Sep  1 22:04:07 2002
--- test/hoge2.txt      Sun Sep  1 22:12:57 2002
***************
*** 1 ****
--- 1,2 ----
  abcdefghijklmn
+ hogehoge
この結果をパッチとして保存します。
> diff -crN test.20020901 test > test.patch
> ls
test            test.20020901   test.patch
では、test ディレクトリ内ファイルを元に戻します。
> cd ..
> rm -R test
> ls
test.20020901   test.patch
> cp -R test.20020901 test
> cd test
> ls
hoge1.txt       hoge2.txt
> cat hoge1.txt
1234567890
> cat hoge2.txt
abcdefghijklmn
> cd ..
> pwd
/usr/home/kenz
> ls
test            test.20020901   test.patch

では、パッチを当てます。
> patch < test.patch
Hmm...  Looks like a new-style context diff to me...
The text leading up to this was:
--------------------------
|diff -crN test.20020901/hoge1.txt test/hoge1.txt
|*** test.20020901/hoge1.txt    Sun Sep  1 22:04:07 2002
|--- test/hoge1.txt     Sun Sep  1 22:12:34 2002
--------------------------
Patching file test/hoge1.txt using Plan A...
Hunk #1 succeeded at 1.
Hmm...  The next patch looks like a new-style context diff to me...
The text leading up to this was:
--------------------------
|diff -crN test.20020901/hoge2.txt test/hoge2.txt
|*** test.20020901/hoge2.txt    Sun Sep  1 22:04:07 2002
|--- test/hoge2.txt     Sun Sep  1 22:12:57 2002
--------------------------
Patching file test/hoge2.txt using Plan A...
Hunk #1 succeeded at 1.
done
パッチが当たっているか確認しましょう。
> cd test
> ls
hoge1.txt       hoge1.txt.orig  hoge2.txt       hoge2.txt.orig
> cat hoge1.txt
1234567890
one,two
> cat hoge2.txt
abcdefghijklmn
hogehoge
正しくパッチが当たっていました。 尚、c オプションをつけたので、orig ファイルが作成されています。

戻る



(C)1999 - 2002 Kenji Ito All rights reserved.