Linus ha suggerito (vedi sotto per il post completo della mailing list) di usare git gc --aggressive
solo quando hai, nelle sue parole, "un pacco davvero pessimo" o "delta davvero orribilmente pessimi", tuttavia "quasi sempre, in altri casi, è effettivamente un pessimo cose da fare." Il risultato potrebbe persino lasciare il tuo repository in condizioni peggiori rispetto a quando hai iniziato!
Il comando che suggerisce per farlo correttamente dopo aver importato “una storia lunga e impegnativa” è
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>
Giovedì 6 dicembre 2007, Daniel Berlin ha scritto:
In realtà, si scopre che git-gc --aggressive
fa questa cosa stupida per impacchettare i file a volte indipendentemente dal fatto che tu abbia convertito da un repository SVN o meno.
Assolutamente. git --aggressive
è per lo più stupido. E 'davvero utile solo per il caso di “So di avere un davvero pacco pessimo e voglio buttare via tutte le decisioni sbagliate che ho preso".
Per spiegare questo, vale la pena spiegare (probabilmente ne sei consapevole, ma lasciami comunque passare attraverso le basi) come funzionano le catene delta di git e come sono così diverse dalla maggior parte degli altri sistemi.
In altri SCM, una catena delta è generalmente fissa. Potrebbe essere "in avanti" o "indietro" e potrebbe evolversi un po 'mentre lavori con il repository, ma generalmente è una catena di modifiche a un singolo file rappresentato come una sorta di singola entità SCM. In CVS, è ovviamente il *,v
file e molti altri sistemi fanno cose piuttosto simili.
Git esegue anche catene delta, ma le fa molto più "liberamente". Non esiste un'entità fissa. I Delta vengono generati rispetto a qualsiasi altra versione casuale che git ritenga essere un buon candidato delta (con varie euristiche abbastanza efficaci) e non ci sono assolutamente regole di raggruppamento rigide.
Questa è generalmente una cosa molto buona. È buono per varie ragioni concettuali (ad esempio , git internamente non ha mai bisogno di preoccuparsi dell'intera catena di revisione - non pensa affatto in termini di delta), ma è anche fantastico perché sbarazzarsi delle regole delta inflessibili significa quel git non ha alcun problema con l'unione di due file insieme, per esempio - semplicemente non ci sono *,v
"file di revisione" arbitrari che hanno qualche significato nascosto.
Significa anche che la scelta dei delta è una domanda molto più aperta. Se limiti la catena delta a un solo file, non hai davvero molte scelte su cosa fare con i delta, ma in git può davvero essere un problema completamente diverso.
Ed è qui che --aggressive
entra in gioco il nome davvero male . Mentre git generalmente cerca di riutilizzare le informazioni delta (perché è una buona idea, e non spreca tempo della CPU per ritrovare tutti i delta buoni che abbiamo trovato in precedenza), a volte tu voglio dire "ricominciamo da capo, con una tabula rasa, ignoriamo tutte le informazioni delta precedenti e proviamo a generare una nuova serie di delta"
Quindi --aggressive
non si tratta davvero di essere aggressivi, ma di sprecare tempo della CPU per ripetere una decisione che abbiamo già fatto in precedenza!
A volte è una buona cosa. Alcuni strumenti di importazione in particolare potrebbero generare delta davvero orribilmente pessimi. Tutto ciò che usagit fast-import
, ad esempio, probabilmente non ha un ottimo layout delta, quindi potrebbe valere la pena dire "Voglio iniziare da zero".
Ma quasi sempre, in altri casi, è davvero una cosa davvero brutta da fare. Sprecherà tempo per la CPU e, soprattutto se in precedenza hai fatto un buon lavoro nel delta, il risultato finale non riutilizzerà tutti quei delta buoni che hai già trovato, quindi ti ritroverai con molto anche il risultato finale peggiore!
Invierò una patch a Junio per rimuovere solo la git gc --aggressive
documentazione. Può essere utile, ma generalmente è utile solo quando capisci veramente a un livello molto profondo cosa sta facendo e quella documentazione non ti aiuta a farlo.
In generale, fare incrementale git gc
è l'approccio giusto e meglio che farlo git gc --aggressive
. Riutilizzerà i vecchi delta, e quando quei vecchi delta non possono essere trovati (il motivo per fare GC incrementale in primo luogo!) Ne creerà di nuovi.
D'altra parte, è sicuramente vero che un '"importazione iniziale di una storia lunga e impegnativa" è un punto in cui può valere la pena spendere molto tempo per trovare i delta davvero buoni . Quindi, ogni utente per sempre (a patto che non l'abbia git gc --aggressive
annullato!) Otterrà il vantaggio di quell'evento una tantum. Quindi, specialmente per i grandi progetti con una lunga storia, probabilmente vale la pena fare un po 'di lavoro extra, dicendo al delta che trova il codice di scatenarsi.
Quindi l'equivalente di git gc --aggressive
- ma fatto correttamente - è fare (durante la notte) qualcosa di simile
git repack -a -d --depth=250 --window=250
dove quella cosa della profondità è solo quanto possono essere profonde le catene delta (renderle più lunghe per la vecchia storia - vale lo spazio in testa), e la cosa della finestra riguarda la dimensione della finestra dell'oggetto che vogliamo che ogni candidato delta scansiona.
E qui, potresti voler aggiungere il -f
flag (che è "elimina tutti i vecchi delta", poiché ora stai effettivamente cercando di assicurarti che questo trovi effettivamente dei buoni candidati.
E poi ci vorrà un'eternità e un giorno ( cioè , una cosa da fare durante la notte). Ma il risultato finale è che tutti a valle di quel repository riceveranno pacchetti molto migliori, senza dover spendere alcuno sforzo per realizzarli.
Linus