Понимание git gc --auto

Я экспериментирую с довольно агрессивным auto gc в Git, в основном для упаковки. В моих репо, если я сделаю git config --list У меня есть настройки

...
gc.auto=250
gc.autopacklimit=30
...

Если я сделаю git count-objects -v я получил

count: 376
size: 1251
in-pack: 2776
packs: 1
size-pack: 2697
prune-packable: 0
garbage: 0

Но git gc --auto не меняет эти цифры, ничего не упаковывается! разве не должны быть упакованы незакрепленные объекты, так как я превышаю предел в 126 gc.auto?

3 ответа

Решение

Один из главных пунктов gc --auto в том, что он должен быть очень быстрым, поэтому другие команды могут часто вызывать его "на всякий случай". Чтобы достичь этого, количество объектов только угадывается. Как git help config говорит под gc.auto:

Когда в хранилище находится примерно больше, чем много свободных объектов […]

Смотря на код (too_many_loose_objects() вbuildin/gc.c) вот что происходит:

  1. Gc.auto делится на 256 и округляется
  2. Папка, содержащая все объекты, которые начинаются с 17 открыт
  3. Проверяется, содержит ли папка больше объектов, чем результат шага 1

Это прекрасно работает, поскольку SHA-1 распределен равномерно, поэтому "все объекты, начинающиеся с X", являются репрезентативными для всего набора. Но, конечно, это работает только для большого количества объектов. Чтобы лениться делать математику, я бы предположил, по крайней мере>3000. С 6700 (значение по умолчанию gc.auto), это должно работать уже достаточно надежно.

Основной вопрос для меня заключается в том, зачем вам нужен такой низкий уровень и важно ли, чтобы он действительно работал на 250 объектах. С настройкой 250, gc будет работать, как только у вас есть 2 свободных объекта, которые начинаются с 17, Вероятность того, что это произойдет, > 80% на 600 предметов и > 90% на 800 предметов.

Обновление: не мог с этим поделать - пришлось делать математику:). Мне было интересно, насколько хорошо эта система оценки будет работать. Вот график результатов. Для любого данного gc.autoнасколько высока вероятность того, что gc начнется, когда есть gc.auto (красный) / gc.auto * 1.1 (зеленый) / gc.auto * 1.2 (оранжевый) / gc.auto * 1.5 (синий) / gc.auto * 2 (фиолетовый) незакрепленные предметы в репо?

График результатов

Обратите внимание, что gc auto быть более надежным в Git 2.12.2 (выпущен в марте 2017 года, два дня назад).

Смотрите коммит a831c06 (10 февраля 2017 г.) Дэвида Тернера ( csusbdt )
Помогает: Джефф Кинг ( peff )
(Объединено Юнио С Хамано - gitster - в коммите d30ec1b, 21 марта 2017 г.)

gc: игнорировать старое gc.log файлы

Сервер может оказаться в состоянии, в котором находится множество свободных объектов, на которые нет ссылок (скажем, потому, что многие пользователи делают много перебазировок и толкают свои перебазированные ветки).
Бег " git gc --auto "в этом состоянии вызовет gc.log файл, который будет создан, предотвращая будущие авто gcs, заставляя файлы пакета накапливаться.
Поскольку многие операции с Git O(n) в количестве файлов пакета это приведет к снижению производительности.

Git никогда не должен входить в состояние, в котором он отказывается от какого-либо обслуживания, просто потому, что в какой-то момент часть обслуживания не достигла прогресса.

Научите Git игнорировать gc.log файлы старше (по умолчанию) одного дня, которые можно настроить с помощью gc.logExpiry переменная конфигурации.
Таким образом, эти файлы пакетов будут очищаться, если необходимо, по крайней мере, один раз в день. И операторы, которые находят потребность в более частых gcs, могут настроить gc.logExpiry чтобы удовлетворить их потребности.


Примечание: начиная с Git 2.17 (Q2 2018), git gc --auto будет работать на каждом git commit тоже.
Смотрите " Список всех команд, вызывающих git gc --auto ".

И есть pre-gc --auto Хук, связанный с этой командой тоже.

Это помогло мне:

      git config --global gc.auto 0

https://git-scm.com/docs/git-gc/2.6.7

Другие вопросы по тегам