Лінус запропонував (див. Нижче повний пост списку розсилки) використовувати git gc --aggressive
лише тоді, коли у вас є, за його словами, " дуже поганий пакет" або "дійсно жахливо погані дельти", однак "майже завжди, в інших випадках, це насправді дуже погано що робити ". Результат може навіть залишити ваше сховище в гіршому стані, ніж коли ви починали!
Команда, яку він пропонує зробити це належним чином після імпортування "довгої та задіяної історії", така
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: <4aca3dc20712052111o730f6fb6h7a329ee811a70f28@mail.gmail.com>
Message-ID: <alpine.LFD.0.9999.0712052132450.13796@woody.linux-foundation.org>
References: <4aca3dc20712051947t5fbbb383ua1727c652eb25d7e@mail.gmail.com>
<20071205.202047.58135920.davem@davemloft.net>
<4aca3dc20712052032n521c344cla07a5df1f2c26cb8@mail.gmail.com>
<20071205.204848.227521641.davem@davemloft.net>
<4aca3dc20712052111o730f6fb6h7a329ee811a70f28@mail.gmail.com>
У четвер, 6 грудня 2007 року, Даніель Берлін написав:
Насправді виявляється, що git-gc --aggressive
ця німа штука іноді пакує файли, незалежно від того, конвертували ви з репозиторію SVN чи ні.
Абсолютно. git --aggressive
в основному німий. Це насправді корисно лише у випадку: "Я знаю, що у мене дуже поганий пакет, і я хочу відкинути всі погані рішення щодо упаковки, які я зробив".
Щоб пояснити це, варто пояснити (ви, мабуть, це вам відомо, але дозвольте мені все-таки пройти через основи), як працюють дельта-ланцюжки git і чим вони настільки відрізняються від більшості інших систем.
В інших СКМ дельта-ланцюг, як правило, фіксований. Це може бути "вперед" або "назад", і це може трохи еволюціонувати, коли ви працюєте зі сховищем, але, як правило, це ланцюжок змін до одного файлу, представленого як певна сутність SCM. У CVS, очевидно, це *,v
файл, і багато інших систем роблять досить подібні речі.
Git також робить дельта-ланцюги, але робить їх набагато "вільніше". Немає фіксованої сутності. Дельти створюються на основі будь-якої випадкової іншої версії, яку git вважає хорошим кандидатом у дельту (з різними досить успішними евристиками), і немає абсолютно жодних жорстких правил групування.
Це взагалі дуже гарна річ. Це добре з різних концептуальних причин ( тобто , git внутрішньо ніколи навіть не потребує турботи про весь ланцюжок ревізій - він насправді взагалі не думає про дельти), але це також чудово, оскільки позбавлення від негнучких правил дельти означає що git взагалі не має жодних проблем зі злиттям двох файлів, наприклад - просто немає довільних *,v
"файлів ревізій", які мають якесь приховане значення.
Це також означає, що вибір дельт - це набагато більш відкрите питання. Якщо ви обмежите дельта-ланцюжок лише одним файлом, ви дійсно не маєте багато варіантів, що робити з дельтами, але в git це дійсно може бути зовсім іншою проблемою.
І ось тут з’являється справді погано названий --aggressive
. Хоча git, як правило, намагається повторно використовувати дельта-інформацію (оскільки це гарна ідея, і вона не витрачає час процесора на пошук усіх хороших дельт, які ми знайшли раніше), іноді ви хочу сказати "давайте почнемо все спочатку, з чистого аркуша, і проігноруємо всю попередню інформацію про дельту і спробуємо створити новий набір дельт."
Отже, --aggressive
справа не в тому, щоб бути агресивними, а в тому, щоб витратити час процесора на повторне прийняття рішення, яке ми вже приймали раніше!
Іноді це добре. Деякі інструменти імпорту, зокрема, можуть генерувати дуже жахливі дельти. Все, що використовує git fast-import
, наприклад, швидше за все, не має великого дельта-макета, тому, можливо, варто сказати "Я хочу почати з чистого аркуша".
Але майже завжди, в інших випадках, це насправді дуже погано робити. Це витратить час процесора, і особливо, якщо ви насправді добре зробили роботу з дельтатацією, кінцевий результат не буде використовувати повторно всі ті добрі дельти, які ви вже знайшли, тому ви насправді отримаєте багато гірший кінцевий результат теж!
Я надішлю патч Junio, щоб просто видалити git gc --aggressive
документацію. Це може бути корисно, але загалом корисно лише тоді, коли ви дійсно на глибокому рівні розумієте, що це робить, і ця документація не допомагає вам цього зробити.
Як правило, робити інкремент git gc
- це правильний підхід, і краще, ніж робити git gc --aggressive
. Він буде використовувати повторно старі дельти, і коли ці старі дельти не вдасться знайти (причина для поступового GC в першу чергу!), Він збирається створити нові.
З іншого боку, безумовно вірно, що «початковий імпорт довгої та залученої історії» - це момент, коли може бути варто витратити багато часу на пошук справді хороших дельт. Тоді кожен користувач, який коли-небудь пізніше (якщо він не git gc --aggressive
скасовує це!) Отримає перевагу цієї одноразової події. Тож особливо для великих проектів з давньою історією, мабуть, варто зробити додаткову роботу, сказавши коду пошуку дельти розійштися.
Тож еквівалент git gc --aggressive
- але зроблено правильно - це робити (за ніч) щось на зразок
git repack -a -d --depth=250 --window=250
де ця глибинна річ - це приблизно те, наскільки глибокими можуть бути ланцюги дельта (зробіть їх довшими для старої історії - це варто простору), а вікно - про те, наскільки велике вікно об’єкта ми хочемо, щоб кожен кандидат у дельту просканував.
І тут, можливо, ви захочете додати -f
прапор (що є “скидання всіх старих дельт”, оскільки зараз ви насправді намагаєтесь переконатися, що цей насправді знаходить хороших кандидатів.
І тоді це займе вічно і цілий день ( тобто річ "зроби це за ніч"). Але кінцевий результат полягає в тому, що всі, хто перебуває з цього сховища, отримуватимуть набагато кращі пакети, не витрачаючи на це жодних зусиль.
Linus