Eine Option ist git rebase -i @{u}
. Ich benutze dies häufig genug, dass ich es als git freebase
(da es auf die Commits funktioniert, die Sie frei Rebase ) hat.
Falls Sie nicht vertraut sind, ist @{u}
eine Abkürzung für @{upstream}
oder "der Upstream des aktuellen Zweigs".
Wenn die Anzahl der Vermittler-Commits zwischen A bis X relativ klein ist, können Sie problemlos mit interaktiver Neufassung :
%Vor%Allerdings ist in meiner persönlichen Erfahrung langsam . Ich habe eine interaktive Neufassung von ungefähr hundert Commits auf einmal (auf einem Windows-Computer mit Git Bash) ausgeführt, und es dauerte lange, bis msysgit den interaktiven Rebase-Commit-Editor erzeugte, mit dem Sie auswählen können, welche Operationen ausgeführt werden sollen auf denen commit, weil, na ja, die Liste endete sehr groß.
In einer solchen Situation haben Sie einige Problemumgehungen.
git reset
Mixed und Soft-Resets können verwendet werden, um Ihren Arbeitsbaum oder Staging-Bereich (bzw.) zu ändern, um alle Änderungen zwischen zwei Commits A und Y zu sammeln / zu sammeln, nach denen Sie alle Änderungen gleichzeitig als Single committen können commit.
Ich werde nur ein Beispiel für einen Soft-Reset geben, da es bereits alles für Sie inszeniert, während Sie, wenn Sie einen gemischten Reset verwenden, die Modifikationen sowieso durchführen müssen:
%Vor%Eine andere Option ist die Verwendung von Patches. Erzeugen Sie einfach ein Diff-Patch mit dem Unterschied zwischen A und Y und wenden Sie das Patch dann als neues Commit über Y an:
%Vor% Wie schon von @ ABB in den Kommentaren , dies wird nicht ganz funktionieren, wenn es Binärdateien beteiligt sind. git diff --binary
kann verwendet werden, um ein diff für Binärdateien auszugeben Zusätzlich zu den Textdateien, aber ich bin mir nicht sicher, ob diese Diffs auch als Patches verwendet werden können.
"Einfachste" ist immer ein bisschen schwierig. Interaktive Rebase lässt Sie alles zerquetschen und ist in gewisser Weise "einfach".
Ein weiterer "einfacher" Weg, der ein wenig kompliziert aussieht, ist die Verwendung eines "Squash Merge" (was eigentlich kein Merge ist, aber den gleichen zugrunde liegenden Code verwendet wie git merge
, also mit dem gleicher Befehl). Nehmen wir an, Sie befinden sich im Zweig devel
, dessen Upstream origin/devel
ist. Zuerst benennen wir devel
in devel-full
um, um anzuzeigen, dass es sich um die mit der vollständigen Folge von Commits handelt. Dann erstellen wir ein neues devel
tracking origin/devel
und "squash-merge" devel-full
:
Sie müssen separat git commit
als --squash
das Commit unterdrücken, das git merge
normalerweise macht.
Eine dritte einfache (?), aber etwas gruselige Art ist es, die Tipp-Version zu überprüfen und zu begehen. Nehmen wir einmal devel
wie zuvor an, verschieben wir den Verzweigungsnamen "full develoment" aus dem Weg und machen einen neuen lokalen Zweig, um das neue Commit zu aktivieren. Diesmal verwenden wir anstelle von git merge --squash
zwei Befehle vor git commit
:
Die git rm -rf .
-Pläne (im Index / Staging-Bereich) jede einzelne zu entfernende Datei, aber dann sagt git checkout devel-full -- .
git, den Index / staging-Bereich mit jeder einzelnen Datei neu zu füllen Tipp von devel-full
. Das bedeutet also "mach den Baum für den nächsten Commit, sieh genau wie der Baum für die Spitze von devel-full
".
(Die remove-and-re-create-Methode funktioniert in einem Fall, in dem merge --squash
nicht funktioniert: Insbesondere wird die Spitze einer Verzweigung durch die Spitze einer anderen Verzweigung ersetzt, auch wenn dies nicht der Fall ist verwandt und daher nicht zusammenführbar. Sonst ist merge --squash
einen Schritt kürzer und definitiv nicht so gruselig aussehend, zumindest!)
Diese beiden anderen "einfachen" (?) Wege hinterlassen einen Zweig mit der vollständigen Entwicklungshistorie. Wenn du es willst, großartig! Wenn nicht, müssen Sie es löschen.
Tags und Links git git-rebase squash