Git
schiacciamento
Ricerca…
Osservazioni
Cos'è lo schiacciamento?
Lo schiacciamento è il processo di prendere più commit e combinarli in un singolo commit che incapsula tutte le modifiche rispetto ai commit iniziali.
Rami schiacciati e remoti
Prestare particolare attenzione quando lo schiacciamento si verifica su un ramo che sta monitorando un ramo remoto; se schiacci un commit che è già stato spinto su un ramo remoto, i due rami saranno divergenti, e dovrai usare git push -f
per forzare le modifiche sul ramo remoto. Tieni presente che questo può causare problemi agli altri utenti che monitorano quel ramo remoto , quindi devi usare cautela quando i commit forzati di forza su repository pubblici o condivisi.
Se il progetto è ospitato su GitHub, è possibile abilitare la "protezione forzata push" su alcuni rami, come master
, aggiungendolo a Settings
- Branches
- Protected Branches
.
Squash Recits recenti senza rebasing
Se vuoi schiacciare la precedente x
commit in una sola, puoi usare i seguenti comandi:
git reset --soft HEAD~x
git commit
Sostituendo x
con il numero di commit precedenti che si desidera includere nel commit schiacciato.
Ricorda che questo creerà un nuovo commit, essenzialmente dimenticando le informazioni relative ai precedenti x
commit compreso il loro autore, messaggio e data. Probabilmente vuoi prima copiare e incollare un messaggio di commit esistente.
Lo schiacciamento si verifica durante il rebase
I commit possono essere schiacciati durante un git rebase
. Si consiglia di comprendere la ridefinizione prima di tentare di schiacciare i commit in questo modo.
Determina il commit da cui vorresti rebase e prendi nota del suo hash commit.
Esegui
git rebase -i [commit hash]
.In alternativa, è possibile digitare
HEAD~4
invece di un hash di commit, per visualizzare l'ultima commit e altri 4 commit prima dell'ultima.Nell'editor che si apre quando si esegue questo comando, determinare quali commit si desidera schiacciare. Sostituisci il
pick
all'inizio di quelle linee con losquash
per schiacciarle nel commit precedente.Dopo aver selezionato quali commit si vorrebbe schiacciare, ti verrà richiesto di scrivere un messaggio di commit.
Registrazione si impegna a determinare dove rebase
> git log --oneline
612f2f7 This commit should not be squashed
d84b05d This commit should be squashed
ac60234 Yet another commit
36d15de Rebase from here
17692d1 Did some more stuff
e647334 Another Commit
2e30df6 Initial commit
> git rebase -i 36d15de
A questo punto il tuo editor di scelta si apre dove puoi descrivere cosa vuoi fare con i commit. Git fornisce aiuto nei commenti. Se lo lasci come è, allora non succederà nulla perché ogni commit verrà mantenuto e il loro ordine sarà lo stesso di quello precedente al rebase. In questo esempio applichiamo i seguenti comandi:
pick ac60234 Yet another commit
squash d84b05d This commit should be squashed
pick 612f2f7 This commit should not be squashed
# Rebase 36d15de..612f2f7 onto 36d15de (3 command(s))
#
# 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
Git log dopo aver scritto il messaggio di commit
> git log --oneline
77393eb This commit should not be squashed
e090a8c Yet another commit
36d15de Rebase from here
17692d1 Did some more stuff
e647334 Another Commit
2e30df6 Initial commit
Autosquash: codice di commit che si desidera schiacciare durante un rebase
Data la seguente cronologia, immagina di apportare una modifica che desideri schiacciare nel commit bbb2222 A second commit
:
$ git log --oneline --decorate
ccc3333 (HEAD -> master) A third commit
bbb2222 A second commit
aaa1111 A first commit
9999999 Initial commit
Una volta apportate le modifiche, è possibile aggiungerle all'indice come al solito, quindi impegnarle utilizzando l'argomento --fixup
con un riferimento al commit a cui si desidera eseguire lo schiacciamento:
$ git add .
$ git commit --fixup bbb2222
[my-feature-branch ddd4444] fixup! A second commit
Questo creerà un nuovo commit con un messaggio di commit che Git può riconoscere durante un rebase interattivo:
$ git log --oneline --decorate
ddd4444 (HEAD -> master) fixup! A second commit
ccc3333 A third commit
bbb2222 A second commit
aaa1111 A first commit
9999999 Initial commit
Successivamente, --autosquash
un rebase interattivo con l'argomento --autosquash
:
$ git rebase --autosquash --interactive HEAD~4
Git ti proporrà di schiacciare il commit effettuato con commit --fixup
nella posizione corretta:
pick aaa1111 A first commit
pick bbb2222 A second commit
fixup ddd4444 fixup! A second commit
pick ccc3333 A third commit
Per evitare di dover digitare --autosquash
su ogni rebase, puoi abilitare questa opzione per impostazione predefinita:
$ git config --global rebase.autosquash true
Lo squashing si impegna durante l'unione
Puoi usare git merge --squash
per schiacciare le modifiche introdotte da un ramo in un singolo commit. Nessun commit effettivo verrà creato.
git merge --squash <branch>
git commit
Questo è più o meno equivalente all'utilizzo di git reset
, ma è più conveniente quando le modifiche che vengono incorporate hanno un nome simbolico. Confrontare:
git checkout <branch>
git reset --soft $(git merge-base master <branch>)
git commit
Autosquash e correzioni
Quando si eseguono modifiche è possibile specificare che il commit verrà in seguito schiacciato su un altro commit e questo può essere fatto in questo modo,
git commit --squash=[commit hash of commit to which this commit will be squashed to]
Si potrebbe anche usare, --fixup=[commit hash]
alternativa alla correzione.
È anche possibile utilizzare le parole dal messaggio di commit anziché l'hash del commit, in questo modo
git commit --squash :/things
dove verrà utilizzato il commit più recente con la parola "cose".
Il messaggio di questi commit inizia con 'fixup!'
o 'squash!'
seguito dal resto del messaggio di commit a cui questi verranno commessi.
Quando si usa il flag --autosquash --autosquash
deve essere usato per usare la funzione autosquash / fixup.