Come eliminare i commit in Git per mantenere pulita la cronologia
Quando lavori con Git, è una buona idea impegnarsi spesso, così puoi sempre tornare allo stato del codice se sbagli. Tuttavia, non è sempre una buona idea eseguire tutte queste mini-modifiche nel ramo principale. Rende la storia disordinata e difficile da seguire.
Git fornisce un modo per schiacciare un mucchio di commit usando il comando rebase. Dopo aver apportato localmente le modifiche a un particolare file o per una particolare funzionalità, puoi sempre utilizzare il metodo squash per combinare le modifiche insieme prima di eseguire il commit nel ramo principale. Questo aiuterà gli altri a capire meglio le tue modifiche.
Avvertenza: anche se puoi estrarre da repository esterni e eseguire commit di squash insieme, è una cattiva idea. Può creare conflitti e confusione. Evita di cambiare la cronologia che è già pubblica. Attieniti solo a schiacciare i commit che sono locali per il tuo lavoro.
Esaminiamo un caso di esempio.
Supponiamo di avere due file a.py e b.pi. Esaminiamo prima il processo di creazione dei file e di apportare le modifiche:
$ mkdir mioprogetto$ cd mioprogetto/
$ git init
$ echo "print("ciao A")" > a.pi
$ git add -A && git commit -m "Aggiunto a.pi"
$ echo "print("ciao B")" > b.pi
$ git add -A && git commit -m "Aggiunto b.pi"
$ echo "print("ciao BB")" > b.pi
$ git add -A && git commit -m "b.py Modifica 1"
$ echo "print("ciao BBB")" > b.pi
$ git add -A && git commit -m "b.py Modifica 2"
Se controlliamo la cronologia dei commit, vedremo quanto segue:
$ git log --oneline --graph --decorate* dfc0295 (TESTA -> master) b.py Modifica 2
* ce9e582 b.py Modifica 1
* 7a62538 Aggiunto b.pi
* 952244a Aggiunto a.pi
Dopo che abbiamo finito con il nostro lavoro, decidiamo di mettere tutte le modifiche al b.py in un singolo commit per chiarezza. Contiamo che ci siano 3 commit su b.py dalla TESTA. Diamo il seguente comando:
git rebase -i TESTA~3L'opzione -i dice a Git di usare la modalità interattiva.
Dovrebbe apparire una finestra sul tuo editor di testo Git:
pick 7a62538 Aggiunto b.piscegli ce9e582 b.py Modifica 1
scegli dfc0295 b.py Modifica 2
# Ribasare 952244a… dfc0295 su 952244a (3 comandi)
#
# Comandi:
# p, scegli = usa commit
# r, reword = usa commit, ma modifica il messaggio di commit
# e, edit = usa commit, ma fermati per la modifica
# s, squash = usa commit, ma si fonde con il commit precedente
# f, fixup = come "squash", ma scarta il messaggio di registro di questo commit
# x, exec = esegui il comando (il resto della riga) usando la shell
#
# Queste righe possono essere riordinate; vengono eseguiti dall'alto verso il basso.
#
# Se rimuovi una riga qui QUESTO COMMIT SARÀ PERSO.
#
# Tuttavia, se rimuovi tutto, il rebase verrà interrotto.
#
# Nota che i commit vuoti sono commentati
~
I commit sono elencati in ordine cronologico in alto dal primo al più recente. Puoi scegliere quale commit "scegliere" e quale commit da squash. Per semplicità, sceglieremo il primo commit e ci schiacceremo il resto. Quindi modificheremo il testo in questo modo:
pick 7a62538 Aggiunto b.pizucca ce9e582 b.py Modifica 1
zucca dfc0295 b.py Modifica 2
# Ribasare 952244a… dfc0295 su 952244a (3 comandi)
#
# Comandi:
# p, scegli = usa commit
# r, reword = usa commit, ma modifica il messaggio di commit
# e, edit = usa commit, ma fermati per la modifica
# s, squash = usa commit, ma si fonde con il commit precedente
# f, fixup = come "squash", ma scarta il messaggio di registro di questo commit
# x, exec = esegui il comando (il resto della riga) usando la shell
#
# Queste righe possono essere riordinate; vengono eseguiti dall'alto verso il basso.
#
# Se rimuovi una riga qui QUESTO COMMIT SARÀ PERSO.
#
# Tuttavia, se rimuovi tutto, il rebase verrà interrotto.
#
# Nota che i commit vuoti sono commentati
Non appena salvi e chiudi il file di testo, dovrebbe apparire un'altra finestra di testo simile a questa:
# Questa è una combinazione di 3 commit.# Il messaggio del primo commit è:
Aggiunto b.pi
# Questo è il secondo messaggio di commit:
b.py Modifica 1
# Questo è il terzo messaggio di commit:
b.py Modifica 2
# Per favore inserisci il messaggio di commit per le tue modifiche. Linee che iniziano
# con '#' verrà ignorato e un messaggio vuoto interrompe il commit.
#
# Data: Ven 30 Mar 21:09:43 2018 -0700
#
# rebase in corso; su 952244a
# Stai attualmente modificando un commit durante il rebase del ramo 'master' su '952244a'.
#
# Modifiche da eseguire:
# nuovo file: b.pi
#
Salva e chiudi anche questo file. Dovresti vedere qualcosa del genere:
$ git rebase -i HEAD~3[TESTA staccata 0798991] Aggiunto b.pi
Data: Ven Mar 30 21:09:43 2018 -0700
1 file modificato, 1 inserimento(+)
crea modalità 100644 b.pi
Arbitri/teste/master ribasati e aggiornati con successo.
Se controlli ora la cronologia dei commit:
$ git log --oneline --graph --decorate* 0798991 (TESTA -> master) Aggiunto b.pi
* 952244a Aggiunto a.pi
Tutti i commit per b.py sono stati schiacciati in un commit. Puoi verificare guardando il b.py file:
$ gatto b.piprint("ciao BBB")
Ha il contenuto della Modifica 2.
Conclusione
Il rebase è un comando potente. Può aiutarti a mantenere pulita la tua cronologia. Ma evita di usarlo per commit già pubblici in quanto può causare conflitti e confusione. Usalo solo per il tuo repository locale.
Ulteriori studi:
- https://git-scm.com/docs/git-rebase
- https://git-scm.com/book/en/v2/Git-Branching-Rebasing
- https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History