2010-05-21 17 views
22

Ho un albero git comeCome cancellare VERAMENTE un ramo git (ad esempio rimuovere tutti i suoi oggetti/commit)?

    A---B---C topic 
       /
      D---E---F---G master  <-- 

Vorrei rimuovere argomento e tutti gli oggetti su di esso.

rilevo l'SHA ID di argomento, quindi digitare:

git branch -D topic 
git gc         # <-- I also tried prune here... 
git checkout -b temp <SHA1 ID of topic> 

Dopo l'ultimo comando mi aspetto di ottenere un errore (qualcosa come "ID oggetto inesistente ..." o somth del genere.). Tuttavia non c'è nessun errore e gitk mostra la stessa struttura ad albero di cui sopra ??

Cosa mi manca? Ho pensato che gc/prune cancellasse tutti gli oggetti non raggiungibili?

+2

La risposta di VonC spiega i fatti della questione. Se vuoi conoscere la ragione "filosofica", è semplicemente che git ci prova molto duramente a non lasciarti cancellare accidentalmente nulla. 'git gc' da solo è destinato ad essere un'operazione di cleanup/repacking. Devi dire qualcosa di più forte per farlo potenzialmente cancellare il lavoro recente. – Cascabel

risposta

4

Nota maggio 2010: come mentioned by Jakub, se il ramo è stato unito, l'argomento sarebbe ancora raggiungibile.

Qui, supponiamo che non ci sia stata unione.
Poi, come mentioned in the ProGit book e dettagliata in questo SO question:

git gc --prune=now 

dovrebbe essere sufficiente (si dovrebbe chiamare direttamente git prune). Puoi controllarlo con un git count-objects -v.
Modifica aprile 2012: maxschlepzig nei commenti conferma che potrebbero essere necessari ulteriori passaggi, come descritto in Duke's answer (ma senza git repack).
Così, invece di un git gc --prune now:

git reflog expire --expire=now --all 
git gc --aggressive --prune=now 
+1

"Unreachable" è in realtà anche più forte di quello che implichi qui. Per quanto riguarda 'git-gc', un oggetto è raggiungibile se è raggiungibile da un reflog - e i reflog impiegano molto tempo a scadere. Ad esempio, è possibile unire il ramo al master, rendersi conto che era cattivo e ripristinare il master nella posizione precedente e il commit sarebbe considerato raggiungibile fino alla scadenza della voce del reflog (impostazione predefinita 90 giorni). – Cascabel

+3

Inoltre, probabilmente è ovvio, ma sii super-accurato usando '--prune = now'. Sarebbe orribile rendersi conto, subito dopo essere entrati, che un altro impegno importante è stato spazzato via. – Cascabel

+0

grazie ragazzi, rock! :) – Alan

24

Proprio la prugna gc spesso non è sufficiente per sbarazzarsi degli oggetti extra in pronti contro termine. Se i commit sono ancora referenziati nel reflog, non considereranno quegli oggetti irraggiungibili e quindi maturi per la potatura.

Ecco cosa ha funzionato per me:

git reflog expire --expire=now --all 
git gc --aggressive --prune=now 
git repack -a -d -l 

Questo renderà alcune modifiche alla storia del vostro pronti contro termine, e può ben presenti le difficoltà se gli altri sono a seconda dei rami che si soffiare via.

Potrebbe essere necessario ripetere la clonazione del repository per vedere effettivamente una differenza nelle sue dimensioni.

+0

Feedback interessante. +1 – VonC

+1

Ho dovuto usare 'git reflog expire --expire = now --all'. Nota il "expire" aggiunto. –

+0

Testato - e il passo di repack non era necessario. – maxschlepzig

Problemi correlati