Навіщо використовувати diff / patch, коли легше просто використовувати cp


19
diff -u file1.txt file2.txt > patchfile

створює файл виправлення, який складається з інструкції для patchперетворення file1.txt таким чином, як файл2.txt

Це не можна зробити cpзамість команди? Я можу уявити, що це корисно, коли файл занадто великий і його потрібно перенести через мережу, де такий підхід може зберегти пропускну здатність. Чи є якийсь інший спосіб використання diff / patch, який був би вигідним в інших сценаріях?

Відповіді:


31

Відмінності можуть бути складнішими, ніж просто порівняння одного файлу з іншим. Можна порівняти цілі ієрархії каталогів. Розглянемо приклад, що я хочу виправити помилку в GCC. Моя зміна додає рядок або два в 4 або 5 файлах і видаляє кілька рядків у тих та інших файлах. Якщо я хочу повідомити про ці зміни комусь, можливо, для включення до GCC я мої варіанти

  • Скопіюйте все початкове дерево
  • Скопіюйте лише ті файли, які були змінені
  • Постачайте лише ті зміни, які я вніс

Копіювати все дерево-джерело не має сенсу, але що стосується двох інших варіантів, які лежать в основі вашого запитання. Тепер подумайте, що ще хтось працював над тим же файлом, що і я, і ми обидва передаємо свої зміни комусь. Як ця особа дізнається, що ми зробили, і якщо зміни сумісні (різні частини файлу) чи конфліктні (однакові рядки файлу)? Він їх відрізнятиме! Різниця може сказати йому, як файли відрізняються один від одного та від немодифікованого вихідного файлу. Якщо diff - це те, що потрібно, просто має більше сенсу просто надіслати diff в першу чергу. Розмінність також може містити зміни з більш ніж одного файлу, тому, хоча я редагував 9 файлів загалом, я можу надати один розрізний файл для опису цих змін.

Відмінності також можна використовувати для надання історії. Що робити, якщо зміна три місяці тому спричинила помилку, яку я виявив лише сьогодні. Якщо я можу звузити, коли помилка була введена, і можу виділити її до певної зміни, я можу використовувати diff для "скасування" або повернення зміни. Це не те, що я міг би так легко зробити, якби тільки копіював файли навколо.

Це все пов'язано з контролем версій джерела, де програми можуть записувати історію файлів як серію, що відрізняється від часу їх створення до сьогодні. Історія diffs надає історію (я можу відтворити файл таким, яким він був у будь-який конкретний день), я можу побачити, хто винен у тому, що щось порушив (у diff є власник), і я можу легко надсилати зміни до вищезазначених проектів, надаючи їм конкретні diff ( можливо, їх цікавить лише одна зміна, коли я зробив багато).

Загалом, так, cpце простіше , ніж diffта patch, але корисність diffі patchбільше , ніж cpв ситуації , коли , яким чином зміна файлів важливо відстежувати.


Насправді, git насправді не зберігає історію файлів як різницю наступних комітів. Для кожного комітету зберігається вміст кожного файлу (див. "Git show -s --pretty = raw" та "git ls-tree HEAD"). Тоді поверх цього шару стільки файлів будуть схожими в різних комісіях, він використовує дельта-компресію для обміну даними з двома файлами (але це не пов'язано з історією).
ysdx

Однак diff є зручним інструментом візуалізації для цієї історії.
ysdx

20

Отримавши виправлення, ви часто можете (тобто, якщо ви не внесли зміни в цілком ті самі рядки), застосувати патч до набору файлів, які ви також змінили.

Патч містить інформацію про старий і новий стан файлів. Якщо ви отримаєте скопійований файл, ви не знаєте, яким був оригінал (старий стан), і ви не можете застосувати відмінності до файлу (або набору файлів), який ви також змінили без великих труднощів. Отже, для наборів вихідних файлів головне питання не є збереженням простору, це інформація, яка є попередньою.

Перш ніж (контекст / уніфікований) відрізняється, це часто робилося з інструкціями для редакторів (вставити рядок після X, видалити рядок Y), але це спрацювало б лише, якщо ви знали, з якого стану починається ця інструкція. Таким чином виникає така ж проблема, як і ваше "рішення" з просто копіюванням.


2
Патч-файли також дозволяють скасувати його та застосувати до декількох файлів одночасно
Gilsham

Насправді, уніфіковані diffs ( diff -u) - це поліпшення, призначене для людей, вони не допомагають стійкості проти конфліктів у звичайному контексті diff ( diff -c), я думаю. Навіть звичайна різниця ( diff) все ще часто працює, не знаючи точно "стан, з якого розпочалася ця інструкція". Тим не менше, це краще, ніж прийнята відповідь, оскільки говорити про те, як файли патчів можуть виправляти декілька вихідних файлів одночасно - це справді червона оселедець.
Селада

@celeda Ви маєте рацію щодо того, що контекст відрізняється, між тим і нормальним різницею є те, де лежить головне відмінність. Без контекстних виправлень набагато складніше застосувати їх у зворотному, якщо взагалі.
Антон

12

Якщо ви використовуєте diff, ви можете побачити, що саме змінилося, тож використання diff / patch - це спосіб запобігти комусь пробурюванню небажаних змін у файлі.


11

Зміни, внесені до файлів, зазвичай набагато менші, ніж файли, що змінюються.

Це означає, що зберігання різниці може заощадити багато місця. Коли diffбуло створено, дисковий простір був дорогим.

Але це також означає, що ви можете повторно застосувати diff до файлу, навіть коли цей файл змінився іншими способами. Патч утиліта зробить це за вас і сказати вам , коли є проблеми.

Це насправді найважливіша причина роботи з різними розробниками програмного забезпечення. Коли зміни внесені (як правило, до декількох файлів), вони можуть бути збережені у вигляді відмінності: результат називається набором змін або виправленням . Якщо все добре, патч - це не просто якась довільна зміна, але він реалізує якусь функціональну зміну - наприклад, виправлення помилки або нову функцію.

Тим часом, може бути внесена інша зміна, можливо, інший розробник, навіть в іншому місці. Якщо зміни не були внесені до одних і тих самих частин одних і тих же файлів, їх можна застосувати самостійно. Тож розробники можуть надсилати один одному свої патчі для тестування. Можна створити цілий набір патчів, що представляє можливі зміни; частина з них у кінцевому рахунку може бути відхилена, решта буде інтегрована в систему.

Тож робота з розрізненням дозволяє одночасно розвиватись. Вам більше не потрібно працювати над однією зміною.

Сучасні системи управління версіями - це продовження такого способу роботи.


1

Словом, це може. Якщо ви переглядаєте кілька відеозаписів Thinkg Big Larry Wall на youtube, він розповідає про те, як розпочалися розробки / виправлення та які проблеми вони вирішили, а по суті, про зменшення розміру для спілкування через Інтернет, зберігаючи патчі гнучкими та зрозумілими для людини. .

Якщо ви перебуваєте в локальній системі і не переймаєтесь жодною з цих речей, тоді cpабо rsyncдобре.


Дякую PSKocik. Не могли б ви поділитися посиланням на це відео?
toddlermenot

Я не згоден з останнім твердженням. Сьогодні справа не в розмірі, а в тому, щоб відстежувати процес розробки, щоб ним було легше керувати.
reinierpost

@reinierpost використовувати git для відстеження мого процесу розвитку. Я не змінюю патч безпосередньо.
PSkocik
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.