Перейти к основному содержанию Перейти к навигации Перейти к нижнему колонтитулу
Ограниченное время: Программа Design Partner. План BUSINESS бесплатно на всю жизнь.

rdc repo diff

Выводит git-подобный diff уровня файлов между двумя форками репозиториев с copy-on-write путем сравнения зашифрованных образов на уровне блоков без их расшифровки.

rdc repo diff

rdc repo diff показывает, какие файлы изменились между двумя связанными репозиториями: форком и его родителем, или любыми двумя репозиториями, имеющими общего предка с copy-on-write. Передайте --name <fork> для сравнения форка с родителем, записанным в локальной конфигурации, или добавьте --base <repo> для сравнения с произвольным связанным репозиторием, где --base это базовая (старая) сторона, а --name целевая (новая) сторона. Команда предназначена только для чтения и никогда не расшифровывает образы. Она сравнивает их на уровне блоков на удаленной машине, поэтому стоимость определяется количеством измененных блоков, а не размером репозитория: репозиторий объемом 1 ГБ и репозиторий объемом 100 ГБ с одинаковыми редактированиями обрабатываются за одно и то же время. Если весь репозиторий изменился, количество блоков масштабируется с размером, как и стоимость.

When to use it

Итак: используйте repo diff перед продвижением форка. Агент ИИ разгулялся в форковой копии production-окружения, и вы хотите увидеть ровно какие файлы он трогал перед тем как вливать изменения обратно: repo diff --name <fork> -m <machine> дает вам список файлов за секунды. Буквально секунды. После восстановления при аварийном восстановлении отличите восстановленный форк от снимка, который он должен был воспроизвести, чтобы убедиться, что вернулся ожидаемый набор файлов и ничего больше не отклонилось. Для долгоживущего форка, работающего рядом с родителем неделями, diff показывает накопленное расхождение (редактирование конфига, нарастание логов, миграции схемы) без необходимости монтировать и вручную проходить оба дерева.

Не используйте его между несвязанными репозиториями. Обе стороны должны иметь общего предка с copy-on-write, потому что сравнение работает с общей историей блоков. Это также не инструмент двоичного diff: --content выдает вывод на уровне строк только для текстовых файлов, двоичные файлы выводятся как Binary files differ.

Command reference

Synopsis

rdc repo diff --name <fork> -m <machine>            # diff a fork against its parent
rdc repo diff --name <fork> --base <repo> -m <machine>   # diff against an arbitrary related repo

Options

OptionDescriptionDefault
--name <name>Репозиторий для инспекции (целевая, новая сторона). Обязателен.required
--base <name>Репозиторий для сравнения (базовая, старая сторона). По умолчанию родитель --name, разрешается из локальной конфигурации.parent of --name
(no format flag)Вывод статуса имен: цветная буква A/M/D/R для каждого измененного файла плюс однострочное резюме.on
--name-onlyПо одному измененному пути на строку, без буквы статуса. Удобно для pipe.off
--statВеличина изменения на файл (дельты байтов и блоков) с итоговым подвалом.off
--content <path>Унифицированный текстовый diff одного файла. Только текст; двоичные файлы выводятся как Binary files differ.off
--jsonСтруктурированный вывод для агентов и скриптов.off
--fastПропустить шаг подтверждения хеша содержимого и доверять фильтру блоков. Быстрее, но может перечислить файлы как Modified.off
-m, --machine <name>Целевая машина. Обязательна.required
--debugПодробная диагностика на stderr.off
--skip-router-restartПропустить шаг перезагрузки маршрутизатора.off

Examples

Default name-status against the parent

С одним только --name форк сравнивается с родителем, записанным в локальной конфигурации. Здесь форк test-1gb:fork1 имеет один измененный файл:

$ rdc repo diff --name test-1gb:fork1 -m hostinger
M  hello.txt

1 file changed: 0 added, 1 modified, 0 deleted, 0 renamed

Diffing against an explicit base

Передайте --base для сравнения с произвольным связанным репозиторием. --base это базовая (старая) сторона, --name целевая (новая) сторона:

$ rdc repo diff --name test-1gb:fork1 --base test-1gb:latest -m hostinger
M  hello.txt

1 file changed: 0 added, 1 modified, 0 deleted, 0 renamed

Change magnitude with --stat

--stat добавляет дельту байтов и блоков для каждого файла и итоговый подвал:

$ rdc repo diff --name test-1gb:fork1 --stat -m hostinger
 hello.txt | +8 bytes, 1 block

1 file changed, 4096 bytes touched

Paths only, piped to a tool

--name-only выводит один путь на строку без буквы статуса, готов к передаче другой команде:

$ rdc repo diff --name test-1gb:fork1 --name-only -m hostinger | xargs -I{} echo "review: {}"
review: hello.txt

Line-level diff of one file

--content выдает унифицированный diff одного текстового файла:

$ rdc repo diff --name test-1gb:fork1 --content hello.txt -m hostinger
--- a/hello.txt
+++ b/hello.txt
@@ -1 +1 @@
-the original line of text in the parent
+the original line of text in the parent, now edited

Filtering JSON with jq

--json выводит структурированный конверт на stdout, так что хорошо передается в jq:

$ rdc repo diff --name test-1gb:fork1 --json -m hostinger | jq '.data.entries[] | select(.status=="M")'
{
  "status": "M",
  "path": "/hello.txt",
  "type": "file",
  "old_size": 53,
  "size": 61,
  "bytes_changed": 4096,
  "blocks_changed": 1,
  "inode": 13,
  "content_changed": true,
  "mode_changed": false,
  "uid_changed": false,
  "gid_changed": false
}

Output formats

Name-status (default)

Каждый измененный файл получает букву статуса и его путь. A добавлен, M изменен, D удален, R переименован (с показанным старым путем). За ним следует строка резюме с подсчетом по категориям.

--name-only

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

--stat

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

--content <path>

Стандартный унифицированный diff (---/+++ заголовки, @@ куски) для одного текстового файла. Двоичные файлы выводятся как Binary files differ и не содержат кусков.

--json

Полный структурированный результат. Данные выводятся на stdout; прогресс и диагностика выводятся на stderr, так что JSON хорошо передается в jq или другой парсер даже во время вывода прогресса.

JSON schema

CLI оборачивает результат renet в стандартный конверт (success, command, data, errors, warnings, metrics). Результат diff находится в data с полями в формате snake_case:

{
  "success": true,
  "command": "repo diff",
  "data": {
    "base": "<base-guid>",
    "target": "<target-guid>",
    "added": 0,
    "modified": 1,
    "deleted": 0,
    "renamed": 0,
    "strategy": "shared",
    "fast": false,
    "degraded": false,
    "block_size": 4096,
    "total_bytes_changed": 4096,
    "entries": [
      {
        "status": "M",
        "path": "/hello.txt",
        "type": "file",
        "old_size": 53,
        "size": 61,
        "bytes_changed": 4096,
        "blocks_changed": 1,
        "inode": 13,
        "content_changed": true,
        "mode_changed": false,
        "uid_changed": false,
        "gid_changed": false
      }
    ]
  }
}

Каждый объект в entries[] описывает один измененный путь:

FieldTypeDescription
statusA | M | D | RДобавлен, Изменен, Удален или Переименован.
pathstringПуть на целевой стороне (или базовой стороне при удалении).
old_pathstringПредыдущий путь. Присутствует только при переименованиях.
typefile | dir | symlink | otherТип записи.
old_sizenumberРазмер в байтах на базовой стороне.
sizenumberРазмер в байтах на целевой стороне.
bytes_changednumberРазличающиеся байты, округленные до целых блоков.
blocks_changednumberКоличество измененных блоков.
inodenumberНомер inode, используется для обнаружения переименований.
content_changedbooleanИзменилось ли содержимое файла (не только метаданные).
mode_changedbooleanИзменился ли режим файла. old_mode/new_mode присутствуют, когда true.
uid_changedbooleanИзменился ли владелец. old_uid/new_uid присутствуют, когда true.
gid_changedbooleanИзменилась ли группа. old_gid/new_gid присутствуют, когда true.
old_target / new_targetstringЦели симлинков. Присутствуют для измененных симлинков.

Для полей конверта и правил автоматического обнаружения, которые выводят JSON в не-TTY окружениях, см. JSON Output Reference.

How it works

Репозиторий это файл образа LUKS2 на пуле btrfs, а форк это рефлинк с постоянным временем этого образа. repo diff сравнивает два зашифрованных образа на уровне блоков через FIEMAP, читая только метаданные файловой системы и никогда не расшифровывая ничего. Он сдвигает смещения измененного шифротекста на смещение данных LUKS для получения смещений ext4-устройства, затем преобразует эти смещения обратно в имена файлов через карту экстентов ext4 каждого файла. Финальный проход по идентичности inode обоих монтирований согласовывает результат в записи Added, Modified, Deleted и Renamed. Поскольку работа ограничена количеством измененных блоков, diff независим от размера репозитория, и поскольку он повторно использует живое монтирование на месте, он никогда не нарушает работающий репозиторий. Полный механизм описан в Git diff for encrypted disk images.

Limitations

  • Только связанные форки. Обе стороны должны иметь общего предка с copy-on-write. Нет смысла сравнивать на уровне блоков несвязанные репозитории.
  • Обнаружение переименований основано на inode. Файл считается переименованным, когда один и тот же inode появляется в новом пути. Удаление с последующим воссозданием (новый inode) выводится как запись Deleted плюс Added, а не переименование.
  • --content только для текста. Выдает куски на уровне строк для текстовых файлов. Двоичные файлы выводятся как Binary files differ.
  • --fast может переучитать Modified. Доверяет фильтру блоков и пропускает подтверждение хеша содержимого, поэтому файл, чьи блоки переместились без изменения содержимого, может казаться Modified.
  • Время прохода по экстентам масштабируется с фрагментацией, а не размером. Сильно фрагментированная файловая система имеет больше экстентов для преобразования, что удлиняет проход даже при малом объеме байтов изменений.

See also

  • rdc repo fork. Создайте форк с copy-on-write, который эта команда сравнивает.
  • rdc repo status. Текущее состояние одного репозитория.
  • rdc repo cat. Прочитайте один файл из репозитория.