Ответ 1
Я думаю, что diff algo, используемый для файлов pack, был связан с одним из дельта-кодировок: сначала (2005) xdelta, а затем libXDiff.
Но затем, как подробно описано ниже, он переключился на пользовательскую реализацию.
Во всяком случае, как упоминалось здесь:
Git делает deltification только в packfiles.
Но когда вы нажимаете SSH, git генерирует пакетный файл с фиксацией другой стороны, а эти пакеты - тонкие пакеты, поэтому у них также есть дельта... но удаленная сторона добавляет базы к тем тонким пакетам, что делает их автономный.
(примечание: создание многих packfiles или получение информации в огромном пакете является дорогостоящим, и объясните, почему git не справляется с огромными файлами или огромным репо.
См. Больше в " git с большими файлами ")
Эта тема также напоминает нам:
Фактически packfiles и deltification (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 <[email protected]>, (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 недействителен.
Дефицированное представление
Концептуально существует только четыре типа объектов: commit, tree, tag и blob.
Однако для экономии места объект может быть сохранен как "дельта" другого "базового" объекта.
Этим представлениям присваиваются новые типы-delta и ref-delta, которые действительны только в файле пакета.В обоих случаях
ofs-delta
иref-delta
хранится "дельта", которая применяется к другому объекту (называемому "базовым объектом") для восстановления объекта.
Разница между ними,
- ref-delta напрямую кодирует 20-байтовое имя базового объекта.
- Если базовый объект находится в одном пакете, by-delta вместо этого кодирует смещение базового объекта в пакете.
Базовый объект также может быть делит, если он находится в одном пакете.
Ref-delta также может ссылаться на объект вне упаковки (т.е. Так называемый "тонкий пакет"). Однако при хранении на диске пакет должен быть автономным, чтобы избежать циклической зависимости.Дельта-данные представляют собой последовательность инструкций по восстановлению объекта из базового объекта.
Если базовый объект делит, он сначала должен быть преобразован в каноническую форму. Каждая команда добавляет все больше данных к целевому объекту до его завершения.
До сих пор есть две поддерживаемые инструкции:
- один для копирования диапазона байтов из исходного объекта и
- один для вставки новых данных, встроенных в собственно инструкцию.
Каждая команда имеет переменную длину. Тип инструкции определяется седьмым битом первого октета. Следующие диаграммы следуют за соглашением в RFC 1951 (формат сжатых данных с дефлятом).