Unterschied zwischen Git Pull und Git Pull - Basis

311

Ich habe vor einiger Zeit angefangen, Git zu verwenden und verstehe die Feinheiten nicht ganz. Meine grundlegende Frage hier ist, den Unterschied zwischen a git pullund herauszufinden git pull --rebase, da das Hinzufügen der --rebaseOption nichts ganz anderes zu tun scheint: nur ein Ziehen.

Bitte helfen Sie mir, den Unterschied zu verstehen.

Rndm
quelle

Antworten:

326

git pull= git fetch+ git mergegegen Tracking Upstream Branch

git pull --rebase= git fetch+ git rebasegegen Tracking Upstream Branch

Wenn Sie wissen möchten, wie git mergeund sich git rebaseunterscheiden, lesen Sie dies .

mvp
quelle
12
Es ist erwähnenswert, dass das Sprichwort git pull --rebasedasselbe ist git fetchund git rebaseim Grunde so ist, wie es ist, aber es ist nicht genau semantisch äquivalent. Es gibt einige Unterschiede, von denen einige hier erläutert werden. gitolite.com/git-pull--rebase
w0rp
8
Es ist das, was ich als "bequeme Lüge" bezeichnen würde, um einen Satz von Scott Meyers auszuleihen. Es ist eine gute Möglichkeit, es trotzdem zu erklären.
w0rp
Sehr kurz. Ich kann den Unterschied nicht verstehen. Was ist so wichtig fetch?
Grün
240

Manchmal haben wir einen Upstream, der einen Zweig, von dem wir abhängig sind, neu basiert / zurückgespult hat. Dies kann ein großes Problem sein und zu chaotischen Konflikten führen, wenn wir nachgelagert sind.

Die Magie ist git pull --rebase

Ein normaler Git-Pull ist im Großen und Ganzen so etwas (in all diesen Beispielen verwenden wir eine Fernbedienung namens origin und einen Zweig namens foo):

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

Auf den ersten Blick könnte man denken, dass ein Git Pull - Rebase genau das tut:

git fetch origin
git rebase origin/foo

Dies hilft jedoch nicht, wenn die Upstream-Rebase ein "Squashing" beinhaltet (was bedeutet, dass sich die Patch-IDs der Commits geändert haben, nicht nur ihre Reihenfolge).

Was bedeutet, dass Git Pull - Rebase ein bisschen mehr als das tun muss. Hier ist eine Erklärung, was es tut und wie.

Angenommen, Ihr Ausgangspunkt ist folgender:

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

Die Zeit vergeht und Sie haben einige Verpflichtungen zusätzlich zu Ihrem eigenen "foo" eingegangen:

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

In einem Anfall von unsozialer Wut hat der vorgelagerte Betreuer nicht nur sein "Foo" neu begründet, sondern sogar ein oder zwei Kürbisse verwendet. Seine Commit-Kette sieht jetzt so aus:

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

Ein Git-Pull an diesem Punkt würde zu Chaos führen. Sogar ein Idiot holen; git rebase origin / foo würde es nicht schneiden, da Commits "b" und "c" auf der einen Seite und Commit "b + c" auf der anderen Seite zu Konflikten führen würden. (Und ähnlich mit d, e und d + e).

Was git pull --rebasein diesem Fall bedeutet, ist:

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

Dies gibt Ihnen:

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

Möglicherweise erhalten Sie immer noch Konflikte, aber es handelt sich um echte Konflikte (zwischen p / q / r und a / b + c / d + e / f) und nicht um Konflikte, die durch b / c-Konflikte mit b + c usw. verursacht werden.

Antwort von (und leicht modifiziert):
http://gitolite.com/git-pull--rebase

Mauri Lopez
quelle
9
Dies ist die beste Antwort. Möglicherweise möchten Sie das Endergebnis in ändern, a---b+c---d+e---f---p'---q'---r' (foo)da die Basis Hashes ändert.
Bastien
22
Diese Antwort wurde wörtlich von gitolite.com/git-pull--rebase kopiert und eingefügt und sollte die Zuordnung gemäß der Lizenz auf dieser Seite enthalten.
Wildcard
Dies ist eine großartige Erklärung. Aber ich hatte eine Situation, in der ich mich verpflichtet hatte A, und ich schickte eine PR an das vorgelagerte Repo, die akzeptiert wurde. Als ich dann git pull --rebasegegen das Upstream-Repo war, bekam ich kein neues A'Commit über das gezogene Upstream-Repo. Tatsächlich A'gab es überhaupt keine . Liegt das daran, dass Aes in das System integriert wurde? Oder liegt es daran, dass es keinen Unterschied zwischen dem Upstream und meiner neu basierten Version gab?
CMCDragonkai
Ich gehe gerade das Git-Tutorial durch und habe diese Antwort verwendet, um a besser zu verstehen git pull --rebase. Eine Sache, die mich in dieser hypothetischen Situation verwirrt, ist, dass der vorgelagerte Betreuer die Projekthistorie geändert hat, die bereits in die Repositorys der lokalen Entwickler gezogen wurde. Ist das nicht nur schlechte Praxis im Allgemeinen? Wenn er Commits quetschen / den Verlauf neu schreiben wollte, sollte dies vor der Integration in das zentrale Repository geschehen sein, um diese Art von Konflikten zu vermeiden.
bmcentee148
44

Angenommen, Sie haben zwei Commits in der lokalen Niederlassung:

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

Nach "git pull" wird sein:

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

Nach "git pull --rebase" gibt es keinen Zusammenführungspunkt G. Beachten Sie, dass D und E unterschiedliche Commits werden:

A---B---C---F---D'---E'   master, origin/master
Deqing
quelle
1
ist es nicht A --- B --- C --- D '--- E' - F?
prgmrDev
5
@prgmrDev Warum sollten D und E vor F eingefügt werden?
Jon
1
Ist es nicht genau das, was es git rebasetut? Aber wir reden darüber git pull --rebase. Und das sind verschiedene Dinge.
Grün
10

Im einfachsten Fall keine Kollisionen

  • mit rebase: Rebasing Ihre lokale Commits ontop von Remote - Head und ist nicht erstellen merge / Merge - Commit
  • ohne / normal: führt zusammen und erstellt ein Zusammenführungs-Commit

Siehe auch:

man git-pull

Genauer gesagt führt git pull git fetch mit den angegebenen Parametern aus und ruft git merge auf, um die abgerufenen Verzweigungsköpfe mit dem aktuellen Zweig zusammenzuführen. Mit --rebase wird git rebase anstelle von git merge ausgeführt.

Siehe auch:
Wann sollte ich git pull --rebase verwenden?
http://git-scm.com/book/en/Git-Branching-Rebasing

drahnr
quelle
3
Und bei Kollisionen?
Rndm
1
Sie werden aufgefordert, sie manuell aufzulösen und dann - fahren Sie mit rebase fort: git sdd modified-file; git rebase --continueoder merge: git add modified-file; git commit;wo modified-fileist Ihre lokale Datei, die Sie manuell geändert haben / mergetool
drahnr
Was ist das Besondere daran fetch? Warum haben sie zwei rebaseFlows erstellt? 1) git rebaseund 2) git pull --rebase?
Grün
7

Dazu ist es wichtig, den Unterschied zwischen Merge und Rebase zu verstehen.

Bei Rebases sollten Änderungen von der Spitze der Hierarchie nach unten und bei Zusammenführungen nach oben zurückfließen.

Weitere Informationen finden Sie unter http://www.derekgourlay.com/archives/428

Sagar Mody
quelle
Ich denke, dass Ihre Antwort eine viel einfachere Erklärung bietet, die bei den übrigen Antworten oben nicht offensichtlich ist. Vielen Dank.
Aaron C