Was passiert mit verwaisten Commits?

8

Ich habe ein Repo mit vier Commits:

%Vor%

I reset -- soft zu C2 commit und jetzt habe ich ein Repo wie folgt:

%Vor%

Jetzt füge ich einen zusätzlichen Commit hinzu, so dass das Log so aussieht:

%Vor%

Was ist mit commits C3 und C4 passiert? Ich habe sie nicht gelöscht, also nehme ich an, dass sie immer noch da sind, C3 ist immer noch C2 .

    
BanksySan 06.05.2015, 22:20
quelle

3 Antworten

7

Kurze Antwort: Die Commits C3 und C4 bleiben in der Git-Objektdatenbank, bis sie als Garbage Collection gesammelt werden.

Lange Antwort: Die Garbage-Collection wird automatisch durch verschiedene Git-Porcelain-Befehle oder bei explizitem Garbage Collection-Vorgang ausgeführt. Es gibt viele Szenarien, die eine automatische Speicherbereinigung auslösen könnten. Sehen Sie sich die gc.* -Konfigurationseinstellungen an, um eine Idee zu erhalten. Sie können das Sammeln explizit mit dem git gc -Baubefehl durchführen. Schauen wir uns ein Beispiel an, um zu sehen, was passiert.

Lassen Sie uns zuerst unsere Umgebung einrichten (ich benutze Linux; nehmen Sie die nötigen Änderungen für Ihre Umgebung vor), damit wir hoffentlich die gleichen Objekt-Hashes in verschiedenen Git-Repositories erhalten.

%Vor%

Da Commit-Objekt-Hashes unter Verwendung dieser Information erzeugt werden, sollten wir alle dieselben Hashes erhalten, wenn wir dieselben Autor- und Committer-Werte verwenden.

Lassen Sie uns jetzt eine Funktion initialisieren, um Objektinformationen mit Hilfe von git log , git reflog , git count-objects , git rev-list und git fsck .

%Vor%

Nun initialisieren wir ein Git Repository.

%Vor%

Was für mich heißt:

%Vor%

Wie erwartet haben wir ein initialisiertes Repository ohne Objekte darin. Lassen Sie uns ein paar Commits machen und sich die Objekte ansehen.

%Vor%

Was mir die folgende Ausgabe gibt:

%Vor%

Jetzt haben wir sechs Objekte im Repository: fünf Commits und einen leeren Baum. Wir können sehen, dass Git Verzweigungs-, Tag- und / oder Reflog-Referenzen auf alle fünf Commit-Objekte hat. Solange Git auf ein Objekt verweist, wird dieses Objekt nicht als Garbage Collection behandelt. Das explizite Ausführen einer Gabagesammlung führt dazu, dass keine Objekte aus dem Repository entfernt werden. (Ich überlasse es, dies als eine Übung für Sie zu vervollständigen.)

Lassen Sie uns jetzt Git-Referenzen auf die Commits C3 , C4 und C5 entfernen.

%Vor%

Welche Ausgaben:

%Vor%

Nun sehen wir, dass nur zwei Commits von Git referenziert werden. Alle sechs Objekte befinden sich jedoch noch im Repository. Sie verbleiben im Repository, bis sie automatisch oder explizit als Garbage Collection erfasst werden. Sie können zum Beispiel ein nicht referenziertes Commit mit git cherry-pick wiederbeleben oder es mit git show . Lassen Sie uns jetzt jedoch die unreferenzierten Objekte explizit abräumen und sehen, was Git hinter den Kulissen macht.

%Vor%

Dies wird ein bisschen Information ausgeben.

%Vor%

Und schließlich, lassen Sie uns die Objekte betrachten.

%Vor%

Welche Ausgaben:

%Vor%

Jetzt sehen wir, dass wir nur drei Objekte haben: die zwei Commits und einen leeren Baum.

    
Dan Cruz 07.05.2015, 15:15
quelle
5

Führen Sie git show 6c35831 aus, um zu sehen, dass C4 zum Beispiel immer noch da ist. Führen Sie git reflog master aus, um (viele) zu sehen, was master verwendet ist, um darauf zu verweisen. Einer der Einträge ( master^{1} meist wahrscheinlich, aber vielleicht einen älteren, wenn Sie auch andere Änderungen vorgenommen haben) sollte 6c35831 entsprechen, und git show master^{1} (oder welcher Eintrag auch immer) sollte die gleiche Ausgabe des ersten anzeigen git show command Ich erwähnte.

    
chepner 06.05.2015 22:33
quelle
4

Verwaiste Commits bleiben einfach dort, bis sie durch explizites Ausführen von git gc gelöscht werden.

    
Mureinik 06.05.2015 22:26
quelle

Tags und Links