Avvertenza: quanto segue è pericoloso, in quanto riscrive la cronologia. Assicurati sempre di avere un backup del tuo repository prima di fare qualsiasi tipo di riscrittura della storia come questa.
Sostituire l'hash di seguito con l'hash del genitore del commit che si desidera avere come nuovo primo commit.
git filter-branch --parent-filter '
read parent
if [ "$parent" = "-p 5bdd44e5919cb0a95a9924817529cd7c980f88b5" ]
then
echo
else
echo "$parent"
fi'
Questo riscrive i genitori di ciascun commit; per la maggior parte dei commit, li lascia gli stessi, ma quello con il genitore che corrisponde all'hash specificato, sostituisce con un genitore vuoto, il che significa che ora diventerà un commit senza genitore. Questo scollegherà tutta la tua vecchia storia.
Nota: se quello che vuoi essere il tuo primo commit è un commit di merge, dovrai corrispondere a qualcosa come -p parent1 -p parent2 -p parent3
per ciascuno dei genitori del commit di unione, nell'ordine corretto.
Se si desidera applicare questo a tutti i rami e tag anziché solo il ramo corrente, passare in --all
alla fine del comando (dopo lo script).
Dopo aver fatto questo, e controllato che ha funzionato correttamente, è possibile eliminare il ramo originale ed eseguire un gc
per ripulire i commit ora senza riferimenti:
git update-ref -d refs/original/refs/heads/master
Nota che, dal momento git
tende a cercare di preservare i dati, per liberare effettivamente lo spazio dovrai anche rimuovere i commit dal tuo reflog, quindi eseguire lo gc
per pulirlo.
git reflog expire --expire-unreachable=all --all
git gc --prune=all
Se non si sta facendo questo per risparmiare spazio o sradicare le vecchie commit, è possibile mantenere la vecchia storia intorno a un ramo, come ad esempio git branch old-master refs/original/refs/heads/master
; puoi persino "riattaccarlo virtualmente" usando git replace
, a quel punto avresti due storie non connesse (quindi quando premi su un repository remoto, sposterai solo la cronologia troncata) ma quando guardi la cronologia nel repository locale tu vedrà la storia completa.
Può darci maggiori informazioni? Perché se lo fai, finirai per eliminare tutti i primi commit del tuo repository! Che è impossibile Cosa vuoi veramente fare? Magari crea una nuova root nel tuo repository e rebase solo il commit che vuoi su questo commit. – Philippe
Aggiornato con ulteriori informazioni. In pratica voglio solo cancellare una parte importante della cronologia, mantenendo gli ultimi commit. –
Per dirla in altre parole, voglio racchiudere alcune migliaia di commit in uno, ignorando i conflitti di merge e mantenendo solo lo stato del repository all'ultimo commit dell'intervallo. –