#navi_header|技術| 細かいところとかが結構「あれれ?」となりやすいので、patchの使い方を今一度自分用にメモ。 - GNU Diffutils -- http://www.gnu.org/software/diffutils/ - GNU Diffutils HTML ドキュメント(1ページ版) -- http://www.gnu.org/software/diffutils/manual/html_mono/diff.html - Linux jman の patch -- http://www.linux.or.jp/JM/html/GNU_patch/man1/patch.1.html - FreeBSD の patch (FreeBSD 5.0) -- http://www.jp.freebsd.org/cgi/mroff.cgi?subdir=man&lc=1&cmd=&man=patch&dir=jpman-5.0.0/man§=0 * 基本 patchコマンドはカレントディレクトリのソースツリーに対して処理する。 patch < patchfile # タブやスペースマッチの条件を緩めにする patch -l < patchfile # パッチ適用ファイルに対して".orig"拡張子をつけてバックアップする。 patch -b < patchfile "-b"によるバックアップファイルの拡張子を変更するには・・・ GNUの場合: patch -b -z .bk < patchfile FreeBSDの場合: patch -b .bk < patchfile "-d ディレクトリ名"を指定すると、そのディレクトリに移動してから処理が始まる。 ** (個人的に)一番重要なオプション "-pNum" + "--dry-run"/"-C or --check" patchを実行する前に、「何が行われるのか確認だけしたい」場合は以下のオプションを使う。 GNUの場合: patch ... --dry-run ... < patchfile FreeBSDの場合:(-C or --check) patch ... -C ... < patchfile patchを実行する時に個人的に極めて重要だと考えているオプションが "-pNum" オプションである。 "-pNum"を使うと、patchfileで見つかったファイル名それぞれについてNum個のスラッシュとその間のディレクトリ名を除去する。 patchfile中のファイル名が proj-0.0.1/src/foo/bar/main.c であったとすると、以下のように調整される。 - "-p" 指定無し : カレントディレクトリ中のファイル、すなわち "`pwd`/main.c" が適用対象となる。 - "-p0" or "-p" 指定時 : パス名は変更されない。"`pwd`/proj-0.0.1/src/foo/bar/main.c"が適用対象となる。 - "-p1" 指定時 : 最初の"/"とその間のディレクトリ名が除去されるので、"proj-0.0.1/"が除去される。従って "`pwd`/src/foo/bar/main.c" が適用対象となる。 - "-p2" 指定時 : 2番目の"/"とその間のディレクトリ名が除去されるので、"proj-0.0.1/src/"が除去される。従って "`pwd`/foo/bar/main.c" が適用対象となる。 個人的な経験として、Linuxに触りだした当時、雑誌記事を見つつソースコードを弄っていた時"-p"オプションの意味を知らずにpatchを無理矢理あててしまい、ソースコードがぐちゃぐちゃになってしまった事がある。 patchファイルを作成した人の環境と、自分の環境は必ず異なるので、"--dry-run/-C/--check"を活用して丁寧に確認してからpatchを適用するよう心がけたい。 ** "-R"によるロールバック "-R"は本来の意味としては「patchfileの中の新旧が逆でした~」というpatchを当てたい時に使う。 しかし見方を変えれば、旧→新で作られた正常なpatchfileを「新→旧へのロールバック用patch」として処理する事を意味する。 従って、パッチ適用後にパッチに間違いが発見され、ロールバックしたい場合は、適用時のオプションに "-R" を加えるだけで適用前の状態にロールバックできる。 $ patch -p1 < foobar.patch ↓ロールバックしたい・・・ $ patch -p1 -R < foobar.patch なお、ed形式のpatchファイルについては必要な情報が不足している為、"-R"オプションは使えない。 ** より良いpatchファイルを作成するには Linux jman, FreeBSDのmanページ共に「パッチを送る人への注意」「パッチ作成者への注意」という項目があり、参考になる。 + "patchlevel.h"というファイルを必ず更新するようにしておくと、今どのpatchlevelが当たっているのか分かりやすい。(ソースコード管理ツールが普及した今でも通用するのかな?) + "diff -uNr dir_old dir_new"などで、"dir_old"や"dir_new"にスラッシュを含めない。("-p"でのずれや混乱をなるべく抑える) + 上記に関連して、"-pNum"の調整が必要な場合は、ユーザーにきちんとアナウンスする。 + さらに関連して、"-pNum"の調整をユーザーにお願いする場合は、diffする時のディレクトリ階層を合わせておく事。"diff foo/bar/baz/main.c baz/main.c"のようにしてしまうと"-pNum"が上手く動かなくなってしまう為。 + 日付については世界協定時を用いてdiffするとよい。"LC_ALL=C TZ=UTC0 diff..."とするとよい。 + 新規ファイルの作成や、ファイル削除については "diff -N"オプションを使ってpatchファイルを作成すると良い。 + リバースパッチを送らないよう注意しよう! + 適当な大きさに分割する事。 #navi_footer|技術|