Ответ 1
В настоящее время нет никакой разницы: git gc --aggressive
работает в соответствии с предложением Линуса, сделанным в 2007 году; увидеть ниже. Начиная с версии 2.11 (4 квартал 2016 г.), git по умолчанию имеет глубину 50. Окно размером 250 хорошо, потому что сканирует большую часть каждого объекта, но глубина 250 плохо, потому что каждая цепочка ссылается на очень глубокую старую объекты, что замедляет все будущие операции git для незначительно меньшего использования диска.
Историческое прошлое
Линус предложил (см. Ниже полный список рассылки) использовать git gc --aggressive
только тогда, когда у вас, по его словам, "действительно плохой пакет" или "действительно ужасно плохие дельты", однако "почти всегда", в других случаях, это на самом деле очень плохо. " Результат может даже оставить ваше хранилище в худшем состоянии, чем когда вы начали!
Команда, которую он предлагает сделать правильно после импорта "длинной и сложной истории",
git repack -a -d -f --depth=250 --window=250
Но это предполагает, что вы уже удалили нежелательный ганк из своей истории репозитория и что вы следовали контрольному списку для сокращения репозитория, найденному в документации git filter-branch
.
git -f ilter-branch может использоваться, чтобы избавиться от подмножества файлов, обычно с некоторой комбинацией
--index-filter
--subdirectory-filter
и--subdirectory-filter
. Люди ожидают, что результирующий репозиторий будет меньше исходного, но вам нужно сделать еще несколько шагов, чтобы сделать его меньше, потому что Git старается не потерять ваши объекты, пока вы не скажете это. Сначала убедитесь, что:
Вы действительно удалили все варианты имени файла, если BLOB-объект был перемещен в течение срока его службы.
git log --name-only --follow --all -- filename
может помочь вам найти переименования.Вы действительно отфильтровали все ссылки: используйте
--tag-name-filter cat -- --all
при вызовеgit filter-branch
.Тогда есть два способа получить меньший репозиторий. Более безопасный способ - это клонирование, сохраняющее ваш первоначальный нетронутым.
- Клонируйте его с помощью
git clone file:///path/to/repo
. У клона не будет удаленных объектов. Смотри мерзавец. (Обратите внимание, что клонирование с простым путем просто жестко связывает все!)Если вы действительно не хотите клонировать его по каким-либо причинам, отметьте следующие пункты (в этом порядке). Это очень разрушительный подход, поэтому сделайте резервную копию или вернитесь к ее клонированию. Вы были предупреждены.
Удалите исходные ссылки, скопированные с помощью git -f ilter-branch: say
git for-each-ref --format="%(refname)" refs/original/ | xargs -n 1 git update-ref -d
git reflog expire --expire=now --all
всех reflogs сgit reflog expire --expire=now --all
.
git gc --prune=now
мусора собирает все объекты безgit gc --prune=now
с помощьюgit gc --prune=now
(или если вашgit gc
недостаточно нов, чтобы поддерживать аргументы для--prune
, используйтеgit repack -ad; git prune
вместо этого используйтеgit repack -ad; git prune
).
Date: Wed, 5 Dec 2007 22:09:12 -0800 (PST) From: Linus Torvalds <torvalds at linux-foundation dot org> To: Daniel Berlin <dberlin at dberlin dot org> cc: David Miller <davem at davemloft dot net>, ismail at pardus dot org dot tr, gcc at gcc dot gnu dot org, git at vger dot kernel dot org Subject: Re: Git and GCC In-Reply-To: <[email protected]> Message-ID: <[email protected]> References: <[email protected]> <[email protected]> <[email protected]> <[email protected]> <[email protected]>
В четверг, 6 декабря 2007 года, Даниэль Берлин написал:
На самом деле, оказывается, что
git-gc --aggressive
делает этуgit-gc --aggressive
вещь, чтобы упаковать файлы иногда независимо от того, конвертировали ли вы из репозитория SVN или нет.Абсолютно.
git --aggressive
в основном тупой. Это действительно полезно только для случая "Я знаю, что у меня действительно плохая упаковка, и я хочу отбросить все плохие решения, которые я принял".Чтобы объяснить это, стоит объяснить (вы, вероятно, знаете об этом, но в любом случае позвольте мне пройтись по основам), как работают дельта-цепочки git, и как они так отличаются от большинства других систем.
В других SCM дельта-цепь обычно является фиксированной. Это может быть "вперед" или "назад", и он может немного эволюционировать, когда вы работаете с репозиторием, но, как правило, представляет собой цепочку изменений в одном файле, представленном в виде некой единой сущности SCM. В CVS, очевидно
*,v
файл*,v
и многие другие системы делают довольно похожие вещи.Git также делает дельта-цепочки, но делает их гораздо более "свободно". Не существует фиксированной сущности. Дельты генерируются против любой другой случайной версии, которую git считает хорошим кандидатом в дельты (с различными довольно успешными эвристиками), и здесь нет абсолютно никаких жестких правил группировки.
Это вообще очень хорошая вещь. Это хорошо по различным концептуальным причинам (то есть внутреннему git никогда даже не нужно заботиться о всей цепочке ревизий - он вообще не мыслит в терминах дельт), но это также здорово, потому что избавление от негибких правил дельты означает, что git например, вообще не возникает проблем с объединением двух файлов - просто не существует произвольных
*,v
"файлов редакций", имеющих какое-то скрытое значение.Это также означает, что выбор дельт является гораздо более открытым вопросом. Если вы ограничите цепочку дельт только одним файлом, у вас действительно не будет большого выбора, что делать с дельтами, но в git это действительно может быть совсем другая проблема.
И вот
--aggressive
появляется действительно плохо названный--aggressive
. Хотя git обычно пытается повторно использовать дельта-информацию (потому что это хорошая идея, и она не тратит процессорное время на повторное использование -f всех хороших дельт, которые мы нашли ранее) иногда вы хотите сказать: "давайте начнем все сначала с чистого листа, проигнорируем всю предыдущую информацию о дельте и попытаемся создать новый набор дельт".Таким образом,
--aggressive
самом деле не о том, чтобы быть агрессивным, а о том, чтобы тратить время процессора на решение, которое мы уже приняли ранее!Иногда это хорошо. Некоторые инструменты импорта, в частности, могут генерировать ужасно плохие дельты. Например, все, что использует
git fast-import
, скорее всего, не имеет большой разметки дельты, поэтому стоит сказать: "Я хочу начать с чистого листа".Но почти всегда, в других случаях, это действительно очень плохая вещь. Это приведет к потере процессорного времени, и особенно если вы действительно хорошо поработали над дельтацией ранее, конечный результат не будет повторно использовать все те хорошие дельты, которые вы уже нашли, так что на самом деле вы также получите гораздо худший конечный результат. !
Я пошлю патч в Junio, чтобы просто удалить документацию
git gc --aggressive
. Это может быть полезно, но, как правило, полезно только тогда, когда вы действительно очень глубоко понимаете, что он делает, и эта документация вам не помогает.Как правило, правильное выполнение инкрементального
git gc
лучше, чемgit gc --aggressive
. Он собирается повторно использовать старые дельты, и когда эти старые дельты не могут быть найдены (прежде всего, для создания инкрементального ГХ!), Он собирается создавать новые.С другой стороны, определенно верно, что "первоначальный импорт длинной и сложной истории" - это точка, в которой стоит потратить много времени на поиск действительно хороших дельт. Затем каждый пользователь (если только он не использует
git gc --aggressive
для его отмены!)git gc --aggressive
преимущество этого единовременного события. Так что, особенно для больших проектов с длинной историей, вероятно, стоит проделать дополнительную работу, рассказав дельта-поисковому коду.Таким образом, эквивалент
git gc --aggressive
- но выполненный правильно - это сделать (в одночасье) что-то вродеgit repack -a -d --depth=250 --window=250
где эта глубина только о том, насколько глубокими могут быть дельта-цепочки (сделать их более длинными для старой истории - это стоит пространства), а суть окна в том, насколько велико окно объекта, которое мы хотим, чтобы каждый кандидат-дельта сканировал.
И здесь вы, возможно, захотите добавить флаг
-f
(то есть "отбросить все старые дельты"), поскольку вы сейчас действительно пытаетесь убедиться, что этот действительно найдет хороших кандидатов.И тогда это займет вечность и день (то есть, сделай это за одну ночь). Но конечный результат заключается в том, что все, кто находится ниже по потоку от этого хранилища, получат гораздо лучшие пакеты, не тратя на это никаких усилий.
Linus