Wie reduziere ich die Tiefe eines vorhandenen Git Clones?

9

Ich habe einen Klon. Ich möchte die Geschichte darauf reduzieren, ohne von Grund auf mit einer reduzierten Tiefe zu klonen. Arbeitete Beispiel:

%Vor%

OK, das ist nicht so, aber, aber es wird für diese Diskussion dienen. Wenn ich gc versuche, wird es kleiner:

%Vor%

Immer noch ziemlich groß (Git Pull gibt an, dass es immer noch Push / Pulling zur Fernbedienung ist). Wie wäre es mit dem Umpacken?

%Vor%

Yup, wurde nicht kleiner. --depth für repack ist nicht das gleiche für Klon:

%Vor%

Git Pull sagt, es ist immer noch im Takt mit der Fernbedienung, was niemanden überrascht.

OK - so wie man einen bestehenden Klon in einen seichten Klon umwandelt, ohne ihn zu nixen und neu auszuprobieren?

    
paul_h 03.07.2016, 16:21
quelle

4 Antworten

7
%Vor%

Dies ist wirklich nicht "von Grund auf" Klonen, da es rein lokale Arbeit ist und es schafft praktisch nichts mehr als die heruntergekommenen Pack-Dateien, wahrscheinlich in der Größenordnung von mehreren zehn Kilobytes. Ich gehe davon aus, dass Sie nicht effizienter werden. Sie werden mit benutzerdefinierten Arbeiten fertig, die mehr Platz in Form von Skripts und Testaufgaben benötigen, als dies in Form von ein paar KB temporären Repo-Overhead tut .

    
jthill 05.07.2016, 01:48
quelle
2

Bearbeiten, Februar 2017: Diese Antwort ist jetzt veraltet / falsch. Git kann einen flachen Klon seichter machen, zumindest intern. Git 2.11 hat auch --deepen , um die Tiefe eines Klons zu erhöhen, und es sieht so aus, als ob es Pläne gibt, negative Werte zuzulassen (obwohl sie gerade abgelehnt werden). Es ist nicht klar, wie gut das in der realen Welt funktioniert, und Ihre beste Wette ist immer noch, den Klon zu klonen, wie in jthills Antwort .

Sie können nur ein Repository vertiefen. Dies liegt hauptsächlich daran, dass Git um herum gebaut wird, um neue Sachen hinzuzufügen . Die Art und Weise, wie flache Klone funktionieren, besteht darin, dass Ihr (empfangendes) Git den Sender (ein anderes Git) dazu bringt, beim Erreichen des shallow-clone-depth-Arguments keine neuen Sachen mehr zu senden und koordiniert mit dem Absender, um warum .git/shallow , die sowohl das Repository als flach markiert, als auch Notizen, welche Commits gekürzt werden.

Beachten Sie, dass Ihr Git während dieses Prozesses immer noch neues Material hinzufügt . (Auch wenn es das Klonen beendet und beendet hat, vergisst Git, was die Tiefe war, und mit der Zeit wird es unmöglich, herauszufinden, was es war. Alles, was Git sagen kann, ist, dass dies ein flacher Klon ist , weil die Datei .git/shallow , die Commit-IDs enthält, noch existiert.)

Der Rest von Git wird weiterhin um dieses "add new stuff" -Konzept herum gebaut, so dass Sie den Klon vertiefen können, aber nicht seine Oberflächlichkeit erhöhen können. (Es gibt kein gutes, vereinbartes Verb dafür: das Gegenteil davon, eine Grube zu vertiefen, füllt sie aus, aber fill hat die falsche Konnotation. Vermindern könnte funktionieren; denke ich Ich werde das benutzen.)

Theoretisch könnte git gc , das ist der einzige Teil von Git, der jemals tatsächlich etwas hinauswirft, 1 vielleicht ein Repository verkleinern, sogar einen vollständigen Klon in einen flachen umwandeln, aber nein Man hat Code geschrieben, um das zu tun. Es gibt einige knifflige Bits, z. B. verwerfen Sie Tags? Flache Klone beginnen aus Implementierungsgründen mit sans-Tags, so dass zum Konvertieren eines Repositorys in seicht oder zum Reduzieren eines vorhandenen seichten Repositorys möglicherweise mindestens einige Tags verworfen werden müssen. Sicherlich müsste jedes Tag, das auf einen Commit hinweist, der durch die abnehmende Aktion ausgelöscht wird, verschwinden.

Das Argument --depth bis git-pack-objects (übergeben von git repack ) bedeutet indessen etwas anderes: Es ist die maximale Länge einer Delta-Kette, wenn Git sein modifiziertes xdelta-Komprimierung auf Git-Objekten, die in jeder Pack-Datei gespeichert sind. Dies hat nichts mit der Tiefe bestimmter Teile des Commit-DAG zu tun (wie von jedem Zweigkopf berechnet).

1 Nun, git repack endet als Side Effect, je nachdem welche Flags benutzt werden, aber es wird auf diese Weise von git gc aufgerufen. Dies gilt auch für git prune . Damit diese beiden Befehle richtig funktionieren, müssen sie git reflog expire zuerst ausführen. Das "normale Benutzer" Ende der Aufräumsequenz ist git gc ; Es beschäftigt sich mit all dem. So können wir sagen, dass git gc ist, wie Sie angesammelte "neue Sachen" verwerfen, die sich doch als unerwünscht herausgestellt haben.

    
torek 03.07.2016 21:05
quelle
2

seit mindestens git Version 2.14.1 gibt es

%Vor%

Dies wird die neuesten Commits vom Ursprung holen, wenn es welche gibt, und dann den lokalen Verlauf bis zur Tiefe von 10 abschneiden (oder verlängern).

Die Cutoff-Commits sind nicht mehr mit normalen Mitteln erreichbar, bleiben aber im Repository hängen. Wenn es keine anderen Referenzen gibt, die sie enthalten, werden sie eventuell durch das automatische git gc entfernt.

Sie können die alten Commits auch sofort entfernen. Um dies zu tun, müssen Sie alle Referenzen entfernen, die sie enthalten könnten. das ist meistens der Reflog und die Tags. Dann starte git gc .

Beachten Sie, dass sich der Reflog nach einer bestimmten Zeit selbst löscht, aber Tags bleiben für immer bestehen. Wenn Sie also den Speicherplatz von alten Commits zurückfordern möchten, müssen Sie die Tags manuell entfernen.

Wenn Sie Tags entfernt haben, ruft das nächste git fetch nur die Tags ab, die für die Commits relevant sind, die sich derzeit im Repository befinden.

lösche den Reflog:

%Vor%

Entfernen Sie alle Tags:

%Vor%

lösche alle dangling Objekte:

%Vor%     
lesmana 01.09.2017 16:37
quelle
0

OK hier ist ein Versuch, es zu bash, ignoriert nicht standardmäßige Verzweigungen, und auch angenommen, die Fernbedienung heißt 'Herkunft':

%Vor%

Verwenden Sie: 'git-slimmer.sh & lt; folder_containing_git_repo & gt;'

    
paul_h 05.07.2016 01:28
quelle

Tags und Links