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?

5voto

Stephen Crosby Punkte 1133

Ich habe mein eigenes Git-Alias erstellt, um genau dies zu tun. Ich nenne ihn git freebase ! Es nimmt Ihren bestehenden unordentlichen, unbasierbaren Feature-Zweig und erstellt ihn neu, so dass er zu einem neuen Zweig mit demselben Namen wird, dessen Commits in einem Commit zusammengefasst und auf den von Ihnen angegebenen Zweig (standardmäßig Master) umgebasht werden. Ganz zum Schluss erlaubt es Ihnen, eine beliebige Commit-Nachricht für Ihren neuen "freebased" Zweig zu verwenden.

Installieren Sie es, indem Sie den folgenden Alias in Ihre .gitconfig einfügen:

[alias]
  freebase = "!f() { \
    TOPIC="$(git branch | grep '\\*' | cut -d ' ' -f2)"; \
    NEWBASE="${1:-master}"; \
    PREVSHA1="$(git rev-parse HEAD)"; \
    echo "Freebaseing $TOPIC onto $NEWBASE, previous sha1 was $PREVSHA1"; \
    echo "---"; \
    git reset --hard "$NEWBASE"; \
    git merge --squash "$PREVSHA1"; \
    git commit; \
  }; f"

Verwenden Sie es von Ihrem Funktionszweig aus, indem Sie es ausführen: git freebase <new-base>

Ich habe dies nur ein paar Mal getestet, also lesen Sie es zuerst und stellen Sie sicher, dass Sie es ausführen wollen. Als kleine Sicherheitsmaßnahme druckt es die Start-Sha1 aus, so dass Sie in der Lage sein sollten, Ihren alten Zweig wiederherzustellen, falls etwas schief geht.

Ich werde es in meinem dotfiles Repository auf Github pflegen: https://github.com/stevecrozz/dotfiles/blob/master/.gitconfig

3voto

Gurjinder Singh Punkte 7152

Sie haben einen Master-Zweig und einen Feature-Zweig. Sie haben viele Commits in einem Feature-Branch. Sie wollen nicht, dass alle Commits des Feature-Branches in der Commit-Historie des Masters erscheinen. Folgen Sie diesen Schritten

  1. Erstellen Sie einen neuen Zweig aus dem aktuellen Mastercode und Sie befinden sich in diesem Zweig
git checkout -b latest_MCode
  1. Führen Sie nun Ihren Feature-Zweig in den latest_Mcode-Zweig ein
git merge --squash feature
  1. Commit ohne -m param durchführen

git commit # ohne -m

Ein Editor sollte ein Popup-Fenster mit allen Commit-Protokollen und geänderten Dateien aus dem Feature-Zweig sein. Sie können hier alle Übertragungen des Funktionszweigs sehen. Wenn Sie möchten, können Sie alles löschen und nur eine Zeile der Commit-Nachricht schreiben, die Sie nach dem Zusammenführen in Master anzeigen möchten. Drücken Sie i, schreiben Sie Ihre Nachricht und drücken Sie Esc->:wq->Enter, um zu speichern und den Editor zu verlassen. 4. Führen Sie den neu erstellten Zweig in master ein.

git checkout master
git merge latest_Mcode
git push

Sie sind fertig! Die Originalantwort finden Sie unter GithubLink

-1voto

Arjun Mullick Punkte 11

git merge --squash <feature branch> Die "Git Commit"-Funktion zeigt Ihnen die Commit-Nachricht des Funktionszweigs an, wobei Sie entscheiden können, ob Sie sie behalten wollen.

Für weniger Commit Merge .

Git-Zusammenführung do x mal --git reset HEAD^ --soft dann git commit .

Risiko - gelöschte Dateien können wieder auftauchen.

-8voto

NamshubWriter Punkte 22785

Sie können dies mit dem Befehl "rebase" tun. Nennen wir die Zweige "main" und "feature":

git checkout feature
git rebase main

Mit dem Befehl rebase werden alle Commits von "feature" als ein Commit mit einem Parent gleich "main" wiedergegeben.

Sie könnten Folgendes ausführen git merge main avant git rebase main wenn sich "main" seit der Erstellung von "feature" (oder seit der letzten Zusammenführung) geändert hat. Auf diese Weise haben Sie immer noch die vollständige Historie, falls Sie einen Zusammenführungskonflikt haben.

Nach dem Rebase können Sie Ihren Zweig mit dem Hauptzweig zusammenführen, was zu einem Fast-Forward-Merge führen sollte:

git checkout main
git merge feature

Siehe die neu gründen Seite von Git konzeptionell verstehen für einen guten Überblick

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