== Кратко == diff - утилита, показывающая разницу между двумя файлами. patch - утилита позволяющая применить изменения (патч) к файлу более старой версии, чтобы получить из него файл текущей версии. Конечно, это очень примитивное и краткое описание - на самом деле обе утилиты обладают гораздо большими возможностями. Утилиты относятся к классам "must have" и "must understand" для всех, кто программирует или разбирается в кодах. Причем не обязательно в Linux - в других системах есть порты или аналоги. Вообще в среде разработчиков Linux/Unix принято не передавать друг другу огромные исправления и обновления программ - а присылать только патчи. Для примера возьмем два некоторых файла с кодом - oldfile1 и newfile, где newfile - является улучшенной версией oldfile. // oldfile $file = "somefile.txt"; if ($f = fopen($file,'r')) { while(!eof($f)) { $s = fgets($f); print "$s\n"; } } // newfile $file = "/file.txt"; if ($f = fopen($file,'r')) { while(!feof($f)) { $s = fgets($f); echo "$s\n"; } fclose($f); } == diff == diff может создавать два различных вида патчей - обычный и контекстный. Контекстный - более наглядный, более большой по размеру, и в большинстве случаев лучше, чем обычный, поскольку привязан к контексту (не зря ведь так называется!). В GNU есть еще унифицированный контекстный патч - более компактный, но чуть менее переносимый. $ diff oldfile newfile > patch или $ diff -c oldfile newfile > contextpatch или $ diff -u oldfile newfile > upatch Обычный патчи patch выглядит так: 1c1 < // oldfile --- > // newfile 3c3 < $file = "somefile.txt"; --- > $file = "/file.txt"; 6c6 < while(!eof($f)) { --- > while(!feof($f)) { 8c8 < print "$s\n"; --- > echo "$s\n"; 9a10 > fclose($f); А контекстный: *** oldfile 2011-11-02 12:13:10.192499384 +0400 --- newfile 2011-11-02 12:13:04.484418321 +0400 *************** *** 1,11 **** ! // oldfile ! $file = "somefile.txt"; if ($f = fopen($file,'r')) { ! while(!eof($f)) { $s = fgets($f); ! print "$s\n"; } } --- 1,12 ---- ! // newfile ! $file = "/file.txt"; if ($f = fopen($file,'r')) { ! while(!feof($f)) { $s = fgets($f); ! echo "$s\n"; } + fclose($f); } == patch == Чтобы применить полученные патчи достаточно воспользоваться командой $ patch oldfile -i patchfile -o file Где patchfile - это имя патч-файла (у нас patch, upatch или contextpath). После выполнения данной команды file и newfile - должны быть полностью эквивалентны. == Патч проекта == Патч можно получить не только для отдельного файла, но и для целого дерева каталогов $ diff ./olddir/ ./newdir/ > bigpatch или $ dirr -r ./olddir/ ./newdir/ > rec_bigpatch Полученные изменения применяются командой patch с ключом -p0 $ patch -p0 < bigpatch или $ patch -p0 -i bigpatch Если внутри нового проекта есть файлы, которых нет в старом, т.е. изменилось не только содержимое файлов но и их количество, то нужно добавлять специальные ключи и для diff и для patch: $ diff -r -N ./olddir/ ./newdir/ > diff_patch $ patch -p0 -E < diff_patch == Откат патча == Патч можно откатить назад, если он применился, но не помог решить проблему. $ patch -p0 -R -i bigpatch И напоследок. Перед тем, как применять патч, желательно убедиться, что он подходит и отрабатывает нормально: $ patch -p0 --dry-run < patch Заодно можно сделать бекап, указав для patch ключ -b. Если всё же ошибка произошла, то patch создаст файлы .orig, .rej - по которым можно восстановить исходники и понять причину сбоя. Это, однако, уже совсем не быстро - гораздо проще забекапить проект до применения патча. Читайте маны - там еще много всяких возможностей.
Linux/Windows Справочник v0.05 © 2007-2024 Igor Salnikov aka SunDoctor