patch コマンドはDiffコマンドで作った差分ファイルを適用します。
実運用でのDiff
Diffは新規ファイルや削除、再帰的にたどるオプションをつけて実行します。
diff -urN older_dir newer_dir > `date +%Y-%m-%d`.patch
-r 再帰的 -N 新規ファイルを空ファイルと見なす -u ユニファイド形式
パッチを適用するには、ディレクトリに入ってパッチを流し込みます。
cd older_dir patch -p1 < 2011-02-13.patch
これだけでだとなんかよく分からないので、実際にDiffを取ったりPatchを当てて遊んでみた。
diff を取り消したいとき ` -R ` をつける
diff を revert したいときにはオプションで付けられる。これで元にもどる。
cd older_dir patch -p1 -R < 2011-02-13.patch
patchコマンドを使って遊んでみた。
ファイル単位の差分とパッチ
ファイルをつくりりました。
パッチ作成(差分を作成)
diff -u misdo misdo.2 > misdo.patch
パッチの適用
patch misdo < misdo.patch
ファイル"misdo"にパッチをあてて "misdo2"の状態にしました。
適用結果
diff misdo misdo.2 #二つのファイルは同じです。
ディレクトリの差分を適用
patch -p0 # ディレクトリ名
patch -p0 < shop.patch
結果
$ ls -l 合計 1 -rw-r--r--+ 1 takuya None 249 2月 13 01:18 shop.patch drwxr-xr-x+ 1 takuya None 0 2月 13 01:19 shop1 drwxr-xr-x+ 1 takuya None 0 2月 12 23:57 shop2
カレントディレクトリにパッチを適応したのです。
さらに一段下にいる場合
patch -p1 # ディレクトリの上位一つを無視
patch -p1 < ../shop.patch patching file misdo takuya@letsnote:~/test/shop1$ ls -l 合計 1 -rw-r--r--+ 1 takuya None 92 2月 13 02:21 misdo
このように、どのディレクトリにパッチを当てるかで -p のオプション値が変わるのです。
diffについて
patchを試すには、差分がないと何もできません。差分はdiffコマンドで作ります。diffコマンドで差分を作ることができます。diffコマンドはファイル・ディレクトリの中身を一行ずつ調べて違いを表示してくれます。まずは、diffコマンドでファイル差分を取得します。
先ほどと同じmisdoファイルでやってみます。
misdo
ツイスト オールドファッション ポンデリング
このファイルに一行書き加えたのがmisdo2
misdo.2
ツイスト フレンチクルーラー オールドファッション ポンデリング
差分を取得します
diff misdo misdo.2 1a2 > フレンチクルーラー
これが標準形式のDiffです。ぱっと見た目ではわかりにくいです。
diffの出力形式には複数あります。つまり、差分を表現するフォーマットが複数有り、そのどれかから選んで差分を書き出すことができます。
diffの出力形式にはいろいろある
- 標準形式 オプション無し
- コンテキスト(context) 形式 オプション -c
- ユニファイド形式(unified) オプション -u
- ed 形式 (ed) オプション -e *1
context 形式の差分を作ってみます。
diff -c misdo misdo.2 *** misdo 2011-02-12 23:08:31.144081900 +0900 --- misdo.2 2011-02-12 23:09:31.048187100 +0900 *************** *** 1,4 **** --- 1,5 ---- ツイスト + フレンチクルーラー オールドファッション ポンデリング
unified形式を作ってみます。
diff -c misdo misdo.2 *** misdo 2011-02-12 23:08:31.144081900 +0900 --- misdo.2 2011-02-12 23:09:31.048187100 +0900 *************** *** 1,4 **** --- 1,5 ---- ツイスト + フレンチクルーラー オールドファッション ポンデリング
形式の違いについて。
標準形式とed形式は、ファイルの差分情報だけです。この二つはファイル名情報が欠落しています。よってPatchには使いません。*2
一方、ユニファイド形式とコンテキスト形式はファイル名とディレクトリ情報が記述されています。差分を適用するとき、ユーザーがファイルを指定する必要がなくなります。
従って、PATCHファイルはコンテキスト形式(またはユニファイド形式)で作るそうです。
git/hg などバージョン管理ファイルのDiffを取っちゃう?
.gitの diff 取ってくれたりするので本当に不要だと思います.
diff --exclude=.git -urN from_dir to_dir > `date +%Y-%m-%d`.patch
のように exclude で除外できます.