Angenommen , ursprünglich gab es 3 Commits A, B, C:
Dann erstellte Entwickler Dan ein Commit Dund Entwickler Ed ein Commit E:
Offensichtlich sollte dieser Konflikt irgendwie gelöst werden. Dafür gibt es zwei Möglichkeiten:
MERGE :
Beide Commits Dund Esind immer noch hier, aber wir schaffen merge commit , Mdass inherits Änderungen von beiden Dund E. Dies schafft jedoch eine Diamantform , die viele Menschen sehr verwirrend finden.
REBASE :
Wir erstellen ein Commit R, dessen tatsächlicher Dateiinhalt mit dem Moben beschriebenen Merge-Commit identisch ist . Aber wir werden das Commit los E, als ob es nie existiert hätte (bezeichnet durch Punkte - verschwindende Linie). Aufgrund dieser Auslöschung Esollte es für Entwickler Ed lokal sein und sollte niemals in ein anderes Repository verschoben worden sein. Der Vorteil von Rebase ist, dass die Diamantform vermieden wird und die Geschichte eine schöne gerade Linie bleibt - die meisten Entwickler lieben das!
Schöne Illustrationen. Ich stimme jedoch dem positiven Ton, mit dem die Rebase behandelt wird, nicht vollständig zu. Sowohl beim Zusammenführen als auch beim erneuten Basieren können Konflikte auftreten, die manuell gelöst werden müssen. Und wie immer, wenn Programmierer involviert sind, besteht eine nicht zu vernachlässigende Wahrscheinlichkeit von Fehlern, auch bekannt als Bugs. Wenn ein Zusammenführungsfehler auftritt, kann das gesamte Team oder die Community die Zusammenführung sehen und überprüfen, ob dort ein Fehler aufgetreten ist. Die Historie der Rebase bleibt im Repo eines Entwicklers und selbst dort hat sie nur eine begrenzte Lebensdauer im Reflog. Es mag schöner aussehen, aber niemand kann so leicht sehen, was schief gelaufen ist.
Uwe Geuder
> "Dadurch entsteht jedoch eine Diamantform, die viele Menschen sehr verwirrend finden." Ähm ... kannst du das näher erläutern?
Greg Maletic
@ GregMaletic: Diamantform ist nichtlineare Geschichte. Ich weiß nichts über dich, aber ich mag nichtlineare Dinge im Allgemeinen nicht. Das heißt, Sie können gerne mit Diamanten verschmelzen, wenn Sie es wirklich bevorzugen - niemand zwingt Sie dazu.
MVP
1
Obwohl diese Antwort äußerst hilfreich ist, ist es besser, wenn Sie tatsächliche Git-Befehle mit einfachen foo.txt-Dateien hinzufügen, um sie lokal zu reproduzieren. Wie der letzte Benutzer sagte, ist es nicht offensichtlich, wer Rebase macht.
Vortex
1
@pferrel: Ich glaube nicht, dass du es richtig verstanden hast. git mergeverschachtelt keine Commits (aber es könnte so aussehen, wenn man es sich ansieht git log). Stattdessen git mergebleiben beide Entwicklungsgeschichten von Dan und Ed intakt, wie es jeweils von einem Standpunkt aus gesehen wurde. git rebaselässt es so aussehen, als hätte Dan zuerst daran gearbeitet und Ed ist ihm gefolgt. In beiden Fällen (Zusammenführen und erneutes Basieren) ist der tatsächlich resultierende Dateibaum absolut identisch.
Die Manpages sind ein allmächtiges "F *** you" 1 . Sie beschreiben die Befehle aus der Sicht eines Informatikers, nicht eines Benutzers. Ein typisches Beispiel:
git-push – Update remote refs along with associated objects
Hier ist eine Beschreibung für Menschen:
git-push – Upload changes from your local repository into a remote repository
Update, ein weiteres Beispiel: (danke cgd)
git-rebase – Forward-port local commits to the updated upstream head
Übersetzung:
git-rebase – Sequentially regenerate a series of commits so they can be
applied directly to the head node
Und dann haben wir
git-merge - Join two or more development histories together
Das Problem ist nicht die Sprache oder ob der Benutzer ein Informatiker ist oder nicht. Während es auf eine andere Weise umformuliert wird, um die Ziele zu klären (dh was passiert), kann es die Mittel nicht erklären (wie es passiert). Git erfordert das Verständnis der Mittel, um die Ziele zu verstehen. Es ist genau das Verständnis der Mittel, die Git so schwierig machen. Als Werkzeug, das zur Vereinfachung oder Reduzierung des Arbeitsaufwands verwendet wird, versagt Git schrecklich. Leider merken es zu viele Entwickler nicht.
ATL_DEV
128
Persönlich finde ich die Standard-Diagrammtechnik nicht sehr hilfreich - die Pfeile scheinen für mich immer den falschen Weg zu weisen. (Sie zeigen im Allgemeinen auf das "Elternteil" jedes Commits, was in der Zeit rückwärts ist, was seltsam ist).
Um es in Worten zu erklären:
Wenn Sie Ihren Zweig auf den Zweig umstellen , weisen Sie Git an, ihn so aussehen zu lassen, als hätten Sie den Zweig sauber ausgecheckt, und dann Ihre gesamte Arbeit von dort aus erledigt. Das ergibt ein sauberes, konzeptionell einfaches Paket von Änderungen, die jemand überprüfen kann. Sie können diesen Vorgang erneut wiederholen, wenn neue Änderungen in ihrem Zweig vorgenommen werden, und Sie erhalten immer einen sauberen Satz von Änderungen "an der Spitze" ihres Zweigs.
Wenn Sie verschmelzen ihre Niederlassung in Ihrer Branche, binden Sie die beiden Zweig Geschichten zusammen an dieser Stelle. Wenn Sie dies später mit weiteren Änderungen erneut tun, erstellen Sie einen verschachtelten Thread mit Historien: einige ihrer Änderungen, einige meiner Änderungen, einige ihrer Änderungen. Einige Leute finden dies chaotisch oder unerwünscht.
Aus Gründen, die ich nicht verstehe, haben GUI-Tools für Git nie große Anstrengungen unternommen, um Zusammenführungsverläufe sauberer darzustellen und die einzelnen Zusammenführungen zu abstrahieren. Wenn Sie also einen "sauberen Verlauf" wünschen, müssen Sie rebase verwenden.
Ich erinnere mich an Blog-Beiträge von Programmierern, die nur Rebase verwenden, und von anderen, die Rebase nie verwenden.
Beispiel
Ich werde versuchen, dies anhand eines Beispiels mit nur Worten zu erklären. Angenommen, andere Personen in Ihrem Projekt arbeiten an der Benutzeroberfläche und Sie schreiben Dokumentation. Ohne Rebase könnte Ihre Geschichte ungefähr so aussehen:
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
Das heißt, Zusammenführungen und UI-Commits werden in der Mitte Ihrer Dokumentations-Commits ausgeführt.
Wenn Sie Ihren Code auf den Master übertragen, anstatt ihn zusammenzuführen, sieht er folgendermaßen aus:
Write tutorial
Extend README
Fix a mistake in howto.md
Bigger buttons
Drop down list
Make window larger
Alle Ihre Commits befinden sich oben (am neuesten), gefolgt vom Rest der master Branche.
( Haftungsausschluss: Ich bin der Autor des Beitrags "10 Dinge, die ich an Git hasse", auf den in einer anderen Antwort Bezug genommen wird. )
Obwohl die akzeptierte und am besten bewertete Antwort großartig ist, finde ich es zusätzlich nützlich, den Unterschied nur mit Worten zu erklären:
verschmelzen
„Okay, wir haben zwei unterschiedlich entwickelte Zustände in unserem Repository. Lassen Sie uns sie zusammenführen. Zwei Eltern, ein daraus resultierendes Kind. “
Rebase
„Geben Sie die Änderungen des Hauptzweigs (unabhängig von seinem Namen) an meinen Feature-Zweig weiter. Tun Sie dies, indem Sie so tun, als ob meine Feature-Arbeit später begonnen hätte, und zwar in Bezug auf den aktuellen Status des Hauptzweigs. “
"Schreiben Sie die Geschichte meiner Änderungen neu, um dies widerzuspiegeln." (Sie müssen sie zwangsweise drücken, da es bei der Versionierung normalerweise darum geht, den angegebenen Verlauf nicht zu manipulieren.)
"Wahrscheinlich - wenn die Änderungen, die ich vorgenommen habe, wenig mit meiner Arbeit zu tun haben - ändert sich die Geschichte tatsächlich nicht viel, wenn ich meine Commits diff nach diff betrachte (Sie können auch an 'Patches' denken)."
Zusammenfassung: Wenn möglich, ist Rebase fast immer besser. Erleichterung der Wiedereingliederung in den Hauptzweig.
Weil? ➝ Ihre Feature-Arbeit kann als eine große 'Patch-Datei' (auch bekannt als diff) in Bezug auf den Hauptzweig dargestellt werden, ohne dass mehrere Eltern "erklärt" werden müssen: Mindestens zwei, die aus einer Zusammenführung stammen, aber wahrscheinlich viele weitere, wenn vorhanden waren mehrere Zusammenschlüsse. Im Gegensatz zu Zusammenführungen summieren sich mehrere Rebases nicht. (ein weiteres großes Plus)
Git Rebase ist näher an einer Zusammenführung. Der Unterschied in der Rebase ist:
Die lokalen Commits werden zeitlich aus dem Zweig entfernt.
Lass den Git Pull laufen
Fügen Sie erneut alle Ihre lokalen Commits ein.
Das bedeutet, dass alle Ihre lokalen Commits nach allen Remote-Commits bis zum Ende verschoben werden. Wenn Sie einen Zusammenführungskonflikt haben, müssen Sie ihn ebenfalls lösen.
Zum leichteren Verständnis kann ich meine Figur sehen.
Rebase ändert den Commit-Hash. Wenn Sie also große Konflikte vermeiden möchten, verwenden Sie Rebase einfach, wenn dieser Zweig fertig ist / als stabil abgeschlossen wurde.
Ich fand einen wirklich interessanten Artikel über Git Rebase vs Merge und dachte daran, ihn hier zu teilen
Wenn Sie den Verlauf vollständig so sehen möchten, wie er aufgetreten ist, sollten Sie die Zusammenführung verwenden. Beim Zusammenführen bleibt der Verlauf erhalten, während beim erneuten Basieren der Vorgang neu geschrieben wird.
Durch das Zusammenführen wird Ihrem Verlauf ein neues Commit hinzugefügt
Rebasing ist besser, um einen komplexen Verlauf zu optimieren. Sie können den Commit-Verlauf durch interaktives Rebase ändern.
Antworten:
Angenommen , ursprünglich gab es 3 Commits
A
,B
,C
:Dann erstellte Entwickler Dan ein Commit
D
und Entwickler Ed ein CommitE
:Offensichtlich sollte dieser Konflikt irgendwie gelöst werden. Dafür gibt es zwei Möglichkeiten:
MERGE :
Beide Commits
D
undE
sind immer noch hier, aber wir schaffen merge commit ,M
dass inherits Änderungen von beidenD
undE
. Dies schafft jedoch eine Diamantform , die viele Menschen sehr verwirrend finden.REBASE :
Wir erstellen ein Commit
R
, dessen tatsächlicher Dateiinhalt mit demM
oben beschriebenen Merge-Commit identisch ist . Aber wir werden das Commit losE
, als ob es nie existiert hätte (bezeichnet durch Punkte - verschwindende Linie). Aufgrund dieser AuslöschungE
sollte es für Entwickler Ed lokal sein und sollte niemals in ein anderes Repository verschoben worden sein. Der Vorteil von Rebase ist, dass die Diamantform vermieden wird und die Geschichte eine schöne gerade Linie bleibt - die meisten Entwickler lieben das!quelle
git merge
verschachtelt keine Commits (aber es könnte so aussehen, wenn man es sich ansiehtgit log
). Stattdessengit merge
bleiben beide Entwicklungsgeschichten von Dan und Ed intakt, wie es jeweils von einem Standpunkt aus gesehen wurde.git rebase
lässt es so aussehen, als hätte Dan zuerst daran gearbeitet und Ed ist ihm gefolgt. In beiden Fällen (Zusammenführen und erneutes Basieren) ist der tatsächlich resultierende Dateibaum absolut identisch.Ich liebe diesen Auszug aus 10 Dingen, die ich an Git hasse (er gibt im zweiten Beispiel eine kurze Erklärung für Rebase):
Und dann haben wir
Das ist eine gute Beschreibung.
1. im Original unzensiert
quelle
Persönlich finde ich die Standard-Diagrammtechnik nicht sehr hilfreich - die Pfeile scheinen für mich immer den falschen Weg zu weisen. (Sie zeigen im Allgemeinen auf das "Elternteil" jedes Commits, was in der Zeit rückwärts ist, was seltsam ist).
Um es in Worten zu erklären:
Aus Gründen, die ich nicht verstehe, haben GUI-Tools für Git nie große Anstrengungen unternommen, um Zusammenführungsverläufe sauberer darzustellen und die einzelnen Zusammenführungen zu abstrahieren. Wenn Sie also einen "sauberen Verlauf" wünschen, müssen Sie rebase verwenden.
Ich erinnere mich an Blog-Beiträge von Programmierern, die nur Rebase verwenden, und von anderen, die Rebase nie verwenden.
Beispiel
Ich werde versuchen, dies anhand eines Beispiels mit nur Worten zu erklären. Angenommen, andere Personen in Ihrem Projekt arbeiten an der Benutzeroberfläche und Sie schreiben Dokumentation. Ohne Rebase könnte Ihre Geschichte ungefähr so aussehen:
Das heißt, Zusammenführungen und UI-Commits werden in der Mitte Ihrer Dokumentations-Commits ausgeführt.
Wenn Sie Ihren Code auf den Master übertragen, anstatt ihn zusammenzuführen, sieht er folgendermaßen aus:
Alle Ihre Commits befinden sich oben (am neuesten), gefolgt vom Rest der
master
Branche.( Haftungsausschluss: Ich bin der Autor des Beitrags "10 Dinge, die ich an Git hasse", auf den in einer anderen Antwort Bezug genommen wird. )
quelle
Obwohl die akzeptierte und am besten bewertete Antwort großartig ist, finde ich es zusätzlich nützlich, den Unterschied nur mit Worten zu erklären:
verschmelzen
Rebase
Zusammenfassung: Wenn möglich, ist Rebase fast immer besser. Erleichterung der Wiedereingliederung in den Hauptzweig.
Weil? ➝ Ihre Feature-Arbeit kann als eine große 'Patch-Datei' (auch bekannt als diff) in Bezug auf den Hauptzweig dargestellt werden, ohne dass mehrere Eltern "erklärt" werden müssen: Mindestens zwei, die aus einer Zusammenführung stammen, aber wahrscheinlich viele weitere, wenn vorhanden waren mehrere Zusammenschlüsse. Im Gegensatz zu Zusammenführungen summieren sich mehrere Rebases nicht. (ein weiteres großes Plus)
quelle
Git Rebase ist näher an einer Zusammenführung. Der Unterschied in der Rebase ist:
Das bedeutet, dass alle Ihre lokalen Commits nach allen Remote-Commits bis zum Ende verschoben werden. Wenn Sie einen Zusammenführungskonflikt haben, müssen Sie ihn ebenfalls lösen.
quelle
Zum leichteren Verständnis kann ich meine Figur sehen.
Rebase ändert den Commit-Hash. Wenn Sie also große Konflikte vermeiden möchten, verwenden Sie Rebase einfach, wenn dieser Zweig fertig ist / als stabil abgeschlossen wurde.
quelle
Ich fand einen wirklich interessanten Artikel über Git Rebase vs Merge und dachte daran, ihn hier zu teilen
quelle