Я немного поработал с dulwich , чистой реализацией Python для Git. То, что я собираюсь здесь сказать, отражает мой опыт реализации git Дульвича, а не канонического источника git, и поэтому могут быть различия.
Git удивительно прост - я имею в виду, настолько просто, что это сбивает с толку! Название действительно соответствует его дизайну, который очень умный из-за своей глупости.
Когда вы что-либо фиксируете, git берет то, что находится в индексе (промежуточная область), и создает дайджест-элементы SHA, поэтому каждый файл получает SHAed, а файлы в каждом каталоге - SHAed как объекты BLOB-объектов, и, конечно, структура каталога становится SHAed как дерево. объекты, и все, что связано в коммит-объект, который также имеет SHA. Git просто запускает их прямо в файловую систему в .git / objects, когда обрабатывает коммит. Если ему удастся запустить их всех там, он просто записывает SHA самого последнего объекта коммита в .git / refs /head /.
Время от времени коммит может проваливаться на полпути. Если что-то не удается записать в .git / objects, git не очищает в это время . Это потому, что обычно вы решаете проблему и повторяете коммит - в этом случае git будет перезапущен именно с того места, где он был ранее остановлен, то есть на полпути через коммит.
Вот где вступает git gc. Он просто анализирует все объекты в .git / objects, отмечая все те, на которые так или иначе ссылается HEAD или BRANCH. Все остальное, очевидно, осиротело и не имеет ничего общего с чем-то «важным», поэтому его можно удалить. Вот почему, если вы выполняете ветку, выполняете некоторую работу с этой веткой, но затем отказываетесь от этой ветки и удаляете любую ссылку на нее из вашего git-репо, периодический git gc, который выполняется, полностью очистит вашу ветку. Это может удивить некоторых старых пользователей VCS, например, CVS никогда ничего не забывал, кроме случаев, когда он падал или сам себя портил (что было часто).
git repack (на самом деле git-pack-objects) полностью отличается от git gc (как, например, отдельная команда и операция, хотя git gc может вызывать git repack). Как я упоминал ранее, git просто запускает все в свой собственный файл SHAed. Это делает их сжатыми перед тем, как перейти на диск, но, очевидно, это не экономит место в долгосрочной перспективе. Итак, что делает git-pack-objects, так это проверяет серию объектов SHA в любом месте, где данные реплицируются между ревизиями. Неважно, что это за объект SHA - все считаются равными для упаковки. Затем он генерирует двоичные дельты, где это имеет смысл, и сохраняет весь лот в виде файла .pack в .git / objects / pack, удаляя все упакованные объекты из обычной структуры каталогов.
Обратите внимание, что обычно git-pack-objects создает новый .pack-файл, а не заменяет существующие .pack-файлы, если размер последнего загружаемого файла составляет менее 1 МБ. Таким образом, со временем вы увидите несколько файлов .pack в .git / objects / pack. Действительно, когда вы выполняете git fetch, вы просто просите удаленное хранилище упаковать все распакованные вещи и отправить файлы .pack, которых нет у извлекающего репо, в извлекающее хранилище. git repack просто вызывает git-pack-objects, но велит объединять файлы .pack так, как считает нужным. Это подразумевает распаковку всего, что изменилось, регенерацию двоичных дельт и повторное сжатие.
Итак, чтобы ответить на ваш вопрос, итоговая строка относится к общему количеству объектов в git-репо. Первое дельта-число - это число тех полных объектов, которые являются бинарными дельта-объектами, то есть сколько объектов Git решило иметь сильное сходство с другими объектами и может быть сохранено как двоичная дельта. Повторно используемое число указывает, сколько объектов из сжатого источника (то есть файла пакета) используется без повторного сжатия, чтобы включить более свежие изменения. Это может произойти, когда у вас есть несколько пакетных файлов, но если более свежий объект SHA ссылается на элемент в старом пакетном файле в качестве своей базы, то применяет к нему дельты, чтобы сделать его современным. Это позволяет git использовать ранее сжатые старые версии данных без необходимости повторного сжатия, чтобы включить более свежие дополнения. Обратите внимание, что git может добавить файл существующего пакета без перезаписи всего файла пакета.
Вообще говоря, большое количество повторно используемых указывает, что некоторое пространство может быть возвращено с полным перепаковыванием (то есть git repack -a), которое всегда будет возвращать повторно использованное в ноль. Тем не менее, обычно git молча позаботится обо всем этом для вас. Кроме того, выполнение полных перепаковок может привести к тому, что некоторые git-выборки будут перезапущены с нуля, поскольку пакеты отличаются - это зависит от настроек сервера (разрешение на создание пользовательских пакетов для каждого клиента обходится дорого на ЦП сервера, поэтому некоторые основные сайты GIT отключают его).
Надеюсь, это ответит на ваш вопрос. На самом деле с git все так просто, что вы удивлены, что вначале все работает, а затем, когда вы оборачиваете его вокруг, вы серьезно поражаетесь. Только действительно гениальные программисты могут написать что-то настолько простое, но работает так хорошо, потому что они видят простоту, а большинство программистов видят только сложность.
Найл