Понимание 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
для удовлетворения своих потребностей.