Was ist in git der Unterschied zwischen Merge - Quash und Rebase?


363

Ich bin neu in Git und ich versuche den Unterschied zwischen einem Squash und einem Rebase zu verstehen. Soweit ich weiß, führen Sie beim Rebase einen Squash durch.

Antworten:


360

Beides git merge --squashund git rebase --interactivekann ein "gequetschtes" Commit erzeugen.
Aber sie dienen unterschiedlichen Zwecken.

erzeugt ein gequetschtes Commit für den Zielzweig, ohne eine Zusammenführungsbeziehung zu markieren.
(Hinweis: Es wird nicht sofort ein Commit erstellt: Sie benötigen ein zusätzliches Commit. git commit -m "squash branch")
Dies ist nützlich, wenn Sie den Quellzweig vollständig wegwerfen möchten (Schema aus SO-Frage ):

 git checkout stable

      X                   stable
     /                   
a---b---c---d---e---f---g tmp

zu:

git merge --squash tmp
git commit -m "squash tmp"

      X-------------------G stable
     /                   
a---b---c---d---e---f---g tmp

und dann tmpZweig löschen .


Hinweis: git mergehat eine --commitOption , kann aber nicht mit verwendet werden --squash. Es war nie möglich, --commitund --squashzusammen zu verwenden.
Seit Git 2.22.1 (Q3 2019) wird diese Inkompatibilität explizit gemacht:

Siehe Commit 1d14d0c (24. Mai 2019) von Vishal Verma ( reloadbrain) .
(Zusammengeführt von Junio ​​C Hamano - gitster- in Commit 33f2790 , 25. Juli 2019)

merge: ablehnen --commitmit--squash

Zuvor, als --squashgeliefert wurde, wurde ' option_commit' lautlos fallen gelassen. Dies könnte für einen Benutzer überraschend gewesen sein, der versucht hat, das No-Commit-Verhalten von Squash --commitexplizit zu überschreiben .

git/git builtin/merge.c#cmd_merge() enthält jetzt:

if (option_commit > 0)
    die(_("You cannot combine --squash with --commit."));

Wiederholt einige oder alle Ihrer Commits auf einer neuen Basis, sodass Sie Squash ausführen können (oder in jüngerer Zeit "reparieren", siehe diese SO-Frage ) und direkt zu:

git checkout tmp
git rebase -i stable

      stable
      X-------------------G tmp
     /                     
a---b

Wenn Sie sich dafür entscheiden, alle Commits von zu quetschen tmp(aber im Gegensatz dazu merge --squashkönnen Sie einige wiedergeben und andere quetschen).

Die Unterschiede sind also:

  • squashBerührt Ihren Quellzweig ( tmphier) nicht und erstellt ein einzelnes Commit, wo Sie möchten.
  • rebaseermöglicht es Ihnen, mit demselben Quellzweig (noch tmp) fortzufahren mit:
    • eine neue Basis
    • eine sauberere Geschichte

11
Gwird c--d--e--f--gzusammengedrückt?
Wayne Conrad

8
@ Wayne: Ja, G in diesen Beispielen repräsentiert die zusammengedrückten tmpCommits.
VonC

3
@ Th4wn: Da Git Gründe mit Schnappschüssen eines gesamten Projekts hat, Gwird gaufgrund von Änderungen, die durch eingeführt wurden , nicht derselbe Inhalt wie dargestellt X.
VonC

1
@VonC: Ich bin mir nicht sicher über diesen letzten Kommentar. Wenn Sie eine git merge --no-ff tempanstelle von haben git merge --squash temp, dann erhalten Sie eine chaotischere Geschichte, aber Sie können auch Dinge wie git revert eviel einfacher tun . Es ist eine chaotische, aber ehrliche und pragmatische Geschichte, und der Hauptzweig bleibt immer noch ziemlich sauber.
naught101

2
@ naught101 Ich stimme zu. Wie unter stackoverflow.com/a/7425751/6309 erläutert , geht es auch darum, nicht zu brechen git bisectoder git blamewenn es zu oft verwendet wird (wie in git pull --no-ff: stackoverflow.com/questions/12798767/… ). Es gibt sowieso keinen Ansatz, weshalb in diesem Artikel drei beschrieben wurden ( stackoverflow.com/questions/9107861/… )
VonC

183

Commits zusammenführen: Behält alle Commits in Ihrem Zweig bei und verschachtelt sie mit Commits im BasiszweigGeben Sie hier die Bildbeschreibung ein

Squash zusammenführen: Behält die Änderungen bei, lässt jedoch die einzelnen Commits aus dem Verlauf aus Geben Sie hier die Bildbeschreibung ein

Rebase: Dadurch wird der gesamte Feature-Zweig so verschoben, dass er an der Spitze des Master-Zweigs beginnt, wodurch alle neuen Commits effektiv in den Master integriert werden

Geben Sie hier die Bildbeschreibung ein

Mehr dazu hier


81

Squash zusammenführen führt einen Baum (eine Folge von Commits) zu einem einzigen Commit zusammen. Das heißt, es quetscht alle Änderungen in aus n Commits in einem einzigen begehen.

Beim erneuten Basieren wird erneut basiert, dh es wird eine neue Basis (übergeordnetes Commit) für einen Baum ausgewählt. Vielleicht ist der Quecksilberbegriff dafür klarer: Sie nennen es Transplantation, weil es nur so ist: einen neuen Boden (Eltern-Commit, Wurzel) für einen Baum auswählen.

Wenn Sie eine interaktive Basis neu erstellen, haben Sie die Möglichkeit, die Commits, die Sie neu erstellen möchten, entweder zu quetschen, auszuwählen, zu bearbeiten oder zu überspringen.

Hoffe das war klar!


7
Wann sollte ich wieder aufbauen und wann soll ich quetschen?
Martin Thoma

31

Beginnen wir mit dem folgenden Beispiel:

Geben Sie hier die Bildbeschreibung ein

Jetzt haben wir drei Möglichkeiten, um Änderungen des Feature-Zweigs in den Hauptzweig zusammenzuführen :

  1. Commits zusammenführen
    Behält den gesamten Commit- Verlauf des Feature-Zweigs bei und verschiebt ihn in den Master-Zweig.
    Fügt ein zusätzliches Dummy-Commit hinzu.

  2. Rebase and Merge Hängt den
    gesamten Commit- Verlauf des Feature-Zweigs an der Vorderseite des Master-Zweigs an.
    Fügt KEIN zusätzliches Dummy-Commit hinzu.

  3. Squash and Merge
    Gruppiert alle Feature-Branch- Commits zu einem Commit und hängt sie dann an die Vorderseite des Master-Zweigs an.
    Fügt ein zusätzliches Dummy-Commit hinzu.

Nachfolgend finden Sie, wie der Hauptzweig jeden einzelnen von ihnen betreut.

Geben Sie hier die Bildbeschreibung ein

In allen Fällen:
Wir können den Feature-Zweig sicher LÖSCHEN .


1
Kannst du erklären, was Dummy Commit im 2. Bild ist? Ich bin ein Anfänger in Git.
Yusuf

1
@Yusuf, es ist nur ein zusätzliches Commit, das beide Zweigaktualisierungen enthält. Es ist die Standard-Commit-Nachricht = "Megre-Zweig XYZ in Master"
ahmednabil88
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.