Risposte:
Entrambi git merge --squash
e git rebase --interactive
possono produrre un commit "schiacciato".
Ma servono a scopi diversi.
produrrà un commit schiacciato sul ramo di destinazione, senza contrassegnare alcuna relazione di unione.
(Nota: non produce subito un commit: è necessario un ulteriore git commit -m "squash branch"
)
Ciò è utile se si desidera eliminare completamente il ramo di origine, passando da (schema preso dalla domanda SO ):
git checkout stable
X stable
/
a---b---c---d---e---f---g tmp
per:
git merge --squash tmp
git commit -m "squash tmp"
X-------------------G stable
/
a---b---c---d---e---f---g tmp
e quindi eliminando il tmp
ramo.
Nota: git merge
ha --commit
un'opzione , ma non può essere utilizzata con --squash
. Non è mai stato possibile utilizzare --commit
e --squash
insieme.
Da Git 2.22.1 (Q3 2019), questa incompatibilità è resa esplicita:
Vedi commit 1d14d0c (24 maggio 2019) di Vishal Verma ( reloadbrain
) .
(Unito da Junio C Hamano - gitster
- in commit 33f2790 , 25 lug 2019)
merge
: rifiuta--commit
con--squash
In precedenza, quando
--squash
veniva fornito, 'option_commit
' veniva lasciato cadere silenziosamente. Ciò avrebbe potuto sorprendere un utente che ha cercato di ignorare il comportamento senza commit di squash usando--commit
esplicitamente.
git/git
builtin/merge.c#cmd_merge()
ora include:
if (option_commit > 0)
die(_("You cannot combine --squash with --commit."));
ripete alcuni o tutti i tuoi commit su una nuova base, permettendoti di schiacciare (o più recentemente "aggiustare", vedi questa domanda SO ), andando direttamente a:
git checkout tmp
git rebase -i stable
stable
X-------------------G tmp
/
a---b
Se scegli di eliminare tutti i commit tmp
(ma, al contrario merge --squash
, puoi scegliere di rigiocarne alcuni e schiacciarne altri).
Quindi le differenze sono:
squash
non tocca il ramo di origine ( tmp
qui) e crea un unico commit dove vuoi.rebase
ti permette di continuare sullo stesso ramo di origine (ancora tmp
) con:
tmp
commit compressi insieme.
G
non rappresenterà lo stesso contenuto di g
, a causa delle modifiche introdotte da X
.
git merge --no-ff temp
invece di git merge --squash temp
, allora ottieni una cronologia più complessa, ma puoi anche fare cose come git revert e
, molto più facilmente. È una storia disordinata, ma onesta e pragmatica, e il ramo principale rimane ancora abbastanza pulito.
git bisect
o git blame
se usato troppo spesso (come in git pull --no-ff
: stackoverflow.com/questions/12798767/… ). Non c'è un approccio in ogni caso, che è il motivo per cui questo articolo ha descritto tre ( stackoverflow.com/questions/9107861/... )
Unisci commit: conserva tutti i commit nel tuo ramo e li interfoglia con i commit sul ramo base
Unisci zucca: mantiene le modifiche ma omette i singoli commit dalla cronologia
Rebase: questo sposta l'intero ramo delle caratteristiche per iniziare sulla punta del ramo principale, incorporando efficacemente tutti i nuovi commit nel master
Maggiori informazioni qui
Unisci squash unisce un albero (una sequenza di commit) in un singolo commit. Cioè, comprime tutte le modifiche apportate in n commit in un unico commit.
Rebasing è re-basing, ovvero scegliere una nuova base (commit parent) per un albero. Forse il termine mercuriale per questo è più chiaro: lo chiamano trapianto perché è proprio questo: scegliere un nuovo terreno (impegno del genitore, radice) per un albero.
Quando esegui un rebase interattivo, ti viene data la possibilità di schiacciare, scegliere, modificare o saltare i commit che stai per rebase.
Spero fosse chiaro!
Cominciamo dal seguente esempio:
Ora abbiamo 3 opzioni per unire le modifiche del ramo della funzione nel ramo principale :
Unisci commit
manterrà la cronologia di tutti i commit del ramo funzione e li sposta nel ramo master
Aggiungerà un ulteriore commit fittizio.
Riempi e unisci Aggiungerà
tutta la cronologia dei commit del ramo delle funzioni nella parte anteriore del ramo principale
NON aggiungerà un commit fittizio aggiuntivo.
Schiaccia e unisci
Raggruppa tutti i commit delle diramazioni in un unico commit, quindi aggiungilo nella parte anteriore del branch master
Aggiungerà un commit fittizio aggiuntivo.
Di seguito puoi trovare come sarà il ramo principale dopo ognuno di essi.
In tutti i casi:
possiamo ELIMINARE in sicurezza il ramo delle funzioni .
G
vienec--d--e--f--g
schiacciato insieme?