С чего начать Первые шаги трек · 15 ступеней
Linux Labs

diff и patch — сравнение и применение изменений

4 мин GNU diffutils

Сравнение файлов и применение патчей; сравнить конфиги, увидеть изменения.

Шпаргалка

8 команд Версия для печати
  • diff -u a b читаемые различия
  • diff -qr dir1 dir2 какие файлы отличаются
  • diff <(cmd1) <(cmd2) сравнить вывод команд
  • diff -u orig new > p.patch сделать патч
  • patch orig < p.patch применить патч
  • patch --dry-run -p1 < git.patch проверить применение без записи
  • patch -R < p.patch откатить применённый патч
  • vimdiff a b бок о бок

Обзор

diff показывает различия между файлами; patch применяет такие различия. Полезно сравнить «было/стало» в конфигах, перенести правку, проверить, что изменилось.

bash
diff old.conf new.conf            # построчные различия
diff -u old.conf new.conf         # унифицированный формат (как в git/патчах)

Ключи

9

Ниже — основные ключи diff и patch; полный список — man diff, man patch.

Ключ Что делает Пример
-u --unified Унифицированный формат с контекстом — читаемый и пригодный для patch. diff -u a b
-r --recursive Сравнить каталоги рекурсивно. diff -r dir1 dir2
-p N Срезать N ведущих компонентов пути (git-патчи обычно -p1). patch -p1 < change.patch
--dry-run Проверить, применится ли патч, не меняя файлы. patch --dry-run -p1 < change.patch
-q --brief Только сказать, отличаются ли файлы, без самих различий. diff -qr dir1 dir2
-w --ignore-all-space Игнорировать различия в пробелах. diff -w a b
-R --reverse Откатить уже применённый патч. опасно patch -R < change.patch
-i --ignore-case Сравнивать без учёта регистра. diff -i a b
-B --ignore-blank-lines Игнорировать добавленные и удалённые пустые строки. diff -B a b

Ничего не найдено. Попробуй запрос короче.

Рецепты

2

Команды

bash
diff -u a b                       # unified diff (читаемо, для патчей)
diff -r dir1 dir2                 # рекурсивно по каталогам
diff -qr dir1 dir2                # только какие файлы отличаются (быстро)
diff --color=auto -u a b          # с цветом
diff -w a b                       # игнорировать пробелы ; -i регистр ; -B пустые строки
diff <(cmd1) <(cmd2)              # сравнить ВЫВОД двух команд (process substitution)
diff <(sort a) <(sort b)          # сравнить без учёта порядка строк

# сделать и применить патч
diff -u orig.conf new.conf > change.patch
patch orig.conf < change.patch    # применить
patch -p1 < change.patch          # из git-патча (срезать 1 уровень пути)
patch --dry-run -p1 < change.patch  # проверить без записи
patch -R < change.patch           # откатить (reverse)
vimdiff a b                       # интерактивное сравнение бок о бок

Примеры

bash
# свои отличия от пакетного дефолта
diff -u /etc/svc/conf.dpkg-dist /etc/svc/conf

# что изменится перед применением (git-style)
git diff > my.patch ; patch --dry-run -p1 < my.patch

# три файла (общий предок + две версии)
diff3 mine.txt base.txt theirs.txt

# подсветка различий по словам, а не строкам
wdiff old.txt new.txt | colordiff

Неполадки

4

patch: Hunk FAILED / .rej файлы

Контекст в целевом файле уже изменился. Смотри *.rej (отклонённые куски), применяй вручную или возьми свежий патч. patch --dry-run проверит без записи.

Не знаю, какой -p уровень

git-патчи обычно patch -p1 (срезает a/, b/). Если пути не совпали — пробуй -p0/-p1. patch спросит имя файла, если не нашёл сам.

Слишком шумный diff (пробелы/CRLF/регистр)

diff -w (игнор пробелов), -i (регистр), -B (пустые). CRLF — приведи концы строк (sed -i 's/\r$//', см. sed-awk).

Сравнить вывод команд, а не файлы

diff <(cmd1) <(cmd2) — process substitution (bash). Удобно: diff <(ssh h1 'rpm -qa'|sort) <(ssh h2 'rpm -qa'|sort).

См. также

  • files-basics — Навигация и файлы — ls, cd, cp, mv, rm, cat, less, head, tail, копипаст в терминале.
  • git — Базовый рабочий цикл, ветки, откат, разрешение конфликтов — минимум для работы.
  • sed-awk — Потоковое редактирование (sed) и обработка по столбцам (awk).
Загрузка…