Beim Zusammenführen (einschließlich des Umbasierens, bei dem es sich um einen Spezialfall des wiederholten internen "Mergens" handelt), sind zwei "Köpfe" (zwei spezielle Zweigspitzen) beteiligt. Lassen Sie uns diese your-branch
anrufen und origin/their-branch
:
G - H -------- <-- HEAD=your-branch
/ \
... - E - F M <-- desired merge commit [requires manual merge]
\ /
I - J - K - L <-- origin/their-branch
Dieser Punkt häufig ist (und wenig überraschend) verwirrend, obwohl, wenn wie dies markiert deutlich genug.
machen es noch schlimmer, aber git verwendet --ours
und --theirs
an den beiden Kopf beziehen verpflichtet bei einer Zusammenführung, mit „uns“ ist diejenige, die Sie auf waren (Commit H
), wenn Sie git merge
lief, und „ihre“ zu sein , nun, ihre (commit L
). Aber wenn du eine Rebase machst, sind die beiden Köpfe umgedreht, so dass "unser" der Kopf ist, den du auf-zu-ie, ihren aktualisierten Code, umnimmst - und "ihr" das Commit ist, das du gerade umlegst, dh dein eigener Code.
Dies ist, weil Rebase tatsächlich eine Reihe von Cherry-Pick-Operationen verwendet. Sie beginnen mit der gleichen Bild:
G - H <-- HEAD=your-branch
/
... - E - F
\
I - J - K - L <-- origin/their-branch
Was git hier tun muss, ist zu Kopie die Wirkung von Commits G
und H
, das heißt, begehen git cherry-pick
G
, dann es wieder tun mit H
zu begehen. Aber um das zu tun, git muss SchalterL
zunächst intern zu begehen (mit „frei stehenden HEAD“ -Modus):
G - H <-- your-branch
/
... - E - F
\
I - J - K - L <-- HEAD, origin/their-branch
Jetzt kann es beginnen, das Fütterungsmaterial Operation durch die Bäume zu vergleichen für verpflichtet F
und G
(Um zu sehen, was Sie geändert haben), dann vergleichen Sie F
vs L
(um zu sehen, ob einige Ihrer Arbeit bereits in L
ist) und nehmen Sie alle Änderungen nicht bereits in L
und fügen Sie es hinzu. Dies ist intern eine "Merge" -Operation.
G - H <-- your-branch
/
... - E - F G' <-- HEAD
\ /
I - J - K - L <-- origin/their-branch
Wenn die Zusammenführung nicht gut gehen, bleibt HEAD
noch bei L
begehen (weil G'
existiert begehen noch nicht). Also, ja, HEAD
ist der Chef ihrer Entwicklungsbranche - zumindest ist es gerade jetzt.
Sobald die Kopie G
existiert, obwohl, HEAD
bewegt zu G'
und git versucht, die Änderungen von H
, auf die gleiche Weise zu kopieren (diff G
vs H
, dann F
vs G'
diff und die Ergebnisse zusammenführen):
G - H <-- your-branch
/
... - E - F G' - H' <-- HEAD
\ /
I - J - K - L <-- origin/their-branch
noch einmal, wenn die Zusammenführung versagt und braucht Hilfe, sind Sie links mit HEAD
deutete auf G'
statt H'
als H'
existiert noch nicht.
Sobald die alle Merges erfolgreich zu sein und verpflichtet G'
und H'
tun existieren, git entfernt das Etikett your-branch
von H
zu begehen, und macht es H'
anstatt zu begehen Punkt:
G - H
/
... - E - F G' - H' <-- HEAD=your-branch
\ /
I - J - K - L <-- origin/their-branch
und Sie sind jetzt indexiert und HEAD
ist wieder einmal das, was Sie erwarten würden. Aber während der Rebase, HEAD
ist entweder ihre Verzweigung-Tipp (commit L
), oder eine der neuen Commits kopiert und hinter ihrer Verzweigung Spitze angehängt; und --ours
bedeutet, dass die Verzweigung am Ende von L
gezüchtet wird, während --theirs
bedeutet, dass die Festschreibung kopiert wird (G
oder H
oben).
(Dies ist im Grunde git den rohen Mechanismus des aussetzt, wie es tut, was es tut, was ziemlich viel in git passiert.)
Also im Grunde 'HEAD', in der ersten Operation„their- Branch "'s" HEAD', und in den folgenden Operationen ist 'HEAD' nun die neu angehängten Commits von mir? – Joseph
Ja; aber es kann ziemlich verwirrend sein, weil sie neu angehängt sind - Commits in dem Zweig, den du "wachsst", der noch keinen Namen hat. In den obigen Zeichnungen befinden sie sich in der mittleren Reihe und nicht in der oberen oder unteren Reihe. – torek
danke für die Erklärung. Mein Chef gab mir diesen Blick, als ich ihm erklärte, dass ich verwirrt war mit dem, was HEAD war. Ich denke, er lebt im Rebase-Universum und ich lebte im Merge-Universum. – dtc