Сравнение внешних обработок: распаковка, diff и Git

· 9 мин

Содержание

Положить рядом два файла .epf и натравить на них текстовый diff — не сработает: внешняя обработка это двоичный контейнер, а не текст. Чтобы сравнить две версии, обработку сначала распаковывают в исходники (модули плюс XML форм и реквизитов), а уже их сравнивают любым привычным инструментом — WinMerge, KDiff3, VS Code или git diff.

Самый надёжный способ распаковки в 1С 8.3 — штатная команда конфигуратора DumpExternalDataProcessorOrReportToFiles: платформа сама выгружает .epf в набор XML-файлов, без сторонних утилит. Ниже — весь маршрут: как достать исходники, чем их сравнить, как хранить историю в Git и как перенести найденные отличия обратно в рабочую обработку.

Почему двоичный .epf не сравнивается напрямую

Внешняя обработка (.epf) и внешний отчёт (.erf) — это контейнеры в закрытом двоичном формате. Внутри лежат:

  • 🧩 модуль объекта, модули форм, модули команд;
  • 📐 формы (в собственном внутреннем представлении, тоже не текст);
  • 🗂 макеты, реквизиты, табличные части, картинки.

Открыть такой файл в «Блокноте» и увидеть код нельзя. Поэтому все методы сравнения сводятся к одной идее: превратить обработку в текст, а потом сравнить тексты. Отличаются они тем, чем распаковывать и чем сравнивать.

Коротко по выбору инструмента:

Что у вас за задача — и чем сравнивать?

Как достать исходный код обработки

Способ 1. Штатная выгрузка в XML командой конфигуратора

Начиная с платформы 8.3.10 конфигуратор умеет выгружать внешнюю обработку в дерево XML-файлов из командной строки. Это основной способ — он не требует сторонних программ и даёт формат, который корректно читают и diff-инструменты, и Git.

Команда выгрузки:

"C:\Program Files\1cv8\8.3.XX.XXXX\bin\1cv8.exe" DESIGNER ^
  /DumpExternalDataProcessorOrReportToFiles "C:\src\obrabotka_v1" "C:\epf\obrabotka_v1.epf"

Первый путь — каталог, куда лягут исходники, второй — сам файл обработки. Для внешнего отчёта (.erf) команда та же. После выгрузки в каталоге появятся XML-файлы метаданных, текстовые модули (.bsl/.txt) и описания форм.

Выгрузите так обе версии — в разные каталоги (obrabotka_v1 и obrabotka_v2), и дальше сравнивайте каталоги целиком.

У команды есть ключ формата: иерархический (-Format Hierarchical, по умолчанию в свежих релизах) раскладывает объекты по подпапкам, плоский (Plain) кладёт всё рядом. Для обеих версий используйте один и тот же формат, иначе diff покажет отличия там, где их нет.

Способ 2. Утилита-распаковщик (v8unpack и аналоги)

Если платформа старше 8.3.10 или нужно быстро вскрыть контейнер, подойдут сторонние распаковщики — например v8unpack. Они разбирают двоичный контейнер на внутренние потоки: тексты модулей достаются сразу, а формы остаются в промежуточном виде и требуют доработки.

Для командной работы чаще берут связку на базе precommit1c (ставится через oscript): она распаковывает .epf в удобное для Git дерево и попутно конвертирует формы в читаемый вид.

Распаковщики работают с форматом контейнера, а не с логикой 1С. После сборки обратно всегда открывайте обработку в конфигуратере и проверяйте, что она запускается, — двоичную обработку, собранную сторонним инструментом, обязательно тестируйте перед передачей в рабочую базу.

Способ 3. Скопировать текст модуля из конфигуратора

Для маленькой обработки, где важен только код, распаковка избыточна. Откройте .epf в конфигураторе (Файл → Открыть), откройте нужный модуль, выделите весь текст (Ctrl+A), скопируйте и вставьте в текстовый файл. Повторите для второй версии — и сравните два файла.

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

Чем сравнивать распакованные исходники

Когда обе версии лежат в виде текста и XML, годится любой файловый или папочный diff. Разница — в удобстве просмотра и слияния.

ИнструментДля чего удобенСлияние
WinMergeСравнение двух каталогов целиком, бесплатноДа, по строкам
KDiff3Трёхсторонний diff (базовая + две правки)Да, 3-way
Beyond CompareАккуратный просмотр, правила фильтрацииДа
VS CodeБыстрый diff двух файлов, подсветка bslВручную
git diffИстория версий, сравнение коммитовЧерез Git

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

  1. Выгрузите обе версии в XML (способ 1).
  2. Откройте в WinMerge режим сравнения папок: слева каталог v1, справа v2.
  3. WinMerge подсветит, какие файлы различаются. Изменённые модули открываются построчным diff прямо внутри.
  4. XML форм и реквизитов читаются как обычный текст — видно добавленный реквизит, изменённый тип, новый элемент формы.

Задайте в diff-инструменте фильтр по кодировке и переводам строк. XML от конфигуратора обычно в UTF-8; если одну версию кто-то пересохранил в другой кодировке, инструмент покажет «все строки изменились». Это ложная тревога — приведите кодировки к одной.

Когда версий три — исходная база и две независимые правки от разных разработчиков — берите трёхстороннее сравнение (KDiff3, Beyond Compare). Оно показывает не просто «было/стало», а кто и что изменил относительно общего предка, и помогает увидеть конфликтующие правки: обе версии трогали одну и ту же процедуру. Для двух версий хватает обычного двустороннего diff.

Если истории нет и вы сравниваете две случайно оказавшиеся рядом обработки, сначала поймите, какая из них новее: ориентируйтесь на дату файла, номер версии в модуле (если автор его ведёт) или на то, в какой базе обработка реально используется. Сравнивать вслепую «слева направо», не зная направления правки, — верный способ перенести изменения не в ту сторону.

Хранение и сравнение обработок через Git

Если обработку правят регулярно, разовые сверки превращаются в рутину. Решение — держать в Git не сам .epf, а его распакованные исходники.

Схема работы:

  1. Создаёте репозиторий, в нём каталог под обработку.
  2. При каждом изменении выгружаете .epf в этот каталог командой DumpExternalDataProcessorOrReportToFiles (или через precommit1c).
  3. Делаете коммит. Git сам хранит историю и показывает, что поменялось между любыми двумя версиями.

Тогда сравнение версий — это обычные команды:

# что изменилось между двумя коммитами
git diff HEAD~1 HEAD

# история правок одного модуля
git log -p -- src/Обработка/Ext/ObjectModule.bsl

Плюс к сравнению вы получаете авторство правок (git blame), ветки под разные доработки и возможность откатиться к рабочей версии.

Настройка Git-хранилища обработки
Выполнено: 0 / 5

Главная ошибка — коммитить в Git сам .epf. Двоичный файл Git хранит как «чёрный ящик»: diff по нему пустой, слияние невозможно. В репозиторий кладите распакованный текст, а готовый .epf собирайте из него.

Чтобы случайно не затащить двоичный файл в историю, добавьте *.epf и *.erf в .gitignore, а в .gitattributes пометьте текстовые исходники как текст — тогда Git не станет считать их бинарными из-за нестандартных символов:

# .gitignore
*.epf
*.erf

# .gitattributes
*.bsl text
*.txt text

Первый коммит сделайте от заведомо рабочей версии обработки — это станет точкой отсчёта, с которой вы будете сравнивать все последующие правки.

Что меняется в формах и метаданных

Код в модулях читается легко. Сложнее увидеть отличия в формах и структуре метаданных — реквизитах, табличных частях, параметрах.

При выгрузке в XML (способ 1) форма превращается в XML-описание: элементы, их свойства, привязки к реквизитам. В diff это читается напрямую — видно добавленное поле, изменённый заголовок, новую команду на форме.

На что смотреть при сравнении метаданных:

  • ➕ новые или удалённые реквизиты и табличные части;
  • 🔤 смена типа реквизита (частый источник ошибок при обмене данными);
  • 🧷 изменённые параметры и реквизиты форм;
  • 🖼 добавленные или переименованные макеты.

Отдельный удобный путь — 1С:EDT. Среда разработки хранит обработку как структурированный проект и показывает формы и метаданные не сырым XML, а в своём редакторе. Импортируйте в EDT обе версии (или две ветки одного проекта) и сравните средствами среды — для форм это нагляднее, чем читать XML руками.

Автоматизация: пакетная распаковка и проверка

Когда обработок много, выгрузку автоматизируют. Команды конфигуратора запускаются в пакетном режиме, поэтому их легко завернуть в скрипт или в CI.

Минимальный bat-скрипт, который выгружает обработку перед коммитом:

@echo off
set V8="C:\Program Files\1cv8\8.3.XX.XXXX\bin\1cv8.exe"
set EPF="C:\epf\obrabotka.epf"
set SRC="C:\repo\obrabotka"

%V8% DESIGNER /DumpExternalDataProcessorOrReportToFiles %SRC% %EPF% /Out "C:\logs\dump.log"

Что обычно автоматизируют:

  • 🔁 выгрузку .epf в исходники по расписанию или при коммите (pre-commit hook);
  • 🧪 проверку синтаксиса собранной обработки в CI (GitLab CI, Jenkins);
  • 📦 сборку готового .epf из исходников командой LoadExternalDataProcessorOrReportFromFiles на стороне сборки.

Для сценариев на oscript берут precommit1c — он закрывает и распаковку, и обратную сборку, и интеграцию с Git-хуками.

Ключ /Out пишет лог в файл — в пакетном режиме это единственный способ увидеть, почему выгрузка упала. Проверяйте код возврата процесса: ненулевой означает, что обработку выгрузить не удалось.

Как прочитать diff и перенести изменения обратно

Сравнение — половина дела. Дальше найденные отличия нужно осмыслить и, если надо, перенести в рабочую версию.

Читая diff, разделяйте правки по смыслу:

  1. Логика — изменения в тексте модулей. Самое важное: именно здесь меняется поведение обработки.
  2. Интерфейс — правки форм: новые поля, кнопки, команды.
  3. Структура — реквизиты, типы, табличные части. Влияют на совместимость с базой и обменами.

Перенести изменения можно двумя путями.

Через исходники (рекомендуемый). Слейте нужные правки на уровне текста/XML — в KDiff3 или в Git (merge), затем соберите обработку обратно командой:

"...\1cv8.exe" DESIGNER ^
  /LoadExternalDataProcessorOrReportFromFiles "C:\repo\obrabotka" "C:\epf\obrabotka_new.epf"

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

Вручную в конфигураторе. Если правок немного, откройте обе обработки и перенесите изменения руками: скопируйте процедуру, добавьте реквизит, повторите настройку формы. Надёжно для точечных правок, но легко пропустить мелочь — поэтому финальную версию всё равно полезно ещё раз сравнить с исходником.

Готовые .epf между собой не сливаются: двоичные контейнеры нельзя объединить как текст. Любое слияние делается на уровне распакованных исходников, а .epf затем пересобирается. Перед заменой обработки в рабочей базе сохраните прежнюю версию файла — откат должен быть под рукой.

Частые вопросы

Можно ли сравнить две обработки прямо в конфигураторе, без распаковки?
Встроенного сравнения двух .epf «из коробки» в конфигураторе нет — механизм «Сравнить, объединить» рассчитан на конфигурации. Для обработок сравнивают либо тексты модулей вручную, либо распакованные в XML исходники во внешнем diff.
Чем отличается выгрузка в XML от утилиты-распаковщика?
Команда конфигуратора DumpExternalDataProcessorOrReportToFiles — штатная, даёт корректный XML и умеет собирать обработку обратно. Сторонние распаковщики вскрывают двоичный контейнер и полезны на старых платформах или для быстрого взгляда на один модуль.
Как сравнить внешние отчёты (.erf)?
Точно так же, как обработки: те же команды конфигуратора, те же diff-инструменты. Формат контейнера у .epf и .erf одинаковый по принципу, поэтому маршрут не меняется.
Платформа старше 8.3.10 — что делать?
Команды выгрузки в XML там ещё нет. Используйте распаковщик (v8unpack, precommit1c) либо копируйте тексты модулей из конфигуратора вручную. Как только обновитесь — переходите на штатную выгрузку.
Почему diff показывает отличия, хотя код не менялся?
Чаще всего виноваты разные кодировки файлов или формат переводов строк, реже — разный формат выгрузки (иерархический против плоского). Приведите обе версии к одной кодировке и одному формату — лишние отличия исчезнут.