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 とは何か?
patch は diff が生成した差分を、別のファイルに適用するコマンドだ。ソフトウェアのバグ修正やセキュリティパッチを配布する際に広く使われる。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