Qual è la differenza tra git merge
e git rebase
?
Qual è la differenza tra git merge
e git rebase
?
Risposte:
Supponiamo che in origine erano 3 commit, A
, B
, C
:
Quindi lo sviluppatore Dan ha creato il commit D
e lo sviluppatore Ed ha creato il commit E
:
Ovviamente, questo conflitto dovrebbe essere risolto in qualche modo. Per questo, ci sono 2 modi:
MERGE :
Entrambi eseguono il commit D
e E
sono ancora qui, ma creiamo un commit di unione M
che eredita le modifiche da entrambi D
e E
. Tuttavia, questo crea una forma di diamante , che molte persone trovano molto confusa.
REBASE :
Creiamo commit R
, il cui contenuto effettivo è identico a quello di merge commit M
sopra. Ma ci liberiamo del commit E
, come se non fosse mai esistito (indicato da punti - linea di fuga). A causa di questa cancellazione, E
dovrebbe essere locale allo sviluppatore Ed e non avrebbe mai dovuto essere trasferito in nessun altro repository. Il vantaggio di rebase è che si evita la forma di un diamante e la storia rimane in linea retta - la maggior parte degli sviluppatori lo adora!
git merge
non interleave si impegna (ma potrebbe apparire così guardando git log
). Invece, git merge
mantiene intatte entrambe le storie di sviluppo di Dan ed Ed, come è stato visto da ogni punto di vista alla volta. git rebase
sembra che Dan ci abbia lavorato prima, ed Ed lo ha seguito. In entrambi i casi (unione e rebase), l'albero dei file risultante effettivo è assolutamente identico.
Adoro questo estratto di 10 cose che odio di Git (fornisce una breve spiegazione di rebase nel suo secondo esempio):
3. Documentazione scadente
Le pagine man sono un'onnipotente "fottuta" 1 . Descrivono i comandi dal punto di vista di un informatico, non di un utente. Caso in questione:
git-push – Update remote refs along with associated objects
Ecco una descrizione per l'uomo:
git-push – Upload changes from your local repository into a remote repository
Aggiornamento, un altro esempio: (grazie cgd)
git-rebase – Forward-port local commits to the updated upstream head
Traduzione:
git-rebase – Sequentially regenerate a series of commits so they can be applied directly to the head node
E poi abbiamo
git-merge - Join two or more development histories together
che è una buona descrizione.
1. senza censure nell'originale
Personalmente non trovo molto utile la tecnica del diagramma standard: le frecce sembrano sempre indicare la direzione sbagliata per me. (Indicano generalmente il "genitore" di ogni commit, che finisce per essere indietro nel tempo, il che è strano).
Per spiegarlo a parole:
Per motivi che non capisco, gli strumenti della GUI per Git non hanno mai fatto uno sforzo per presentare le storie di unione in modo più pulito, astraggendo le singole fusioni. Quindi, se si desidera una "cronologia pulita", è necessario utilizzare rebase.
Mi sembra di ricordare di aver letto post sul blog di programmatori che usano solo rebase e altri che non usano mai rebase.
Proverò a spiegarlo con un esempio di sole parole. Supponiamo che altre persone nel tuo progetto stiano lavorando sull'interfaccia utente e tu stia scrivendo documentazione. Senza rebase, la tua storia potrebbe assomigliare a:
Write tutorial
Merge remote-tracking branch 'origin/master' into fixdocs
Bigger buttons
Drop down list
Extend README
Merge remote-tracking branch 'origin/master' into fixdocs
Make window larger
Fix a mistake in howto.md
Cioè, le fusioni e l'interfaccia utente si impegnano nel mezzo dei commit della documentazione.
Se hai riformulato il codice su master invece di unirlo, sembrerebbe così:
Write tutorial
Extend README
Fix a mistake in howto.md
Bigger buttons
Drop down list
Make window larger
Tutti i tuoi commit sono in alto (i più recenti), seguiti dal resto della master
filiale.
( Dichiarazione di non responsabilità: sono l'autore del post "10 cose che odio di Git" a cui fa riferimento in un'altra risposta )
Mentre la risposta accettata e più votata è ottima, trovo inoltre utile cercare di spiegare la differenza solo a parole:
merge
rebase
riepilogo: quando possibile, rebase è quasi sempre migliore. Semplificare la reintegrazione nel ramo principale.
Perché? ➝ il tuo lavoro di funzionalità può essere presentato come un grande 'file patch' (aka diff) rispetto al ramo principale, senza dover 'spiegare' più genitori: almeno due, provenienti da una fusione, ma probabilmente molti altri, se presenti sono state diverse fusioni. A differenza delle fusioni, più rebase non si sommano. (un altro grande vantaggio)
Git rebase è più vicino a un'unione. La differenza in rebase è:
Ciò significa che tutti gli commit locali vengono spostati alla fine, dopo tutti gli commit remoti. Se hai un conflitto di unione, devi risolverlo anche tu.
Ho trovato un articolo davvero interessante su git rebase vs merge , pensato di condividerlo qui