Eine beliebig große Anzahl von Commits kombinieren oder umbasieren

8

Nehmen wir an, mein lokales git log zeigt:

%Vor%

Mein Remote git log zeigt:

%Vor%

Was ist der einfachste Weg, um dies zu erreichen ( Annahme einer beliebig großen Anzahl von lokalen Commits ):

%Vor%     
theanine 04.03.2014, 02:40
quelle

3 Antworten

6

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".

    
sartak 04.03.2014, 02:47
quelle
14

Manchmal möchten Sie möglicherweise Interactive Rebase nicht verwenden

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.

Alternative # 1: 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%

Alternative # 2: Patches verwenden

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.

    
user456814 04.03.2014 02:48
quelle
2

"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 :

%Vor%

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 :

%Vor%

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.

    
torek 04.03.2014 03:03
quelle

Tags und Links