Teilen Sie ein vorheriges Commit in mehrere Commits auf

1224

Ist es möglich, ein einzelnes Commit in ein paar verschiedene Commits zu unterteilen, nachdem es in das lokale Repository festgeschrieben wurde, ohne einen Zweig zu erstellen und eine Menge Funky-Arbeit an einem neuen Zweig zu leisten?

Koblas
quelle
36
Eine gute Quelle, um zu lernen, wie man das macht, ist Pro Git §6.4 Git Tools - Umschreiben des Verlaufs im Abschnitt "Aufteilen eines Commits".
2
Die im obigen Kommentar verlinkten Dokumente sind ausgezeichnet und besser erklärt als die folgenden Antworten.
Blaisorblade
2
Ich schlage vor, diesen Alias stackoverflow.com/a/19267103/301717 zu verwenden . Es erlaubt, ein Commit mitgit autorebase split COMMIT_ID
Jérôme Pouiller
Ohne eine interaktive Rebase ist es am einfachsten, (wahrscheinlich) einen neuen Zweig zu erstellen, der mit dem Commit beginnt, bevor der, den Sie teilen möchten, das Commit auswählt, zurücksetzt, speichert, die Datei verschiebt, den Stash erneut anwendet und Übernehmen Sie die Änderungen und führen Sie sie dann entweder mit dem früheren Zweig zusammen oder wählen Sie die folgenden Festschreibungen aus. (Dann wechseln Sie den früheren Filialnamen zum aktuellen Kopf.) (Es ist wahrscheinlich besser, den Ratschlägen von MBOs zu folgen und eine interaktive Rebase durchzuführen.) (Kopie aus der Antwort von 2010 unten)
William Pursell
1
Ich bin auf dieses Problem gestoßen, nachdem ich während eines Rebases in einem früheren Commit versehentlich zwei Commits gequetscht habe. Meine Art und Weise , es zu beheben war begehen die zerquetschten zur Kasse, git reset HEAD~, git stash, dann git cherry-pickdie erste innerhalb des Squash begehen, dann git stash pop. Mein cherry-pick Fall ist ganz spezifisch hier, aber git stashund git stash popist für andere ganz praktisch.
SOFe

Antworten:

1799

git rebase -i werde es tun.

Beginnen Sie zunächst mit einem sauberen Arbeitsverzeichnis: Es git statussollten keine ausstehenden Änderungen, Löschungen oder Ergänzungen angezeigt werden.

Jetzt müssen Sie entscheiden, welche Commits Sie teilen möchten.

A) Aufteilen des letzten Commits

Um Ihr letztes Commit aufzuteilen, gehen Sie zunächst wie folgt vor:

$ git reset HEAD~

Legen Sie nun die Teile wie gewohnt einzeln fest und erstellen Sie so viele Festschreibungen, wie Sie benötigen.

B) Ein Commit weiter hinten aufteilen

Dies erfordert ein erneutes Basieren , dh ein Umschreiben des Verlaufs. Um das richtige Commit zu finden, haben Sie mehrere Möglichkeiten:

  • Wenn es drei Commits waren, dann

    $ git rebase -i HEAD~3
    

    Wo 3ist, wie viele Commits es zurück gibt?

  • Wenn es weiter hinten im Baum war, als Sie zählen möchten, dann

    $ git rebase -i 123abcd~
    

    Wo 123abcdist der SHA1 des Commits, den Sie aufteilen möchten?

  • Wenn Sie sich in einem anderen Zweig befinden (z. B. einem Feature-Zweig), den Sie in den Master einbinden möchten:

    $ git rebase -i master
    

Wenn Sie den Rebase-Bearbeitungsbildschirm erhalten, suchen Sie das Commit, das Sie trennen möchten. Am Anfang der Zeile, ersetzt pickmit edit( ekurz). Speichern Sie den Puffer und beenden Sie ihn. Rebase wird jetzt unmittelbar nach dem Commit gestoppt, das Sie bearbeiten möchten. Dann:

$ git reset HEAD~

Legen Sie die Teile wie gewohnt einzeln fest und produzieren Sie dann so viele Commits, wie Sie benötigen

$ git rebase --continue
Wayne Conrad
quelle
2
Vielen Dank für diese Antwort. Ich wollte einige zuvor festgeschriebene Dateien im Staging-Bereich haben, daher waren die Anweisungen für mich etwas anders. Bevor ich konnte git rebase --continue, ich hatte tatsächlich zu git add (files to be added), git commitund dann git stash(für die restlichen Dateien). Danach habe git rebase --continueich git checkout stash .die restlichen Dateien erhalten
Eric Hu
18
Die Antwort von manojlds enthält tatsächlich diesen Link zur Dokumentation zu git-scm , in der auch der Prozess der Aufteilung von Commits sehr klar erläutert wird.
56
Sie sollten auch git add -pdie eMöglichkeit nutzen, nur Teilabschnitte von Dateien hinzuzufügen, möglicherweise mit der Option, Unterschiede zu bearbeiten, um nur einen Teil eines Teils festzuschreiben. git stashDies ist auch nützlich, wenn Sie einige Arbeiten fortsetzen, diese jedoch aus dem aktuellen Commit entfernen möchten.
Craig Ringer
2
Wenn Sie Commits teilen und neu anordnen möchten, möchte ich zuerst teilen und dann mit einem anderen git rebase -i HEAD^3Befehl separat neu anordnen . Auf diese Weise müssen Sie nicht so viel Arbeit rückgängig machen, wenn die Aufteilung schlecht wird.
David M. Lloyd
4
@kralyk Die Dateien, die neu in HEAD festgeschrieben wurden, bleiben danach auf der Festplatte git reset HEAD~. Sie sind nicht verloren.
Wayne Conrad
312

Aus dem Git-Rebase- Handbuch (Abschnitt SPLITTING COMMITS)

Im interaktiven Modus können Sie Commits mit der Aktion "Bearbeiten" markieren. Dies bedeutet jedoch nicht unbedingt, dass Git Rebase erwartet, dass das Ergebnis dieser Bearbeitung genau ein Commit ist. In der Tat können Sie das Commit rückgängig machen oder andere Commits hinzufügen. Dies kann verwendet werden, um ein Commit in zwei Teile aufzuteilen:

  • Starten Sie eine interaktive Rebase mit git rebase -i <commit>^, wo <commit>sich das Commit befindet, das Sie teilen möchten. Tatsächlich reicht jeder Festschreibungsbereich aus, solange er dieses Festschreiben enthält.

  • Markieren Sie das Commit, das Sie teilen möchten, mit der Aktion "Bearbeiten".

  • Wenn Sie dieses Commit bearbeiten möchten, führen Sie es aus git reset HEAD^. Der Effekt ist, dass der KOPF um eins zurückgespult wird und der Index folgt. Der Arbeitsbaum bleibt jedoch gleich.

  • Fügen Sie nun die Änderungen zu dem Index hinzu, den Sie beim ersten Festschreiben haben möchten. Sie können dies git add(möglicherweise interaktiv) oder git gui(oder beides) verwenden.

  • Übernehmen Sie den aktuellen Index mit der jeweils geeigneten Festschreibungsnachricht.

  • Wiederholen Sie die letzten beiden Schritte, bis Ihr Arbeitsbaum sauber ist.

  • Setzen Sie den Rebase mit fort git rebase --continue.

MBO
quelle
12
Unter Windows haben Sie ~statt ^.
Kevin Kuszyk
13
Achtung: Bei diesem Ansatz habe ich die Commit-Nachricht verloren.
user420667
11
@ user420667 Ja natürlich. Wir machen schließlich resetdas Commit - Nachricht enthalten. Wenn Sie wissen, dass Sie ein Commit aufteilen, aber einen Teil oder die gesamte Nachricht behalten möchten, sollten Sie eine Kopie dieser Nachricht erstellen. Also, git showdas Commit vor dem rebaseIng, oder wenn Sie dies vergessen oder bevorzugen: kommen Sie später über das zurück reflog. Nichts davon wird tatsächlich "verloren" gehen, bis es in 2 Wochen oder was auch immer Müll gesammelt hat.
underscore_d
4
~und ^sind verschiedene Dinge, auch unter Windows. Sie wollen immer noch das Caret ^, also müssen Sie es nur entsprechend Ihrer Muschel entkommen. In PowerShell ist es HEAD`^. Mit cmd.exe können Sie es verdoppeln, um wie zu entkommen HEAD^^. In den meisten (allen?) Muscheln können Sie mit Anführungszeichen wie umgeben "HEAD^".
AndrewF
7
Sie können auch tun git commit --reuse-message=abcd123. Die kurze Option dafür ist -C.
J0057
41

Verwenden Sie git rebase --interactivediese Option, um das frühere Commit zu bearbeiten, auszuführen git reset HEAD~und dann git add -peinige hinzuzufügen, dann ein Commit durchzuführen, dann weitere hinzuzufügen und ein weiteres Commit durchzuführen, so oft Sie möchten. Wenn Sie fertig sind, führen Sie aus git rebase --continue, und Sie haben alle geteilten Commits früher in Ihrem Stapel.

Wichtig : Beachten Sie, dass Sie herumspielen und alle gewünschten Änderungen vornehmen können und sich keine Sorgen machen müssen, alte Änderungen zu verlieren, da Sie jederzeit git reflogden Punkt in Ihrem Projekt finden können, der die gewünschten Änderungen enthält (nennen wir es a8c4ab). und dann git reset a8c4ab.

Hier ist eine Reihe von Befehlen, um zu zeigen, wie es funktioniert:

mkdir git-test; cd git-test; git init

Fügen Sie nun eine Datei hinzu A

vi A

füge diese Zeile hinzu:

one

git commit -am one

Fügen Sie dann diese Zeile zu A hinzu:

two

git commit -am two

Fügen Sie dann diese Zeile zu A hinzu:

three

git commit -am three

Jetzt sieht die Datei A folgendermaßen aus:

one
two
three

und unser git logsieht wie folgt aus (naja, ich benutzegit log --pretty=oneline --pretty="%h %cn %cr ---- %s"

bfb8e46 Rose Perrone 4 seconds ago ---- three
2b613bc Rose Perrone 14 seconds ago ---- two
9aac58f Rose Perrone 24 seconds ago ---- one

Angenommen, wir möchten das zweite Commit aufteilen two.

git rebase --interactive HEAD~2

Daraufhin wird eine Meldung angezeigt, die folgendermaßen aussieht:

pick 2b613bc two
pick bfb8e46 three

Ändern Sie die erste pickin eine e, um dieses Commit zu bearbeiten.

git reset HEAD~

git diff zeigt uns, dass wir gerade das Commit aufgehoben haben, das wir für das zweite Commit gemacht haben:

diff --git a/A b/A
index 5626abf..814f4a4 100644
--- a/A
+++ b/A
@@ -1 +1,2 @@
 one
+two

Lassen Sie uns diese Änderung inszenieren und dieser Zeile in der Datei "und ein Drittel" hinzufügen A.

git add .

Dies ist normalerweise der Punkt während einer interaktiven Rebase, an dem wir ausgeführt werden git rebase --continue, da wir normalerweise nur in unseren Stapel von Commits zurückkehren möchten, um ein früheres Commit zu bearbeiten. Aber dieses Mal wollen wir ein neues Commit erstellen. Also rennen wir git commit -am 'two and a third'. Jetzt bearbeiten wir die Datei Aund fügen die Zeile hinzu two and two thirds.

git add . git commit -am 'two and two thirds' git rebase --continue

Wir haben einen Konflikt mit unserem Commit three. Lösen wir ihn also:

Wir werden uns ändern

one
<<<<<<< HEAD
two and a third
two and two thirds
=======
two
three
>>>>>>> bfb8e46... three

zu

one
two and a third
two and two thirds
three

git add .; git rebase --continue

Jetzt git log -psieht unser so aus:

commit e59ca35bae8360439823d66d459238779e5b4892
Author: Rose Perrone <[email protected]>
Date:   Sun Jul 7 13:57:00 2013 -0700

    three

diff --git a/A b/A
index 5aef867..dd8fb63 100644
--- a/A
+++ b/A
@@ -1,3 +1,4 @@
 one
 two and a third
 two and two thirds
+three

commit 4a283ba9bf83ef664541b467acdd0bb4d770ab8e
Author: Rose Perrone <[email protected]>
Date:   Sun Jul 7 14:07:07 2013 -0700

    two and two thirds

diff --git a/A b/A
index 575010a..5aef867 100644
--- a/A
+++ b/A
@@ -1,2 +1,3 @@
 one
 two and a third
+two and two thirds

commit 704d323ca1bc7c45ed8b1714d924adcdc83dfa44
Author: Rose Perrone <[email protected]>
Date:   Sun Jul 7 14:06:40 2013 -0700

    two and a third

diff --git a/A b/A
index 5626abf..575010a 100644
--- a/A
+++ b/A
@@ -1 +1,2 @@
 one
+two and a third

commit 9aac58f3893488ec643fecab3c85f5a2f481586f
Author: Rose Perrone <[email protected]>
Date:   Sun Jul 7 13:56:40 2013 -0700

    one

diff --git a/A b/A
new file mode 100644
index 0000000..5626abf
--- /dev/null
+++ b/A
@@ -0,0 +1 @@
+one
Rose Perrone
quelle
38

In früheren Antworten wurde die Verwendung von git rebase -izum Bearbeiten des Commits, das Sie teilen möchten, und zum Festschreiben in Teilen behandelt.

Dies funktioniert gut, wenn Sie die Dateien in verschiedene Commits aufteilen. Wenn Sie jedoch Änderungen an den einzelnen Dateien aufteilen möchten, müssen Sie mehr wissen.

Nachdem Sie das Commit erreicht haben, für das Sie es teilen, verwenden rebase -iund markieren möchten edit, haben Sie zwei Möglichkeiten.

  1. Nach der Verwendung git reset HEAD~, gehen Sie durch die Patches einzeln über git add -pdiejenigen auszuwählen , die Sie in jeder wollen begehen

  2. Bearbeiten Sie die Arbeitskopie, um die nicht gewünschten Änderungen zu entfernen. diesen Zwischenstaat begehen; und dann das volle Commit für die nächste Runde zurückziehen.

Option 2 ist nützlich, wenn Sie ein großes Commit aufteilen, da Sie überprüfen können, ob die Zwischenversionen im Rahmen der Zusammenführung ordnungsgemäß erstellt und ausgeführt werden. Dies läuft wie folgt ab.

Verwenden Sie nach dem Verwenden rebase -iund editFestlegen des Commits

git reset --soft HEAD~

Um das Festschreiben rückgängig zu machen, belassen Sie die festgeschriebenen Dateien jedoch im Index. Sie können auch einen gemischten Reset durchführen, indem Sie --soft weglassen, je nachdem, wie nahe das endgültige Ergebnis Ihres anfänglichen Commits sein wird. Der einzige Unterschied besteht darin, ob Sie mit allen bereitgestellten Änderungen beginnen oder mit allen nicht bereitgestellten Änderungen.

Gehen Sie jetzt hinein und bearbeiten Sie den Code. Sie können Änderungen entfernen, hinzugefügte Dateien löschen und alles tun, um das erste Commit der gesuchten Serie zu erstellen. Sie können es auch erstellen, ausführen und bestätigen, dass Sie über einen konsistenten Quellensatz verfügen.

Wenn Sie zufrieden sind, stellen Sie die Dateien nach Bedarf bereit (ich verwende sie gerne git guidafür) und übernehmen Sie die Änderungen über die Benutzeroberfläche oder die Befehlszeile

git commit

Das ist das erste Commit. Jetzt möchten Sie Ihre Arbeitskopie in dem Zustand wiederherstellen, den sie nach dem Festschreiben hatte, das Sie aufteilen, damit Sie mehr Änderungen für Ihr nächstes Festschreiben vornehmen können. Verwenden Sie, um den sha1 des Commits zu finden, den Sie bearbeiten git status. In den ersten Zeilen des Status sehen Sie den aktuell ausgeführten Rebase-Befehl, in dem Sie den sha1 Ihres ursprünglichen Commits finden:

$ git status
interactive rebase in progress; onto be83b41
Last commands done (3 commands done):
   pick 4847406 US135756: add debugging to the file download code
   e 65dfb6a US135756: write data and download from remote
  (see more in file .git/rebase-merge/done)
...

In diesem Fall hat das Commit, das ich bearbeite, sha1 65dfb6a. Wenn ich das weiß, kann ich den Inhalt dieses Commits über mein Arbeitsverzeichnis überprüfen, wobei die Form git checkoutsowohl ein Commit als auch einen Dateispeicherort annimmt. Hier verwende ich .als Dateispeicherort, um die gesamte Arbeitskopie zu ersetzen:

git checkout 65dfb6a .

Verpassen Sie nicht den Punkt am Ende!

Dadurch werden die Dateien so überprüft und bereitgestellt, wie sie nach dem von Ihnen bearbeiteten Commit waren, jedoch relativ zum vorherigen Commit, sodass alle bereits festgeschriebenen Änderungen nicht Teil des Commits sind.

Sie können entweder jetzt fortfahren und es unverändert festschreiben, um die Aufteilung zu beenden, oder es erneut ausführen und einige Teile des Festschreibens löschen, bevor Sie ein weiteres vorläufiges Festschreiben durchführen.

Wenn Sie die ursprüngliche Festschreibungsnachricht für eine oder mehrere Festschreibungen wiederverwenden möchten, können Sie sie direkt aus den Arbeitsdateien der Rebase verwenden:

git commit --file .git/rebase-merge/message

Sobald Sie alle Änderungen vorgenommen haben,

git rebase --continue

wird den Rebase-Vorgang fortsetzen und abschließen.

Andy Mortimer
quelle
3
Vielen Dank!!! Dies sollte die akzeptierte Antwort sein. Hätte mir heute viel Zeit und Schmerz gespart. Dies ist die einzige Antwort, bei der das Ergebnis des endgültigen Commits Sie in den gleichen Status wie das zu bearbeitende Commit versetzt.
Doug Coburn
1
Mir gefällt die Art und Weise, wie Sie die ursprüngliche Festschreibungsnachricht verwenden.
Salamandar
Wenn ich Option 2 verwende, git checkout *Sha I'm Editing* .heißt es immer Updated 0 paths from *Some Sha That's Not In Git Log*und gibt keine Änderungen.
Noumenon
18

git rebase --interactivekann verwendet werden, um ein Commit in kleinere Commits aufzuteilen. Die Git-Dokumente auf Rebase enthalten eine kurze Anleitung für den Prozess - Splitting Commits :

Im interaktiven Modus können Sie Commits mit der Aktion "Bearbeiten" markieren. Dies bedeutet jedoch nicht unbedingt, dass git rebaseerwartet wird , dass das Ergebnis dieser Bearbeitung genau ein Commit ist. In der Tat können Sie das Commit rückgängig machen oder andere Commits hinzufügen. Dies kann verwendet werden, um ein Commit in zwei Teile aufzuteilen:

  • Starten Sie eine interaktive Rebase mit git rebase -i <commit>^, wo <commit>sich das Commit befindet, das Sie teilen möchten. Tatsächlich reicht jeder Festschreibungsbereich aus, solange er dieses Festschreiben enthält.

  • Markieren Sie das Commit, das Sie teilen möchten, mit der Aktion "Bearbeiten".

  • Wenn Sie dieses Commit bearbeiten möchten, führen Sie es aus git reset HEAD^. Der Effekt ist, dass der KOPF um eins zurückgespult wird und der Index folgt. Der Arbeitsbaum bleibt jedoch gleich.

  • Fügen Sie nun die Änderungen zu dem Index hinzu, den Sie beim ersten Festschreiben haben möchten. Sie können git add(möglicherweise interaktiv) oder Git Gui (oder beides) verwenden, um dies zu tun.

  • Übernehmen Sie den aktuellen Index mit der jeweils geeigneten Festschreibungsnachricht.

  • Wiederholen Sie die letzten beiden Schritte, bis Ihr Arbeitsbaum sauber ist.

  • Setzen Sie den Rebase mit fort git rebase --continue.

Wenn Sie nicht absolut sicher sind, ob die Zwischenrevisionen konsistent sind (sie werden kompiliert, bestehen die Testsuite usw.), sollten Sie git stashdie noch nicht festgeschriebenen Änderungen nach jedem Festschreiben speichern, testen und das Festschreiben ändern, wenn Korrekturen erforderlich sind .


quelle
Denken Sie unter Windows daran, dass es sich ^um ein Escape-Zeichen für die Befehlszeile handelt: Es sollte verdoppelt werden. Zum Beispiel Ausgabe git reset HEAD^^statt git reset HEAD^.
Frédéric
@ Frédéric: s Ich bin noch nie darauf gestoßen. Zumindest in PowerShell ist dies nicht der Fall. Durch ^zweimaliges Zurücksetzen werden zwei Commits über dem aktuellen HEAD zurückgesetzt.
Farway
@Farway, versuchen Sie es in einer klassischen Befehlszeile. PowerShell ist ein ganz anderes Biest, sein Fluchtcharakter ist die Neigung.
Frédéric
Zusammenfassend: "HEAD^"in cmd.exe oder PowerShell, HEAD^^in cmd.exe, HEAD`^in PowerShell. Es ist hilfreich zu erfahren, wie Shells - und Ihre spezielle Shell - funktionieren (dh wie ein Befehl in einzelne Teile umgewandelt wird, die an das Programm übergeben werden), damit Sie Befehle online an die richtigen Zeichen für Ihre bestimmte Shell anpassen können. (Nicht spezifisch für Windows.)
AndrewF
11

Mit dem neuesten TortoiseGit unter Windows können Sie dies jetzt ganz einfach tun.

Öffnen Sie den Rebase-Dialog, konfigurieren Sie ihn und führen Sie die folgenden Schritte aus.

  • Klicken Sie mit der rechten Maustaste auf das Commit, das Sie teilen möchten, und wählen Sie " Edit" (zwischen Auswählen , Squash, Löschen ...).
  • Klicken Sie auf " Start", um die Neubasierung zu starten.
  • Sobald das Commit zum Teilen erreicht ist, Edit/Splitaktivieren Sie die Schaltfläche " " und klicken Sie Amenddirekt auf " ". Der Commit-Dialog wird geöffnet.
    Commit bearbeiten / teilen
  • Deaktivieren Sie die Dateien, die Sie für ein separates Commit festlegen möchten.
  • Bearbeiten Sie die Festschreibungsnachricht und klicken Sie dann auf " commit".
  • Bis Dateien festgeschrieben werden müssen, wird der Festschreibungsdialog immer wieder geöffnet. Wenn keine Datei mehr festgeschrieben werden muss, werden Sie trotzdem gefragt, ob Sie eine weitere Festschreibung hinzufügen möchten.

Sehr hilfreich, danke TortoiseGit!

Mikaël Mayer
quelle
10

Sie können eine interaktive Rebase durchführen git rebase -i. Manpage hat genau das, was Sie wollen:

http://git-scm.com/docs/git-rebase#_splitting_commits

Manojlds
quelle
14
Ein bisschen mehr Kontext zu geben, wie man die Probleme angeht, anstatt nur ein RTFM zu geben, wäre ein bisschen hilfreicher.
Jordan Dea-Mattson
8

Bitte beachten Sie, dass es auch gibt git reset --soft HEAD^. Es ähnelt git reset(standardmäßig --mixed), behält jedoch den Indexinhalt bei. Wenn Sie also Dateien hinzugefügt / entfernt haben, haben Sie diese bereits im Index.

Es stellt sich heraus, dass es bei riesigen Commits sehr nützlich ist.

tödlicher Mann
quelle
3

Hier erfahren Sie , wie Sie ein Commit in IntelliJ IDEA , PyCharm , PhpStorm usw. Aufteilen

  1. Wählen Sie im Protokollfenster der Versionskontrolle das Commit aus, das Sie teilen möchten, klicken Sie mit der rechten Maustaste und wählen Sie das aus Interactively Rebase from Here

  2. Markieren Sie diejenige, als die Sie teilen möchten, editund klicken Sie aufStart Rebasing

  3. Sie sollten sehen, dass ein gelbes Tag platziert ist, was bedeutet, dass der HEAD auf dieses Commit eingestellt ist. Klicken Sie mit der rechten Maustaste auf dieses Commit und wählen SieUndo Commit

  4. Jetzt sind diese Commits wieder im Staging-Bereich. Sie können sie dann separat festschreiben. Nachdem alle Änderungen festgeschrieben wurden, wird das alte Festschreiben inaktiv.

bzuo
quelle
2

Ohne eine interaktive Rebase ist es am einfachsten, (wahrscheinlich) einen neuen Zweig zu erstellen, der mit dem Commit beginnt, bevor der, den Sie teilen möchten, das Commit auswählt, zurücksetzt, speichert, die Datei verschiebt, den Stash erneut anwendet und Übernehmen Sie die Änderungen, und führen Sie sie dann entweder mit dem früheren Zweig zusammen oder wählen Sie die folgenden Festschreibungen aus. (Wechseln Sie dann den früheren Filialnamen in den aktuellen Kopf.) (Es ist wahrscheinlich besser, den Ratschlägen von MBOs zu folgen und eine interaktive Rebase durchzuführen.)

William Pursell
quelle
Laut SO-Standards sollte dies heutzutage als Nicht-Antwort qualifiziert werden. Aber dies kann immer noch für andere hilfreich sein. Wenn es Ihnen nichts ausmacht, verschieben Sie dies bitte in die Kommentare des ursprünglichen Beitrags
YakovL
@ YakovL Scheint vernünftig. Nach dem Prinzip der minimalen Aktion werde ich die Antwort nicht löschen, aber ich würde nichts dagegen haben, wenn es jemand anderes tut.
William Pursell
Dies wäre viel einfacher als alle rebase -iVorschläge. Ich denke, dass dies aufgrund fehlender Formatierung nicht viel Beachtung fand. Vielleicht könnten Sie es überprüfen, jetzt, wo Sie 126.000 Punkte haben und wahrscheinlich wissen, wie man SO. ;)
erikbwork
1

Wenn Sie dies haben:

A - B <- mybranch

Wo Sie in Commit B Inhalte festgeschrieben haben:

/modules/a/file1
/modules/a/file2
/modules/b/file3
/modules/b/file4

Aber Sie möchten B in C - D aufteilen und dieses Ergebnis erhalten:

A - C - D <-mybranch

Sie können den Inhalt beispielsweise so aufteilen (Inhalte aus verschiedenen Verzeichnissen in verschiedenen Commits) ...

Setzen Sie den Zweig zurück auf das Commit vor dem zu teilenden:

git checkout mybranch
git reset --hard A

Erstes Commit erstellen (C):

git checkout B /modules/a
git add -u
git commit -m "content of /modules/a"

Erstes zweites Commit erstellen (D):

git checkout B /modules/b
git add -u
git commit -m "content of /modules/b"
Martin G.
quelle
Was ist, wenn es Commits über B gibt?
CoolMind
1

Es ist mehr als 8 Jahre her, aber vielleicht findet es trotzdem jemand hilfreich. Ich konnte den Trick ohne machen rebase -i. Die Idee ist, Git in den Zustand zu führen, in dem es vor Ihnen war git commit:

# first rewind back (mind the dot,
# though it can be any valid path,
# for instance if you want to apply only a subset of the commit)
git reset --hard <previous-commit> .

# apply the changes
git checkout <commit-you-want-to-split>

# we're almost there, but the changes are in the index at the moment,
# hence one more step (exactly as git gently suggests):
# (use "git reset HEAD <file>..." to unstage)
git reset

Danach sehen Sie dies glänzend Unstaged changes after reset:und Ihr Repo befindet sich in einem Zustand, in dem Sie alle diese Dateien festschreiben möchten. Von nun an können Sie es einfach wieder festschreiben, wie Sie es normalerweise tun. Ich hoffe es hilft.

Stanislav E. Govorov
quelle
0

Eine kurze Referenz der notwendigen Befehle, da ich im Grunde weiß, was zu tun ist, aber immer die richtige Syntax vergesse:

git rebase -i <sha1_before_split>
# mark the targeted commit with 'edit'
git reset HEAD^
git add ...
git commit -m "First part"
git add ...
git commit -m "Second part"
git rebase --continue

Dank an Emmanuel Bernards Blogbeitrag .

Sparkofska
quelle