Как применить diff-файл

Когда мы исправляем баг, это исправление появляется в одной из будущих версий CS-Cart. Новая версия может выйти нескоро, а избавиться от бага нужно побыстрее. Для этого мы даём файлы в формате unified diff.

В файле формата unified diff описано, какие строки из исходного файла нужно убрать, а какие добавить, чтобы получить обновлённый файл. Эти изменения можно внести вручную или воспользоваться командной строкой.

Применение diff-файла в командной строке

Примечание

Эта инструкция рассчитана на случаи, когда сервер работает на UNIX-подобной операционной системе, а у вас есть прямой доступ к серверу или доступ по SSH.

  1. Сделайте полную резервную копию файлов и базы данных вашей установки.

  2. Скопируйте diff-файлы в корневую директорию вашей установки.

  3. Откройте командную строку; если вы работаете с сервером дистанционно, подключитесь к нему по SSH.

  4. В командной строке перейдите в корневую директорию вашей установки c помощью команды:

    cd /path/to/cscart/root/directory
    

    Замените /path/to/cscart/root/directory на путь к корневой директории.

  5. Для каждого diff-файла выполните следующую команду:

    patch -p1 < example.diff
    

    Вместо example.diff указывайте названия diff-файлов.

Применение diff-файла вручную

Если нет возможности воспользоваться консольной командой, можно внести исправления в файл вручную, ориентируясь по diff-файлу. Например, содержимое diff-файла может быть таким:

diff --git a/app/addons/my_changes/addon.xml b/app/addons/my_changes/addon.xml
index efa480f..00981ea 100755
--- a/app/addons/my_changes/addon.xml
+++ b/app/addons/my_changes/addon.xml
@@ -1,9 +1,9 @@
 <?xml version="1.0"?>
 <addon scheme="3.0">
 <id>my_changes</id>
-    <version>1.0</version>
-    <priority>4294967294</priority>
+    <version>2.0</version>
+    <priority>100500</priority>
     <position>0</position>
-    <auto_install>MULTIVENDOR,ULTIMATE</auto_install>
     <default_language>en</default_language>
+    <status>active</status>
 </addon>

Сначала определим, в какой файл нужно будет внести изменения. В нашем случае это файл addon.xml из папки app/addons/my_changes, расположенной в корневой директории CS-Cart. Узнать это можно по следующим строкам diff-файла:

--- a/app/addons/my_changes/addon.xml
+++ b/app/addons/my_changes/addon.xml

Вообще, минусы в diff-файле означают, что строка относится к оригинальному файлу, а плюсы — что строка относится к исправленному файлу.

В одном файле unified diff отображается содержимое и оригинального, и изменённого файла. Изменяемый фрагмент в diff-файле описан так:

 <?xml version="1.0"?>
 <addon scheme="3.0">
     <id>my_changes</id>
-    <version>1.0</version>
-    <priority>4294967294</priority>
+    <version>2.0</version>
+    <priority>100500</priority>
     <position>0</position>
-    <auto_install>MULTIVENDOR,ULTIMATE</auto_install>
     <default_language>en</default_language>
+    <status>active</status>
 </addon>

Основные правила просты:

  • Если строка начинается с -, её нужно удалить из редактируемого файла.
  • Если строка начинается с +, её нужно добавить в редактируемый файл (естественно, без + в начале строки).
  • Если строка начинается с пробела, то ничего делать не нужно (так как строка не менялась).

Получается, файл до изменений выглядел так:

<?xml version="1.0"?>
<addon scheme="3.0">
   <id>my_changes</id>
   <version>1.0</version>
   <priority>4294967294</priority>
   <position>0</position>
   <auto_install>MULTIVENDOR,ULTIMATE</auto_install>
   <default_language>en</default_language>
</addon>

После внесения изменений он будет выглядеть так:

<?xml version="1.0"?>
<addon scheme="3.0">
    <id>my_changes</id>
    <version>2.0</version>
    <priority>100500</priority>
    <position>0</position>
    <default_language>en</default_language>
    <status>active</status>
</addon>

Файл в приведённом примере небольшой, поэтому он уместился в diff-файл целиком. Но бывают случаи, когда нужно внести изменения в нескольких разных частях большого файла. Тогда в формате unified diff приводится только отдельные фрагменты файла; а строки вида @@ -l,s +l,s @@ указывают, в каком месте файла находится каждый фрагмент:

  • Вместо l будет число, указывающее номер строки, в которой начинается фрагмент.
  • Вместо s будет число, которое указывает, сколько строк из файла приведено в этом фрагменте.

В нашем diff-файле запись такая: @@ -1,9 +1,9 @@:

  • -1,9 означает, что ниже приведено 9 строк из исходного файла, начиная с первой строки. Строки с + не входят в это число, так как их нет в исходном файле.
  • +1,9 означает, что ниже приведено 9 строк из нового файла, начиная с первой строки. Строки с - не входят в это число, так как их нет в исправленном файле.

Число 9 одинаково для обоих файлов, так как мы в одном фрагменте удалили и добавили одинаковое количество строк, то есть итоговое количество строк во фрагменте не изменилось.

Иногда после @@ -l,s +l,s @@ строка продолжается, и там приведён фрагмент кода, который находится где-то выше строки с номером l. Это заголовок раздела, и его можно смело игнорировать.