it-swarm.com.de

Was ist der Unterschied zwischen "Git Merge" und "Git Rebase"?

Was ist der Unterschied zwischen git merge und git rebase?

463
Daniel Peñalba

Angenommen, ursprünglich gab es drei Commits, A, B, C:

A-B-C

Dann erstellte Entwickler Dan das Commit D und Entwickler Ed das Commit E:

A-B-C-D-E

Offensichtlich sollte dieser Konflikt irgendwie gelöst werden. Hierfür gibt es zwei Möglichkeiten:

MERGE:

A-B-C-D-E-M

Beide Commits D und E sind immer noch hier, aber wir erstellen ein Merge-Commit M, das die Änderungen sowohl von D als auch von E übernimmt. Dies erzeugt jedoch eine Diamantform , die viele Leute sehr verwirrend finden.

REBASE:

A-B-C-D-E-R

Wir erstellen ein Commit R, dessen tatsächlicher Dateiinhalt mit dem des oben beschriebenen Merge-Commits M identisch ist. Aber wir werden Commit E los, als ob es nie existiert hätte (durch Punkte gekennzeichnet - verschwindende Linie). Wegen dieser Auslöschung sollte E lokal für Entwickler Ed sein und sollte niemals in ein anderes Repository verschoben worden sein. Der Vorteil von Rebase ist, dass die Diamantform vermieden wird und die Geschichte auf einer schönen geraden Linie bleibt - die meisten Entwickler lieben das!

821
mvp

Ich liebe diesen Auszug aus 10 Dinge, die ich an git hasse (es gibt eine kurze Erklärung für Rebase in seinem zweiten Beispiel):

3. Beschissene Dokumentation

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 den 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 ist eine gute Beschreibung.


1. unzensiert im Original

144
mvw

Persönlich finde ich die Standard-Diagrammtechnik nicht sehr hilfreich - die Pfeile scheinen für mich immer in die falsche Richtung zu weisen. (Sie verweisen im Allgemeinen auf die "Eltern" eines jeden Commits, was in der Zeit rückwärts endet, was seltsam ist).

Um es in Worten zu erklären:

  • Wenn Sie Ihren Zweig auf seinen Zweig zurücksetzen , weisen Sie Git an, ihn so aussehen zu lassen, als hätten Sie seinen Zweig sauber ausgecheckt, und dann haben Sie Ihre ganze Arbeit von dort aus erledigt. Das macht ein sauberes, konzeptionell einfaches Paket von Änderungen, die jemand überprüfen kann. Sie können diesen Vorgang erneut wiederholen, wenn sich neue Änderungen in ihrem Zweig befinden, und Sie werden immer einen sauberen Satz von Änderungen "an der Spitze" ihres Zweigs erhalten.
  • Wenn Sie ihren Zweig in Ihrem Zweig zusammenführen , binden Sie die beiden Zweigverläufe an dieser Stelle zusammen. Wenn Sie dies später mit weiteren Änderungen wiederholen, beginnen Sie, einen verschachtelten Thread von Historien zu erstellen: einige ihrer Änderungen, einige meiner Änderungen, einige ihrer Änderungen. Einige Leute finden dies unordentlich oder unerwünscht.

Aus Gründen, die ich nicht verstehe, haben GUI-Tools für Git nie viel Mühe darauf verwendet, Zusammenführungsverläufe sauberer darzustellen und die einzelnen Zusammenführungen zu abstrahieren. Wenn Sie also einen "bereinigten Verlauf" möchten, müssen Sie rebase verwenden.

Ich erinnere mich, dass ich Blog-Posts von Programmierern gelesen habe, die nur rebase verwenden, und von anderen, die nie rebase verwenden.

Beispiel

Ich werde versuchen, dies mit einem einfachen Beispiel zu erklären. Angenommen, andere Personen in Ihrem Projekt arbeiten an der Benutzeroberfläche, und Sie schreiben Dokumentation. Ohne Rebase könnte Ihr Verlauf 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, Merges und UI-Commits werden in der Mitte Ihrer Dokumentations-Commits ausgeführt.

Wenn Sie Ihren Code auf master umbasieren, 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 des Zweigs master.

( Haftungsausschluss: Ich bin der Autor der "10 Dinge, die ich an Git hasse" -Post, auf die in einer anderen Antwort verwiesen wird )

115
Steve Bennett

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:

Zusammenführen

  • „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 (wie auch immer der Name lautet) an meinen Feature-Zweig. Tun Sie dies, indem Sie so tun, als ob meine Feature-Arbeit später begonnen hätte, und zwar über den aktuellen Stand der Hauptniederlassung. “
  • "Schreibe den Verlauf meiner Änderungen neu, um ihn wiederzugeben." (muss erzwungen werden, da es bei der Versionierung normalerweise nur um nicht Manipulieren des Verlaufs geht.)
  • "Wahrscheinlich - wenn die Änderungen, die ich vorgenommen habe, wenig mit meiner Arbeit zu tun haben - wird sich die Geschichte nicht wesentlich ändern, wenn ich meine Commits diff für diff betrachte (Sie können auch an" Patches "denken)."

Zusammenfassung: Nach Möglichkeit ist die Rebase fast immer besser. Vereinfachung der Wiedereingliederung in die Hauptbranche.

Weil? ➝ Ihre Feature-Arbeit kann als eine große 'Patch-Datei' (aka diff) in Bezug auf den Hauptzweig dargestellt werden, ohne dass Sie mehrere erklären müssen Eltern: Mindestens zwei, die aus einem Zusammenschluss stammen, aber wahrscheinlich viel mehr, wenn es mehrere Zusammenschlüsse gab. Anders als bei Zusammenführungen summieren sich mehrere Rebases nicht. (ein weiteres großes Plus)

38
Frank Nocke

Git-Rebase ist näher an einer Zusammenführung. Der Unterschied in der Basis ist:

  • die lokalen Commits werden vorübergehend aus der Zweigstelle entfernt.
  • führe den Git-Pull aus
  • fügen Sie noch einmal alle Ihre lokalen Commits ein.

Das bedeutet, dass alle Ihre lokalen Commits nach allen Remote-Commits an das Ende verschoben werden. Wenn Sie einen Zusammenführungskonflikt haben, müssen Sie ihn ebenfalls lösen.

14
Willem Franco

Zum leichteren Verständnis kann man meine Figur sehen.

Durch einen Neustart wird der Festschreibungs-Hash geändert. Wenn Sie also Konflikte vermeiden möchten, verwenden Sie einfach den Neustart, wenn dieser Zweig als stabil abgeschlossen ist.

enter image description here

5
Nhan Cao