diff/patch 入門 - 差分の取得と適用

diff/patch 入門 - 差分の取得と適用

この記事で解決できること

  • diff コマンドで 2つのファイルの差分を取り出す方法が分かる
  • diff -u(unified 形式)の 出力の読み方が分かる
  • patch コマンドで 差分を別のファイルに適用する方法が身につく
  • 逆適用(patch -R)でパッチを 元に戻す方法が分かる

結論(実務の型)

  • 差分確認: diff -u old_file new_file
  • パッチ保存: diff -u old_file new_file > changes.patch
  • パッチ適用: patch -p0 < changes.patch
  • 逆適用: patch -R -p0 < changes.patch

前提(対象環境)

  • OS: Ubuntu / Debian 系 Linux
  • diff / patch コマンドが使用可能(標準搭載)

diff とは何か?

diff は 2 つのファイルを比較して、どの行がどう変わったかを出力するコマンドだ。ソースコードの変更点確認や設定ファイルの比較に日常的に使われる。引数に渡した2つのファイルを行単位で比較し、差分だけを標準出力に出力する。

diff の基本的な使い方

2つのファイルを比較する

$ diff old.txt new.txt

変更がない場合は何も出力されない。変更がある場合は以下のような出力になる。

2c2
< 古い内容
---
> 新しい内容

この「normal 形式」は読みにくい。実務では unified 形式を使う。

unified 形式(-u オプション)

-u オプションを付けると unified 形式で出力される。パッチファイルの標準形式で最も広く使われている。

$ diff -u old.txt new.txt

出力例:

--- old.txt	2026-06-01 10:00:00.000000000 +0900
+++ new.txt	2026-06-01 10:05:00.000000000 +0900
@@ -1,5 +1,5 @@
 行1(変更なし)
-古い行2
+新しい行2
 行3(変更なし)

読み方:

記号 意味
--- 変更前のファイル
+++ 変更後のファイル
@@ 変更箇所の行番号情報
- 削除された行
+ 追加された行
(スペース) 変更なし(コンテキスト行)

@@ -1,5 +1,5 @@ は「変更前ファイルの1行目から5行 / 変更後ファイルの1行目から5行」を示す。この前後3行がコンテキスト行として表示される。

ディレクトリを再帰的に比較する(-r オプション)

$ diff -ur dir_old/ dir_new/

-u(unified 形式)と -r(再帰)を組み合わせてディレクトリ全体の差分を一度に確認できる。

diff の出力をパッチファイルに保存する

リダイレクトで保存するだけだ。

# ファイル単体
$ diff -u old.txt new.txt > changes.patch

# ディレクトリ全体
$ diff -ur dir_old/ dir_new/ > project.patch

このファイルが patch コマンドに渡す「パッチファイル」になる。

patch とは何か?

patchdiff が生成した差分を、別のファイルに適用するコマンドだ。ソフトウェアのバグ修正やセキュリティパッチを配布する際に広く使われる。diff で差分を生成し、patch で適用する、という組み合わせが基本形だ。

patch の基本的な使い方

-p オプションとは何か?

-p はパッチ内のパス(--- a/path/to/file.txt の部分)から先頭のディレクトリをいくつ除去するかを指定する。

オプション 動作
-p0 パスをそのまま使う
-p1 先頭の1要素を除去(a/b/ を取り除く)
--- a/path/to/file.txt    ← -p1 を使うと "path/to/file.txt" として解釈
+++ b/path/to/file.txt

Git が生成するパッチは a/ b/ プレフィックスを付けるため、-p1 が一般的だ。

シンプルなパッチ適用(-p0)

diff -u で直接作ったパッチを適用する場合:

$ patch -p0 < changes.patch

適用前に --dry-run で確認する。

$ patch --dry-run -p0 < changes.patch

--dry-run は実際にはファイルを変更しない。適用できるかどうかだけ確認できるため、本番実行前の確認に必須だ。

Git 形式のパッチ(-p1)

Git リポジトリや多くのオープンソースプロジェクトのパッチには -p1 を使う。

$ patch -p1 < project.patch

パッチの逆適用(元に戻す)

-R オプションでパッチを逆適用(ロールバック)できる。

$ patch -R -p0 < changes.patch

逆適用はパッチ内のコンテキスト行がファイルと一致する場合のみ成功する。すでに対象ファイルが別の変更を受けていると失敗することがある。

実践的なワークフロー

設定ファイルの変更を共有する

# 1. 元のファイルをバックアップ
$ cp config.conf config.conf.orig

# 2. ファイルを編集
$ vim config.conf

# 3. 差分をパッチファイルに保存
$ diff -u config.conf.orig config.conf > config-fix.patch

# 4. 受け取った側がパッチを適用
$ patch --dry-run -p0 < config-fix.patch
$ patch -p0 < config-fix.patch

ソフトウェアソースへのパッチ適用

# プロジェクトルートで実行
$ patch -p1 < bugfix.patch

# 問題があれば逆適用
$ patch -R -p1 < bugfix.patch

まとめ:diff/patch の要点

コマンド 用途
diff -u old new unified 形式で差分確認
diff -ur dir1/ dir2/ ディレクトリ全体を比較
diff -u old new > fix.patch パッチファイルを生成
patch --dry-run -p0 < fix.patch 適用前の確認
patch -p0 < fix.patch パッチを適用(通常形式)
patch -p1 < fix.patch パッチを適用(Git 形式)
patch -R -p0 < fix.patch パッチを逆適用

コピペ用テンプレ

# パッチ生成
diff -u original.txt modified.txt > changes.patch

# 適用前確認
patch --dry-run -p0 < changes.patch

# 適用
patch -p0 < changes.patch

# 逆適用(元に戻す)
patch -R -p0 < changes.patch

次に読む