Spiegazione di Git Squash

Cos'è Git Squash?

Una delle cose che gli sviluppatori sentono abbastanza spesso riguardo alle loro richieste pull è qualcosa del tipo "Mi sembra buono, per favore schiaccia e unisci". La parte divertente è che non esiste un comando simile git squash(a meno che non si crei un alias).

Per squashtirare richiesta mezzi comunemente per compattare tutti i commit di questa richiesta in uno (raramente altro numero) per renderlo più concisa, leggibile e non inquinare la storia di ramo principale. Per ottenere ciò, uno sviluppatore deve utilizzare la modalità interattiva del comando Git Rebase.

Molto spesso, quando sviluppi una nuova funzionalità, ti ritrovi con diversi commit intermittenti nella tua cronologia: dopotutto, sviluppi in modo incrementale. Potrebbero essere solo alcuni errori di battitura o passaggi per la soluzione finale. La maggior parte delle volte non è utile avere tutti questi commit nella versione pubblica finale del codice, quindi è più vantaggioso averli compressi tutti in una versione unica e finale.

Quindi supponiamo di avere il seguente log di commit nel ramo che desideri unire come parte della richiesta pull:

$ git log --pretty=oneline --abbrev-commit 30374054 Add Jupyter Notebook stub to Data Science Tools 8490f5fc Minor formatting and Punctuation changes 3233cb21 Prototype for Notebook page

Chiaramente preferiremmo avere un solo commit qui, poiché non c'è alcun vantaggio nel sapere cosa abbiamo iniziato a scrivere e quali errori di battitura abbiamo corretto in seguito. Solo il risultato finale è importante.

Quindi, ciò che facciamo è avviare una sessione rebase interattivo dagli attuali TESTA (impegnarsi 30.374.054 ) di commettere 3233cb21 , con l'intenzione di unire le 3 ultimi commit in uno:

$ git rebase -i HEAD~3

Ciò aprirà un editor con qualcosa di simile al seguente:

pick 3233cb21 Prototype for Notebook page pick 8490f5fc Minor formatting and Punctuation changes pick 30374054 Add Jupyter Notebook to Data Science Tools # Rebase # # Commands: # p, pick = use commit # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # f, fixup = like "squash", but discard this commit's log message # x, exec = run command (the rest of the line) using shell # # These lines can be re-ordered; they are executed from top to bottom. # # If you remove a line here THAT COMMIT WILL BE LOST. # # However, if you remove everything, the rebase will be aborted. # # Note that empty commits are commented out

Come sempre, Git ci fornisce un messaggio di aiuto molto carino in cui puoi vedere l' squashopzione che stiamo cercando.

Attualmente le istruzioni per il rebase interattivo dicono a pickogni commit specificato e conservano il messaggio di commit corrispondente. Cioè, non cambiare nulla. Ma alla fine vogliamo avere un solo commit.

Quindi puoi semplicemente modificare il testo nel tuo editor sostituendolo pickcon squash(o semplicemente s) il prossimo anno ogni commit di cui vogliamo eliminare e salvare / uscire dall'editor. Potrebbe assomigliare a questo:

s 3233cb21 Prototype for Notebook page s 8490f5fc Minor formatting and Punctuation changes pick 30374054 Add Jupyter Notebook to Data Science Tools

Quando chiudi l'editor dopo aver salvato questa modifica, verrà riaperto immediatamente e ti suggerirà di scegliere e riformulare quei messaggi di commit. Qualcosa come questo:

# This is a combination of 3 commits. # The first commit's message is: Prototype for Notebook page # This is the 2nd commit message: Minor formatting and Punctuation changes # This is the 3rd commit message: Add Jupyter Notebook to Data Science Tools # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit.

A questo punto puoi eliminare tutti i messaggi che non desideri vengano inclusi nella versione finale del commit. Puoi anche riformularli o semplicemente scrivere un messaggio di commit da zero.

Ricorda solo che la nuova versione includerà tutte le linee che non iniziano con il #personaggio. Ancora una volta, salva ed esci dal tuo editor.

Il tuo terminale ora dovrebbe mostrare un messaggio di successo incluso Successfully rebased and updated e il log git dovrebbe mostrare una cronologia piacevole e compatta con un solo commit. Tutti i commit intermedi sono andati e siamo pronti per la fusione!

Avviso sulla mancata corrispondenza della cronologia dei commit locale e remoto

Questa operazione è leggermente pericolosa se il tuo ramo è già pubblicato in un repository remoto - dopotutto stai modificando la cronologia dei commit. Quindi è meglio eseguire l'operazione di squash su un ramo locale prima di eseguire il push .

A volte, verrà già inviato: come creeresti una richiesta pull dopo tutto? In questo caso dovrai forzare le modifiche sul ramo remoto dopo aver eseguito lo squash, poiché la cronologia locale e la cronologia del ramo nel repository remoto sono diverse:

$ git push origin +my-branch-name

Fai del tuo meglio per assicurarti di essere l'unico a utilizzare questo ramo remoto a questo punto, altrimenti renderai la vita dell'altro sviluppatore più difficile quando hanno una mancata corrispondenza della cronologia. Ma poiché lo schiacciamento viene solitamente eseguito come operazione finale su un ramo prima di eliminarlo, di solito non è un problema così grande.