Differenza tra git pull e git pull --rebase


311

Ho iniziato a usare git qualche tempo fa e non capisco perfettamente le complessità. La mia domanda di base qui è scoprire la differenza tra a git pulle git pull --rebase, poiché l'aggiunta --rebasedell'opzione non sembra fare qualcosa di molto diverso: fa solo un tiro.

Per favore aiutami a capire la differenza.



3
Possibile duplicato di git pull VS git fetch git rebase
TJ

Risposte:


326

git pull= git fetch+ git mergecontro il monitoraggio della diramazione a monte

git pull --rebase= git fetch+ git rebasecontro il monitoraggio della diramazione a monte

Se vuoi sapere come git mergee git rebasedifferire, leggi questo .


12
Vale la pena notare che dire git pull --rebaseè lo stesso git fetched git rebaseè sostanzialmente come è, ma non è esattamente semanticamente equivalente. Ci sono alcune differenze, alcune delle quali sono spiegate qui. gitolite.com/git-pull--rebase
w0rp

8
È quella che definirei una "comoda bugia" per prendere in prestito una frase di Scott Meyers. È un buon modo per spiegarlo a prescindere.
w0rp,

Molto brevemente Non riesco a capire la differenza. Cosa c'è di così importante fetch?
Green

240

A volte abbiamo un upstream che ha rinnovato / riavvolto un ramo da cui dipendiamo. Questo può essere un grosso problema - causando conflitti disordinati per noi se siamo a valle.

La magia è git pull --rebase

Un normale git pull è, in termini vaghi, qualcosa del genere (useremo un telecomando chiamato origin e un ramo chiamato foo in tutti questi esempi):

# assume current checked out branch is "foo"
git fetch origin
git merge origin/foo

A prima vista, potresti pensare che un git pull --rebase faccia proprio questo:

git fetch origin
git rebase origin/foo

Ma ciò non sarà d'aiuto se il rebase upstream implicasse qualche "schiacciamento" (il che significa che i patch-id degli commit sono cambiati, non solo il loro ordine).

Ciò significa che git pull --rebase deve fare un po 'di più. Ecco una spiegazione di cosa fa e come.

Diciamo che il tuo punto di partenza è questo:

a---b---c---d---e  (origin/foo) (also your local "foo")

Il tempo passa e hai fatto alcuni commit in cima al tuo "pippo":

a---b---c---d---e---p---q---r (foo)

Nel frattempo, in un impeto di rabbia antisociale, il manutentore a monte non ha solo riformato il suo "foo", ma ha anche usato uno o due squash. La sua catena di commit ora appare così:

a---b+c---d+e---f  (origin/foo)

A questo punto un tiro di sbalzo provocherebbe il caos. Perfino un git fetch; git rebase origin / foo non lo taglierebbe, perché commette "b" e "c" da un lato e commettere "b + c" dall'altro, sarebbe in conflitto. (E allo stesso modo con d, e, d + e).

Cosa git pull --rebasesignifica, in questo caso,:

git fetch origin
git rebase --onto origin/foo e foo

Questo ti dà:

 a---b+c---d+e---f---p'---q'---r' (foo)

Potresti ancora avere conflitti, ma saranno veri e propri conflitti (tra p / q / r e a / b + c / d + e / f) e non conflitti causati da b / c in conflitto con b + c, ecc.

Risposta tratta da (e leggermente modificata):
http://gitolite.com/git-pull--rebase


9
Questa è la risposta migliore È possibile che si desideri modificare il risultato finale a---b+c---d+e---f---p'---q'---r' (foo)poiché rebase modifica gli hash.
Bastien,

22
Questa risposta è stata copiata e incollata alla lettera da gitolite.com/git-pull--rebase e dovrebbe includere l'attribuzione secondo la licenza in quella pagina.
Wildcard il

Questa è un'ottima spiegazione Ma ho avuto una situazione in cui mi ero impegnato Ae ho inviato un PR al repository upstream che è stato accettato. Quindi, quando l'ho fatto git pull --rebasecontro il repository upstream, non ho ricevuto un nuovo A'commit in aggiunta al repository upstream pull. In realtà non A'esisteva affatto. È perché è Astato unito nel sistema? O è perché non c'era differenza tra la versione upstream e la mia reimpostata sulla versione?
CMCDragonkai,

Attualmente sto seguendo il tutorial Git e sto usando questa risposta per capire ulteriormente a git pull --rebase. Ma una cosa che mi confonde in questa ipotetica situazione è che il manutentore a monte ha cambiato la storia del progetto che è già stata inserita nei repository degli sviluppatori locali. Non è solo una cattiva pratica in generale? Se avesse voluto eseguire il commit / riscrittura della cronologia, avrebbe dovuto essere fatto prima di integrarlo nel repository centrale per evitare questo tipo di conflitti.
bmcentee148,

44

Supponiamo di avere due commit nella filiale locale:

      D---E master
     /
A---B---C---F origin/master

Dopo "git pull", sarà:

      D--------E  
     /          \
A---B---C---F----G   master, origin/master

Dopo "git pull --rebase", non ci sarà nessun punto di unione G. Nota che D ed E diventano diversi commit:

A---B---C---F---D'---E'   master, origin/master

1
non è A --- B --- C --- D '--- E' - F?
prgmrDev

5
@prgmrDev Perché D ed E dovrebbero essere inseriti prima di F?
Jon

1
Non è esattamente cosa git rebasefa? Ma stiamo parlando git pull --rebase. E sono cose diverse.
Verde,

10

Nel caso più semplice senza collisioni

  • con rebase: ripristina il commit locale in cima a HEAD remoto e non crea un commit merge / merge
  • senza / normale: unisce e crea un commit di unione

Guarda anche:

man git-pull

Più precisamente, git pull esegue git fetch con i parametri indicati e chiama git merge per unire le teste di ramo recuperate nel ramo corrente. Con --rebase, esegue git rebase invece di git merge.

Vedi anche:
Quando dovrei usare git pull --rebase?
http://git-scm.com/book/en/Git-Branching-Rebasing


3
E in caso di collisioni?
Rndm,

1
Ti verrà chiesto di risolverli manualmente e poi - continua con rebase: git sdd modified-file; git rebase --continueo unisci: git add modified-file; git commit;dov'è il modified-filetuo file locale che hai modificato manualmente / mergetool
drahnr

Cosa c'è di così speciale fetch? Perché hanno creato due rebaseflussi? 1) git rebasee 2) git pull --rebase?
Green,

7

Per questo è importante capire la differenza tra Merge e Rebase.

I riposizionamenti sono come i cambiamenti dovrebbero passare dall'alto verso il basso della gerarchia verso il basso e le fusioni sono come rifluiscono verso l'alto.

Per i dettagli, consultare: http://www.derekgourlay.com/archives/428


Penso che la tua risposta offra una spiegazione molto più semplice che non è ovvia sul resto delle risposte di cui sopra. Grazie.
Aaron C,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.