patch

オープンソースであるNetHackは、NetHack開発者以外の人間による 修正・改造・追加が多数存在する。

大規模な改造はヴァリアントとして出ているが、小さな修正・追加は パッチという形式で出ている場合が多い。

基本的にはdiffコマンドによるソースファイルの差分ファイルとして 公開されているものである。

NetHackの主なパッチ

パッチの作り方

パッチは基本的にテキストファイルであるため、バイナリファイルがないか、 バイナリファイルに差がないことを前提とする。

修正前のファイルの入ったディレクトリ(仮にold_srcとする)と 修正後のファイルが入ったディレクトリ(仮にnew_srcとする)を 同じディレクトリ(仮にtempとする)内に配置し、 tempをカレントディレクトリとして以下のコマンドを実行する。

diff -aurN old_src new_src > foo.diff

オプションの意味は次のとおり:

  • -a が全ファイルをテキストとみなして処理する。昔のdiffはたまに日本語ファイルをバイナリ扱いする場合があったため。今はどうか知らないが。
  • -u がunified 出力形式を使用する。これは行頭に行追加を示す+と行削除を示す-を出力し、前後3行を比較のために出力する形式。
  • -r がサブディレクトリ配下を再帰的に比較する。
  • -N が片方にファイルが存在しなかった場合に全内容を出力する。新しいファイルを追加したり、ファイルを削除したり、ファイル名を変更したりしている場合に必要。

修正前と修正後のディレクトリが異なるディレクトリ内にある場合、 差分は作成できるが相対パス位置が作成したパッチに記録され、 パッチを当てるときの障害になるのでお勧めしない。

なお、CVSディレクトリ同士で差分をとる場合はオプションに -xCVS を 付加することでCVS管理ディレクトリ配下の差をパッチファイルに出力しないように することができる。

また、WindowsにてNetHackのパッチを作成するときは cygwin の Base-diffutils パッケージを使用するとよい。そのとき、オプションとして --strip-trailing-cr を 使用すれば、LF改行コードとCRLF改行コードの混在したファイルの差分を 正常に取ることが可能。

パッチの当て方

パッチを当てる元のディレクトリをカレントディレクトリとして、 以下のコマンドを実行する。

patch -p1 < foo.diff

カレントディレクトリの中身が書き換わるので元を残しておきたい場合は コピーしておくこと。

ちなみにオプションの意味は「パッチファイル内のdiffコマンドラインの 比較ディレクトリ名の最初のディレクトリ名を無視する」である。 パッチを当てる元のディレクトリ名と比較ディレクトリ名が同じ場合は パッチを当てる元のディレクトリの上位ディレクトリで patch -p0 < foo.diff とすることでパッチを当てることが可能。

また、WindowsにてNetHackのパッチを当てるときは cygwin の Devel-patchutils パッケージを使用するとよい。

パッチの外し方

同様に以下のコマンドを実行する。

patch -p1 -R < foo.diff

うまくいかないこともあるので、まっさらの状態のソースを保存しておいた方が無難かも。

関連リンク