Как патчить Битрикс

Так как патчить в некоторых случаях ядро - единственный способ достичь цели, а при обновлении движка все патчи слетают, есть необходимость «вклеивания» патчей обратно. Для этого есть два способа.

Патч "на лету"

Делается проверка на наличие нужных изменений (патча) в системных файлах, и если таких изменений нет (было обновление), тогда патчится заново. Пример, как можно добавить патч в файл admin_lib.php с помощью выполнения кода в bitrix/php_interface/admin_header.php:

bitrix/php_interface/admin_header.php
$file = $_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/interface/admin_lib.php";
 
$sAdminLibCode = file_get_contents($file);
 
if(strpos($sAdminLibCode, "excel_mode_export_all_pages") === false) {
  $pattern = '/(function GetNavSize\\(.*?\\)\s+{)/is';
  $replacement = '${1}
  if (htmlspecialchars($_REQUEST["mode"]) == "excel") return 10000000; // excel_mode_export_all_pages
  ';
 
  if(preg_match($pattern, $sAdminLibCode, $matches)) {
    $sAdminLibCode = preg_replace($pattern, $replacement, $sAdminLibCode);
    file_put_contents($file, $sAdminLibCode);
  }
}

Недостаток - может не сработать при отсутствии совпадения в регулярке, а также если PHP запрещено писать в этот каталог.

Сохранение патча в файл

Алгоритм сохранения патча в файл

  1. Допустим, необходимо патчить ядро, по-другому проблему не решить. Вносим изменения в ядро
  2. Коммитим в гите
  3. Делаем патч через git или diff:
    1. первый способ - последний коммит: git format-patch --stdout -1 HEAD > patches/my-patch.patch
    2. второй способ - между двумя коммитами: git diff 0953be42c0b1 d5979e73b65 > patches/my-patch.patch
    3. третий способ - между двумя файлами - через diff
  4. Патчи находятся также под гитом, их можно либо также включить в прошлый коммит (через --amend, например), либо закоммитить в следующем.

Вклеивание патчей из файла обратно

После обновления движка патчи возможно автоматически вклеить обратно, но надо этот процесс контролировать просмотром ошибок, а также на уровне работоспособности. Вклейка идет примерно так:

patch -i patches/my-patch.patch -p0 -l

Либо через git:

# проверяем патч
git apply --check patches/my-patch.patch
# применяем патч
git apply patches/my-patch.patch

См. также как патчить ядро Джумлы