Понимание git gc --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?

Ответы

Ответ 1

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

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

Глядя на код (too_many_loose_objects() in buildin/gc.c), вот что происходит:

  • gc.auto делится на 256 и округляется вверх
  • Открывается папка, содержащая все объекты, начинающиеся с 17
  • Проверяется, содержит ли папка больше объектов, чем результат шага 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 (пурпурные) свободные объекты в репо?

Plot of the results

Ответ 2

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

См. совершить a831c06 (10 февраля 2017 г.) Дэвид Тернер (csusbdt).
Помог: Джефф Кинг (peff).
(слияние Junio ​​C Hamano - gitster - в commit d30ec1b, 21 марта 2017 г.

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

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

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

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