Я думаю, что дифференциальный алгоритм, используемый для файлов пакета , был связан с одной из дельта-кодировкой там: первоначально (2005) xdelta , а затем libXDiff .
Но затем, как подробно описано ниже, он перешел к пользовательской реализации.
В любом случае, как указано здесь :
Git выполняет делитирование * только 1017 * в пакетных файлах.
Но когда вы нажимаете через SSH, git генерирует файл с коммитами, а другая сторона не
есть, и эти пакеты являются тонкими пакетами, поэтому они также имеют дельты ... но удаленная сторона затем добавляет базы к этим тонким пакетам, делая их автономными.
(примечание: создание большого количества файлов пакета или извлечение информации из огромного файла пакета дорого и объясняет, почему git плохо обрабатывает огромные файлы или огромное хранилище.
См. Больше в " git с большими файлами ")
Эта тема также напоминает нам:
На самом деле, как я помню и понимаю, на самом деле упаковочные файлы и дельтификации ( LibXDiff, а не xdelta ) изначально были из-за пропускной способности сети (что намного дороже, чем дисковое пространство), и производительность ввода-вывода при использовании одного файла mmapped вместо очень большого количества незакрепленных объектов.
LibXDiff упоминается в этой ветке 2008 .
Однако с тех пор алгоритм эволюционировал, возможно, в пользовательском, как этот поток 2011 иллюстрирует , и как указывает заголовок diff-delta.c
:
Итак, строго говоря, текущий код в Git не имеет никакого сходства с кодом libxdiff вообще.
Однако основной алгоритм обеих реализаций одинаков .
Изучить версию libxdiff, вероятно, проще, чтобы понять, как это работает.
/*
* diff-delta.c: generate a delta between two buffers
*
* This code was greatly inspired by parts of LibXDiff from Davide Libenzi
* http://www.xmailserver.org/xdiff-lib.html
*
* Rewritten for GIT by Nicolas Pitre <nico@fluxnic.net>, (C) 2005-2007
*/
Подробнее о упаковочных файлах Git Book :
Git 2.18 добавляет к дельта-описанию в этом новом разделе документации , который сейчас (Q2 2018) гласит:
Типы объектов
Допустимые типы объектов:
OBJ_COMMIT
(1)
OBJ_TREE
(2)
OBJ_BLOB
(3)
OBJ_TAG
(4)
OBJ_OFS_DELTA
(6)
OBJ_REF_DELTA
(7)
Тип 5 зарезервирован для будущего расширения. Неверный тип 0.
Деликатное представление
Концептуально существует только четыре типа объектов: коммит, дерево, тег и
блоб.
Однако, чтобы сэкономить место, объект может быть сохранен как «дельта»
другой "базовый" объект.
Этим представлениям назначаются новые типы ss-delta и ref-delta, которые действительны только в файле пакета.
И ofs-delta
, и ref-delta
хранят "дельту", которая будет применена к
другой объект (называемый «базовый объект») для реконструкции объекта.
Разница между ними составляет
- ref-delta напрямую кодирует 20-байтовое имя базового объекта.
- Если базовый объект находится в том же пакете, вместо него ofs-delta кодирует смещение базового объекта в пакете.
Базовый объект также можно отделить, если он находится в той же упаковке.
Ref-delta также может относиться к объекту за пределами пакета (т.е.
так называемая «тонкая пачка») . Однако при сохранении на диске пакет должен
быть самодостаточным, чтобы избежать циклической зависимости.
Дельта-данные - это последовательность инструкций для восстановления объекта.
от базового объекта.
Если базовый объект разграничен, он должен быть сначала преобразован в каноническую форму. Каждая инструкция добавляет все больше данных к целевому объекту до тех пор, пока она не будет завершена.
На данный момент есть две поддерживаемые инструкции:
- один для копирования байтового диапазона из исходного объекта и
- один для вставки новых данных, встроенных в саму инструкцию.
Каждая инструкция имеет переменную длину.Тип инструкции определяется седьмым битом первого октета.Следующие схемы соответствуют соглашению в RFC 1951 (формат сжатых данных Deflate).