Linus schlug vor (siehe unten für den vollständigen Beitrag auf der Mailingliste), git gc --aggressive
nur dann zu verwenden, wenn Sie in seinen Worten "eine wirklich schlechte Packung" oder "wirklich schrecklich schlechte Deltas" haben, aber "fast immer, in anderen Fällen ist es tatsächlich eine wirklich schlechte." etwas zu tun." Das Ergebnis kann sogar dazu führen, dass sich Ihr Repository in einem schlechteren Zustand befindet als zu Beginn!
Der Befehl, den er vorschlägt, um dies richtig zu tun, nachdem er „eine lange und involvierte Geschichte“ importiert hat, lautet
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>
Am 6. Dezember 2007 schrieb Daniel Berlin:
Tatsächlich stellt sich heraus, dass git-gc --aggressive
dies manchmal dumm ist, Dateien zu packen, unabhängig davon, ob Sie von einem SVN-Repo konvertiert haben oder nicht.
Absolut. git --aggressive
ist meistens dumm. Es ist wirklich nur für den Fall nützlich: "Ich weiß, dass ich eine wirklich schlechte Packung habe, und ich möchte alle schlechten Packungsentscheidungen, die ich getroffen habe, wegwerfen."
Um dies zu erklären, lohnt es sich zu erklären (Sie sind sich wahrscheinlich dessen bewusst, aber lassen Sie mich trotzdem die Grundlagen durchgehen), wie Git-Delta-Ketten funktionieren und wie sie sich von den meisten anderen Systemen unterscheiden.
In anderen SCMs ist im Allgemeinen eine Delta-Kette festgelegt. Es kann "vorwärts" oder "rückwärts" sein und sich während der Arbeit mit dem Repository etwas weiterentwickeln, aber im Allgemeinen handelt es sich um eine Kette von Änderungen an einer einzelnen Datei, die als eine Art einzelne SCM-Entität dargestellt wird. In CVS ist es offensichtlich die *,v
Datei, und viele andere Systeme tun ziemlich ähnliche Dinge.
Git macht auch Delta-Ketten, aber es macht sie viel "lockerer". Es gibt keine feste Einheit. Deltas werden gegen jede andere zufällige Version generiert, die git als guten Delta-Kandidaten erachtet (mit verschiedenen ziemlich erfolgreichen Heuristiken), und es gibt absolut keine harten Gruppierungsregeln.
Dies ist im Allgemeinen eine sehr gute Sache. Es ist aus verschiedenen konzeptionellen Gründen gut ( dh Git muss sich intern nie wirklich um die gesamte Revisionskette kümmern - es denkt überhaupt nicht wirklich in Deltas), aber es ist auch großartig, weil es bedeutet, die unflexiblen Delta-Regeln loszuwerden Dieser Git hat zum Beispiel überhaupt keine Probleme beim Zusammenführen von zwei Dateien - es gibt einfach keine willkürlichen *,v
„Revisionsdateien“, die eine versteckte Bedeutung haben.
Dies bedeutet auch, dass die Wahl der Deltas eine viel offenere Frage ist. Wenn Sie die Delta-Kette auf nur eine Datei beschränken, haben Sie wirklich nicht viele Möglichkeiten, was Sie mit Deltas tun sollen, aber in Git kann es wirklich ein ganz anderes Problem sein.
Und hier kommt der wirklich schlecht benannte ins --aggressive
Spiel. Während Git im Allgemeinen versucht, Delta-Informationen wiederzuverwenden (weil es eine gute Idee ist und keine CPU-Zeit damit verschwendet, alle guten Deltas wiederzufinden, die wir zuvor gefunden haben), manchmal Sie Ich möchte sagen: "Beginnen wir von vorne mit einer leeren Tafel und ignorieren alle vorherigen Delta-Informationen und versuchen, einen neuen Satz von Deltas zu generieren."
Es geht also --aggressive
nicht wirklich darum, aggressiv zu sein, sondern darum, CPU-Zeit zu verschwenden, um eine Entscheidung zu wiederholen, die wir bereits zuvor getroffen haben!
Manchmal ist das eine gute Sache. Insbesondere einige Importwerkzeuge könnten wirklich schrecklich schlechte Deltas erzeugen. Alles git fast-import
, was zum Beispiel verwendet wird, hat wahrscheinlich nicht viel von einem großartigen Delta-Layout, daher könnte es sich lohnen zu sagen: "Ich möchte von einer sauberen Tafel ausgehen."
Aber in anderen Fällen ist es fast immer eine wirklich schlechte Sache. Es wird CPU-Zeit verschwenden, und besonders wenn Sie beim Deltaing früher gute Arbeit geleistet haben, wird das Endergebnis nicht alle guten Deltas wiederverwenden, die Sie bereits gefunden haben, sodass Sie am Ende tatsächlich viel haben schlechteres Endergebnis auch!
Ich werde einen Patch an Junio senden, um nur die git gc --aggressive
Dokumentation zu entfernen . Es kann nützlich sein, aber es ist im Allgemeinen nur dann nützlich, wenn Sie auf einer sehr tiefen Ebene wirklich verstehen, was es tut, und diese Dokumentation Ihnen dabei nicht hilft.
Inkrementell git gc
ist im Allgemeinen der richtige Ansatz und besser als inkrementell git gc --aggressive
. Alte Deltas werden wiederverwendet, und wenn diese alten Deltas nicht gefunden werden können (der Grund für die erstmalige inkrementelle GC!), Werden neue erstellt.
Auf der anderen Seite ist es definitiv wahr, dass ein „anfänglicher Import einer langen und involvierten Geschichte“ ein Punkt ist, an dem es sich lohnen kann, viel Zeit damit zu verbringen, die wirklich guten Deltas zu finden. Dann git gc --aggressive
erhält jeder Benutzer (solange er es nicht zum Rückgängigmachen verwendet!) Den Vorteil dieses einmaligen Ereignisses. Insbesondere für große Projekte mit einer langen Geschichte lohnt es sich wahrscheinlich, zusätzliche Arbeit zu leisten und dem Delta-Finding-Code zu sagen, dass er wild werden soll.
Das Äquivalent von git gc --aggressive
- aber richtig gemacht - ist also, (über Nacht) so etwas zu tun
git repack -a -d --depth=250 --window=250
Bei dieser Tiefe geht es nur darum, wie tief die Delta-Ketten sein können (verlängern Sie sie für die alte Geschichte - es lohnt sich der Platzaufwand), und bei der Fenstersache geht es darum, wie groß ein Objektfenster ist, das jeder Delta-Kandidat scannen soll.
Und hier möchten Sie vielleicht die -f
Flagge hinzufügen (dies ist das "alle alten Deltas fallen lassen", da Sie jetzt tatsächlich versuchen, sicherzustellen, dass diese tatsächlich gute Kandidaten findet.
Und dann wird es ewig und einen Tag dauern ( dh eine Sache, die man über Nacht macht). Das Endergebnis ist jedoch, dass jeder, der diesem Repository nachgeschaltet ist, viel bessere Pakete erhält, ohne sich selbst darum kümmern zu müssen.
Linus