629 Stimmen

Zusammenführen (mit Squash) aller Änderungen aus einem anderen Zweig als eine einzige Übergabe

Gibt es in Git eine Möglichkeit, alle Änderungen von einem Zweig in einen anderen zusammenzuführen, aber gleichzeitig auf einen einzigen Commit zu quetschen?

Ich arbeite oft an einer neuen Funktion in einem separaten Zweig und werde regelmäßig committen/pushen - hauptsächlich als Backup oder um das, woran ich arbeite, auf einen anderen Rechner zu übertragen. Meistens sagen diese Commits "Feature xxx WIP" oder etwas Redundantes.

Sobald diese Arbeit abgeschlossen ist und ich den WIP-Zweig wieder in den Master-Zweig einbinden möchte, möchte ich all diese Zwischen-Commits verwerfen und nur einen einzigen sauberen Commit haben.

Gibt es eine einfache Möglichkeit, dies zu tun?

Wie wäre es alternativ mit einem Befehl, der alle Commits auf einem Branch seit dem Zeitpunkt, an dem er verzweigt wurde, löscht?

777voto

fseto Punkte 9212

Eine weitere Möglichkeit ist git merge --squash <feature branch> dann schließlich eine git commit .

Von Git-Zusammenführung

--squash

--no-squash

Erzeugen des Arbeitsbaums und des Indexstatus wie bei einer echten Zusammenführung stattgefunden hat (mit Ausnahme der Merge Information), aber machen Sie nicht wirklich eine Übergabe oder verschieben die HEAD noch Rekord $GIT_DIR/MERGE_HEAD um die nächste git commit Befehl zum Erstellen einer Zusammenführung Übertragen. Damit können Sie einen einzelnen Commit über den aktuellen Zweig zu erstellen, dessen Effekt derselbe ist wie Zusammenführen eines anderen Zweiges (oder mehrerer Fall eines Oktopus).

281voto

Brad Robinson Punkte 39967

Ich habe es gefunden! Der Befehl Merge hat eine --squash Option

git checkout master
git merge --squash WIP

Zu diesem Zeitpunkt ist alles zusammengeführt, möglicherweise mit Konflikten behaftet, aber nicht festgelegt. Ich kann also jetzt:

git add .
git commit -m "Merged WIP"

38voto

fseto Punkte 9212

Versuchen Sie git rebase -i master auf Ihrem Feature-Zweig. Sie können dann alle bis auf einen "pick" in "squash" ändern, um die Commits zu kombinieren. Siehe Zerdrücken von Übertragungen mit rebase

Schließlich können Sie dann die Zusammenführung vom Master-Zweig aus vornehmen.

26voto

raratiru Punkte 7315

Verwendung von git merge --squash <feature branch> als die akzeptierte Antwort schlägt vor, dass der Trick funktioniert, aber er zeigt den zusammengeführten Zweig nicht als tatsächlich zusammengeführt an.

Daher ist eine noch bessere Lösung:

  • Erstellen Sie einen neuen Zweig aus dem neuester Master in den Master-Zweig übertragen, in dem der Feature-Zweig begonnen hat.
  • Zusammenführen <feature branch> in die oben genannten mit git merge --squash
  • Führen Sie den neu erstellten Zweig in master ein. Auf diese Weise enthält der Funktionszweig nur eine Übergabe und die Zusammenführung wird in einer kurzen und übersichtlichen Abbildung dargestellt.

Dieses Wiki erklärt das Verfahren im Detail.

Im folgenden Beispiel ist der linke Bildschirmausschnitt das Ergebnis von qgit und der rechte Screenshot ist das Ergebnis von:

git log --graph --decorate --pretty=oneline --abbrev-commit

Beide Die Screenshots zeigen den gleichen Bereich von Übertragungen im gleichen Repository. Dennoch ist das rechte Bild kompakter dank der --squash .

  • Mit der Zeit wird die master Zweig abweichend von db .
  • Wenn die db fertig war, wurde ein neuer Zweig namens tag wurde in der gleichen Übertragung von master dass db hat seine Wurzel.
  • Von tag a git merge --squash db durchgeführt, und anschließend wurden alle Änderungen in einem einzigen Commit zusammengefasst.
  • Von master , tag wurden zusammengelegt: git merge tag .
  • Die Branche search ist irrelevant und in keiner Weise verschmolzen.

enter image description here

9voto

Akbar Pulatov Punkte 2346

2020 aktualisiert

Mit dem --squash Flagge sieht aus wie zwei parallele Zweige, die nichts miteinander zu tun haben:

enter image description here

Die Sortierung von Commits nach Datum sieht so aus:

enter image description here

Ich persönlich mag die Option --squash nicht, versuchen Sie diesen Trick, vielleicht passt er zu Ihren Bedürfnissen, ich verwende ihn für kleine Projekte:

  1. Git-Init
  2. git checkout -b dev
  3. Mehrere Übertragungen in dev
  4. Nachdem Sie einige große Commits in Dev gemacht haben (aber noch nicht in Master zusammengeführt), wenn Sie nicht wollen, dass alle Commits in den Master-Zweig kopiert werden, dann ändern Sie absichtlich etwas in Master und (fügen Sie einige leere Zeilen in der README-Datei und Commit in Master),
  5. git merge dev Das Ergebnis ist ein Merge-Konflikt (leere Zeilen in der README), lösen Sie ihn auf, übertragen Sie die gewünschte neue Nachricht und Sie sind FERTIG. Hier ist die visuelle Darstellung des Vorgangs.

Null-Commit für absichtlichen Merge-Konflikt, nennen Sie es wie Sie wollen

null commit for intentionally merge conflict

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X