Sto lavorando a un corso di git e volevo menzionare che gli errori persi non sono davvero persi fino a quando è in esecuzione git gc
. Ma verificando questo, ho scoperto che non è questo il caso. Anche dopo aver eseguito git gc --prune=all --aggressive
gli errori persi sono ancora lì.Quando esegue esattamente gli oggetti git prune: perché "git gc" non rimuove i commit?
Chiaramente ho frainteso qualcosa. E prima di dire qualcosa di sbagliato nel corso, voglio chiarire i miei fatti! Ecco uno script di esempio illustra l'effetto:
#!/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;
Questo script aggiungerà 10 fittizio impegna, ripristinare a 5 commit nel passato e aggiungere altri 10 commit. Appena prima del ripristino, stamperà l'hash del suo attuale HEAD.
Vorrei aspettare per perdere l'oggetto in CURRENT
dopo aver eseguito git gc --prune=all
. Tuttavia, posso ancora eseguire git show
su quell'hash.
Capisco che dopo aver eseguito git reset
e aggiungendo nuovi commit, ho essenzialmente creato un nuovo ramo. Ma il mio ramo originale non ha più alcun riferimento, quindi non viene visualizzato in git log --all
. Inoltre, non sarebbe stato spinto su nessun telecomando, suppongo.
La mia comprensione di git gc
era che rimuove quegli oggetti. Questo non sembra essere il caso.
Perché? E quando fa esattamente rimuovere git gc
oggetti?
Il reflog contiene ancora riferimenti ai commit "cancellati". Fino a quando non scadono o scadono esplicitamente, non verranno eliminati. – twalberg
Interessante. Ho dato uno sguardo a https://git-scm.com/docs/git-reflog e ho lanciato 'git reflog --expire = all'. Dopo di che l'oggetto era * ancora * lì. Successivamente ho eseguito un altro 'gc' ed era ancora lì. Anche un altro 'git gc --aggressive --prune = all' non ha aiutato. – exhuma
È necessario '--expire = all --all', o eseguirlo su' HEAD' (predefinito) e 'master'. Oppure puoi cancellare manualmente le voci specifiche (o vedere la risposta sotto). – torek