Wann schneidet git Objekte genau ab: Warum entfernt „git gc“ keine Commits?
Ich arbeite an einem Git-Kurs und wollte erwähnen, dass verlorene Refs erst beim Laufen wirklich verloren gehen.git gc
. Als ich dies überprüfte, stellte ich fest, dass dies nicht der Fall ist. Auch nach dem Laufengit gc --prune=all --aggressive
die verlorenen refs sind noch da.
Klar habe ich etwas falsch verstanden. Und bevor ich im Kurs etwas Falsches sage, möchte ich meine Fakten klarstellen! Hier ist ein Beispielskript, das den Effekt veranschaulicht:
#!/bin/bash
git init
# add 10 dummy commits
for i in {1..10}; do
date > foo.txt
git add foo.txt
git commit -m "bump" foo.txt
sleep 1
done;
CURRENT=$(git rev-parse HEAD)
echo HEAD before reset: ${CURRENT}
# rewind
git reset --hard HEAD~5
# add another 10 commits
for i in {1..10}; do
date > foo.txt
git add foo.txt
git commit -m "bump" foo.txt
sleep 1
done;
Dieses Skript fügt 10 Dummy-Commits hinzu, setzt auf 5 Commits in der Vergangenheit zurück und fügt weitere 10 Commits hinzu. Kurz vor dem Zurücksetzen wird der Hash des aktuellen HEADs gedruckt.
Ich würdeerwarten vo um das Objekt in @ zu verlierCURRENT
nach dem Rennengit gc --prune=all
. Trotzdem kann ich noch @ laufgit show
auf diesem Hash.
Ich verstehe, dass nach dem Ausführen vongit reset
und neue Commits hinzufügen, habe ich im Wesentlichen einen neuen Zweig erstellt. Mein ursprünglicher Zweig hat jedoch keine Referenz mehr und wird daher nicht in @ angezeiggit log --all
. Es würde auch nicht zu irgendeiner Fernbedienung geschoben werden, nehme ich an.
Mein Verständnis vongit gc
war das ist entfernt diese Objekte. Dies scheint nicht der Fall zu sein.
Warum? Undwan exactl, y doesgit gc
Objekte entfernen?