Rimuovi i vecchi commit git


89

Sono molto nuovo su git e mi chiedevo se qualcosa del genere fosse possibile?

>git log --pretty=oneline --abbrev-commit
2f05aba Added new feature
3371cec Fixed screw up    <-- I want to remove this
daed25c Screw up          <-- and remove this.
e2b2a84 First.                So it's like they never happend.

È possibile?

Risposte:


63

Questo è possibile con git rebase. Prova quanto segue

git rebase -i HEAD~4

e poi segui le istruzioni interattive nel tuo editor. Nella prima fase si "schiacciano" i commit. Dovrebbe assomigliare a qualcosa di simile a questo:

pick 2f05aba ... will be preserved
squash 3371cec ... will be squashed with daed25c
squash daed25c ... will be squashed with e2b2a84
pick e2b2a84 .. will contain this and 3371cec and daed25c

Nella seconda fase puoi modificare i messaggi di commit.


27
Non si tratta di eliminare i commit piuttosto che di schiacciarli?
Richard

4
@Stony: Beh, probabilmente potresti anche eliminarli. Ma dai commenti di commit nell'OP ("Screw up" e "Fixed Screw up") ho supposto che uno stia annullando l'altro e che potresti anche semplicemente schiacciare i due.
Deve

85

Se desideri veramente cancellarli (cancellandoli dalla cronologia, per non essere più visti), puoi farlo

eseguire rebase:

git rebase -i HEAD~4

e quindi, elimina (o commenta) le righe corrispondenti ai commit che desideri eliminare, in questo modo:

pick 2f05aba ... #will be preserved
#pick 3371cec ... #will be deleted
#pick daed25c ... #will be deleted
pick e2b2a84 ... #will be preserved

2
Sono nuovo su GitHub, come fai a eseguire il push delle modifiche dopo (quando faccio clic su Sincronizza, ripristina semplicemente ciò che ho fatto). Penso di aver capito: git push origin HEAD --force
Nicolas Thery

@NicolasThery non lo fai. Ecco perché git push si rifiuta di funzionare senza --force, perché stai riscrivendo la storia e distruggerai i repository di altre persone. Se hai già spinto, la tua unica opzione è fare un file git revert. Il che, a pensarci bene, è sensato perché se avessi estratto il codice di qualcun altro non vorresti che fossero in grado di cancellare i tuoi vecchi commit senza un qualche tipo di cronologia, vero?
Angry Dan

Presumo che questo funzioni semplicemente nell'attuale repository Git e non cambia nulla a monte / qualsiasi altro nodo Git?
Alexander Mills

2
@AlexanderMills Non cambia nulla a monte fintanto che non lo spingi (e se lo fai, devi aggiungere il flag --force come ha detto Angry Dan).
Shathur

doppure dropè il comando per rimuovere i commit dalla cronologia.
Carrello abbandonato

5

Per eliminare completamente i commit, ora c'è una nuova opzione dropper i rebase interattivi di git. Prima corsa:

git rebase -i HEAD~4

Quindi sostituire pickcon dropper i commit da eliminare:

pick 2f05aba ... #will be preserved
drop 3371cec ... #will be dropped
drop daed25c ... #will be dropped
pick e2b2a84 ... #will be preserved

Questo ha funzionato su Fedora per me con la seguente versione:

$ git version
git version 2.21.0

2

Squash è utile quando vuoi generare un elenco di commit uniti sotto un unico hash, ma se stai cercando di prendere tre commit separati e avere un output finale che sembra essere un singolo commit, ti consiglio fixup

git rebase -i HEAD~4

pick 2f05aba ... will be preserved
fixup 3371cec ... will be merged with daed25c
fixup daed25c ... will be merged with e2b2a84
pick e2b2a84 .. will include 3371cec and daed25c, but only the commit message of e2b2a84

È possibile trovare ulteriori informazioni nell'elenco dei comandi dell'interfaccia utente rebase interattiva.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.