Что означает «Автоматическая упаковка хранилища для оптимальной производительности»?

225

У меня проблема с моим git-репо. В течение последних нескольких дней, когда я делаю отправку на сервер, я получаю это сообщение: «Автоматическая упаковка хранилища для оптимальной производительности», и, похоже, оно не исчезает и не возвращает оболочку.

Я также попытался перейти на новую ветку, а затем сделал ребаз в предыдущей ветке, а затем сделал, git gcчтобы удалить неиспользуемые объекты истории, а затем сделал push, но все равно это сообщение появляется. Пожалуйста, дайте мне знать, что происходит с моим репо.

Фуркан Асгар
источник

Ответы:

305

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

Во время большинства операций, которые потенциально могут увеличить количество незакрепленных (распакованных) объектов в хранилище (включая push-сообщения), Git вызывает git gc --auto. Если имеется достаточно незакрепленных объектов (по умолчанию не менее 6700), он будет вызывать их git repack -d -lдля упаковки. Если есть слишком много отдельных пакетов, он также упакует их в один.

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

Если вы позволите Git закончить переупаковку, это не повторится некоторое время. Это действительно может занять некоторое время, особенно если у вас много больших бинарных объектов, но если это срабатывает, то это признак того, что это, вероятно, значительно сократит объем дискового пространства, занимаемого репо. Если вы действительно не хотите, чтобы это произошло, вы можете изменить параметр config gc.auto. Если вы увеличите его до чего-то намного большего, чем 6700, это будет происходить реже, но это займет больше времени. Если вы уменьшите его, вам все равно придется выполнить ваш текущий перепак, но впоследствии это произойдет чаще и закончится быстрее. Если вы установите его на 0, он отключит автоматическую перепаковку.

Смотрите man git-gc(под --auto) и man git-config(под gc.auto) для получения дополнительной информации.

Cascabel
источник
14
Действительно, это заняло у меня около 5 минут, но все закончилось. Отличный ответ.
Джошуа Пинтер
6
Мы наблюдаем, как это происходит с каждым толчком (несколько секунд, хе).
2
@dpk: Этого не должно происходить в обычных обстоятельствах - количество объектов в одном нажатии не должно быть достаточно большим, чтобы вызвать его (если ваш репозиторий не огромен и / или вы не нажимаете на тонну коммитов), поэтому, как только он успешно завершает (вы позволяете завершить, верно?), это не должно повториться, пока вы не дойдете до этого. Если вы не можете понять это, задайте отдельный вопрос.
Каскабель
6
«Если вы дадите Git закончить», и он сможет ... fatal: Out of memory, malloc failed (tried to allocate 79610689 bytes) error: failed to run repack- это то, что я получаю, вставляя всю нашу кодовую базу в одно git-репо. Думаю, я собираюсь убить приложения и принудительно перепаковать «вручную»
ruffin
11
Я получаю это каждый раз, когда делаю мерзавец. Я сделал git gc вручную, но это все равно происходит каждый раз, когда я тяну. Weird.
Барри Келли
51

Хотя Джефрони прав, что иногда для автоматической упаковки просто требуется время для завершения, если сообщение автоматической упаковки сохраняется в течение нескольких дней, как описано в OP, есть большая вероятность, что при очистке git отсутствуют висячие объекты, как описано в этом вопросе .

Чтобы увидеть, вызывают ли висящие объекты текущие сообщения об автоматической упаковке, попробуйте запустить git fsck. Если вы получили длинный список висячих коммитов, вы можете очистить их

git gc --prune=now

Я обычно запускаю это на своем репо каждые 2-3 месяца, когда сообщение об автоматической упаковке не исчезает после одного нажатия.

wbharding
источник
5
Хотя это и не принятый ответ, это было именно то, что мне было нужно. Я получал сообщение каждый раз, когда делал это git pull, в течение нескольких дней, и fsckдействительно демонстрировал тонну свисающих коммитов.
Йорн Зафферер
36

Чтобы отключить для одного проекта:

cd your_project_dir
git config gc.auto 0

Чтобы отключить глобально:

git config --global gc.auto 0
Андерс Линден
источник
2
Я думаю, я узнал, как: перейдите в папку .git, откройте файл конфигурации, удалите текст 'auto = 0' и сохраните. Это, кажется, чтобы включить автоматическую упаковку.
Адриан Кейстер
18
git config --unset gc.auto
jtatum
10

Git запускает git-repack, который упаковывает множество объектов (= файлы, коммиты и деревья) в один файл пакета. Git делает это иногда, когда эвристик говорит, что может быть сэкономлено место (файл пакета содержит сжатые дельты объектов, в то время как каждый файл в каталоге objects / содержит сжатое полное содержимое файла)

Rudi
источник
2

Надеюсь, этот git gc --autoшаг теперь (git 2.0.1, 25 июня 2014 г.) более эффективен.
Смотрите коммит 62aad18 от Nguyễn Thái Ngọc Duy ( pclouds)

gc --auto: не блокировать ссылки в фоновом режиме

9f673f9 ( gc: опция конфигурации для запуска --auto в фоновом режиме - 2014-02-08, Git 2.0.0) помещает " gc --auto" в фоновом режиме, чтобы уменьшить время ожидания пользователя.
Часть сбора мусора - сборщики мусора и обрезки. Это требует блокировки некоторых ссылок и может прервать другие процессы, пытаясь заблокировать ту же ссылку.

Если gc --autoсработает в середине скрипта, то удержание блокировок в фоновом режиме может привести к сбою скрипта, чего никогда не было до 9f673f9 .

Продолжайте работать pack-refsи " reflog --prune" на переднем плане, чтобы остановить параллельные обновления ссылок. Остальные фоновые операции (переупаковка, удаление и повторное создание) не должны влиять на работу процессов git.

И Git 2.22 (Q2 2019) дополнительно оптимизироватьgit gc .

VonC
источник