Что означают числа в строке "Итого" вывода git gc/git repack?
Когда я бегу git gc
или же git repack
поверх моего Git-репозитория он выводит строку "Total", как только это будет сделано. Что означают эти цифры?
Пара примеров из довольно маленького репозитория:
$ git gc
...
Total 576 (delta 315), reused 576 (delta 315)
$ git repack -afd --depth=250 --window=250
...
Total 576 (delta 334), reused 242 (delta 0)
И один из гораздо большего хранилища:
$ git gc
...
Total 347629 (delta 289610), reused 342219 (delta 285060)
...
Я могу догадаться, что это первое "общее" число: количество объектов Git (так что коммитов, деревьев и файлов) в хранилище. Что на самом деле означают все остальные?
Я уже посмотрел на git-gc(1)
а также git-repack(1)
man-страниц, и просматривал их "Смотрите также", и мои попытки поиска в Google дали только не относящиеся к делу результаты.
1 ответ
Я немного поработал с 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 это так просто, что вы удивлены, что вначале все работает, а затем, когда вы оборачиваете его вокруг, вы серьезно поражаетесь. Только действительно гениальные программисты могут написать что-то настолько простое, но работает так хорошо, потому что они видят простоту там, где большинство программистов видят только сложность.
Найл