Sie sollten den Index verwenden. Fügen Sie nach einem gemischten Reset (" git reset HEAD ^") die ersten Änderungen in den Index ein und schreiben Sie sie fest. Dann legen Sie den Rest fest.
Mit " git add " können Sie alle in einer Datei vorgenommenen Änderungen in den Index einfügen. Wenn Sie nicht jede in einer Datei vorgenommene Änderung vornehmen möchten, sondern nur einige, können Sie "git add -p" verwenden.
Sehen wir uns ein Beispiel an. Nehmen wir an, ich hätte eine Datei namens myfile, die den folgenden Text enthält:
something
something else
something again
Ich habe es in meinem letzten Commit so geändert, dass es jetzt so aussieht:
1
something
something else
something again
2
Jetzt entscheide ich, dass ich es in zwei Teile teilen möchte, und ich möchte, dass die Einfügung der ersten Zeile im ersten Commit und das Einfügen der letzten Zeile im zweiten Commit erfolgt.
Zuerst gehe ich zurück zu HEADs Eltern, aber ich möchte die Änderungen im Dateisystem beibehalten, also verwende ich "git reset" ohne Argument (was einen sogenannten "gemischten" Reset bewirkt):
$ git reset HEAD^
myfile: locally modified
$ cat myfile
1
something
something else
something again
2
Jetzt benutze ich "git add -p", um die Änderungen, die ich in den Index übernehmen möchte, hinzuzufügen (= ich stelle sie bereit). "git add -p" ist ein interaktives Tool, das Sie fragt, welche Änderungen an der Datei vorgenommen werden sollen, wenn sie dem Index hinzugefügt werden.
$ git add -p myfile
diff --git a/myfile b/myfile
index 93db4cb..2f113ce 100644
--- a/myfile
+++ b/myfile
@@ -1,3 +1,5 @@
+1
something
something else
something again
+2
Stage this hunk [y,n,a,d,/,s,e,?]? s # split this section into two!
Split into 2 hunks.
@@ -1,3 +1,4 @@
+1
something
something else
something again
Stage this hunk [y,n,a,d,/,j,J,g,e,?]? y # yes, I want to stage this
@@ -1,3 +2,4 @@
something
something else
something again
+2
Stage this hunk [y,n,a,d,/,K,g,e,?]? n # no, I don't want to stage this
Dann begebe ich diese erste Änderung:
$ git commit -m "Added first line"
[master cef3d4e] Added first line
1 files changed, 1 insertions(+), 0 deletions(-)
Jetzt kann ich alle anderen Änderungen übernehmen (nämlich die in die letzte Zeile eingegebene Ziffer "2"):
$ git commit -am "Added last line"
[master 5e284e6] Added last line
1 files changed, 1 insertions(+), 0 deletions(-)
Lassen Sie uns das Protokoll überprüfen, um festzustellen, welche Commits wir haben:
$ git log -p -n2 | cat
Commit 5e284e652f5e05a47ad8883d9f59ed9817be59d8
Author: ...
Date: ...
Added last line
Diff --git a/myfile b/myfile
Index f9e1a67..2f113ce 100644
--- a/myfile
+++ b/myfile
@@ -2,3 +2,4 @@
something
something else
something again
+2
Commit cef3d4e0298dd5d279a911440bb72d39410e7898
Author: ...
Date: ...
Added first line
Diff --git a/myfile b/myfile
Index 93db4cb..f9e1a67 100644
--- a/myfile
+++ b/myfile
@@ -1,3 +1,4 @@
+1
something
something else
something again
git reset [--patch|-p] <commit>
, mit dem Sie sich die Mühe ersparen können, die Siegit add -p
nach dem Zurücksetzen benötigen. Habe ich recht? Verwenden von git 1.7.9.5.Tore:
splitme
) in zwei Teile teilen .Planen:
splitme
.splitme
.Die Rebase-Schritte (1 & 7) können übersprungen werden, wenn dies das
splitme
letzte Commit ist.Wenn ich wollte, dass die geteilten Dateien zuerst festgeschrieben werden, würde ich dann -i erneut neu starten und die Reihenfolge ändern
quelle
git reset HEAD^
war das fehlende Puzzleteil. Funktioniert auch gut mit-p
. Vielen Dank!-- $files
Argument zu beachtengit reset
.git reset
Stellt diese Dateien bei übergebenen Pfaden den Status des referenzierten Commits wieder her, ändert jedoch keine Commits. Wenn Sie die Pfade weglassen, "verlieren" Sie das Commit, das Sie im nächsten Schritt ändern möchten.git reset HEAD^ -- .
. Sehr überraschend ist dies nicht genau das Verhalten vongit reset HEAD^
.Um das aktuelle Commit in zwei Commits zu ändern, können Sie Folgendes tun.
Entweder:
Dies macht das letzte Commit rückgängig, lässt aber alles inszeniert. Sie können dann bestimmte Dateien entfernen:
Optional können Teile dieser Dateien wiederhergestellt werden:
Machen Sie ein neues erstes Commit:
Die Phase und das Festschreiben der restlichen Änderungen in einem zweiten Festschreiben:
Oder:
Machen Sie alle Änderungen gegenüber dem letzten Commit rückgängig und entfernen Sie sie:
Führen Sie die erste Änderungsrunde selektiv durch:
Verpflichten:
Übernehmen Sie den Rest der Änderungen:
(Wenn Sie in einem der beiden Schritte ein Commit rückgängig machen, das eine brandneue Datei hinzugefügt hat, und dieses zum zweiten Commit hinzufügen möchten, müssen Sie es manuell hinzufügen, da
commit -a
nur Änderungen an bereits verfolgten Dateien schrittweise vorgenommen werden.)quelle
Führen
git gui
Sie " Ausführen " aus, aktivieren Sie das Optionsfeld "Letztes Commit ändern" und deaktivieren Sie (Commit> Unstage From Commit oder Ctrl- U) Änderungen, die Sie nicht in das erste Commit übernehmen möchten. Ich denke, das ist der einfachste Weg, dies zu tun.Sie können die Änderung auch ohne Festschreiben (
git cherry-pick -n
)git gui
auswählen und dann entweder manuell oder mit den gewünschten Änderungen auswählen, bevor Sie sie festschreiben.quelle
Das --hard ist das, was deine Veränderungen tötet.
quelle
Ich bin überrascht, dass niemand vorgeschlagen hat
git cherry-pick -n forum
. Dadurch werden die Änderungen aus dem letztenforum
Commit bereitgestellt , aber nicht festgeschrieben. Sie können dannreset
die nicht benötigten Änderungen entfernen und festschreiben, was Sie behalten möchten.quelle
Die Double-Revert-Squash-Methode
git checkout HEAD~1 -- files with unwanted changes
undgit commit
. Wenn nicht, können Dateien mit gemischten Änderungen teilweisegit reset file
undgit add -p file
als Zwischenschritt bereitgestellt werden.) Nennen Sie dies das Zurücksetzen .git revert HEAD
- Machen Sie noch ein Commit, das die unerwünschten Änderungen wieder hinzufügt. Dies ist die doppelte Rückkehrgit rebase -i HEAD~3
). Dieses Commit wird jetzt frei von unerwünschten Änderungen, da diese im zweiten Commit enthalten sind.Leistungen
quelle
Da Sie Kirschen pflücken, können Sie:
cherry-pick
es mit--no-commit
Option hinzugefügt.reset
und verwendenadd --patch
,add --edit
oder nuradd
zu Stufe , was Sie wollen halten.commit
die inszenierten Änderungen.--reuse-message=<old-commit-ref>
oder--reedit-message=<old-commit-ref>
Optionen hinzufügencommit
.reset --hard
.Eine andere Möglichkeit, die ursprüngliche Festschreibungsnachricht beizubehalten oder zu bearbeiten:
cherry-pick
das ursprüngliche Commit wie gewohnt.add
, um die Umkehrung durchzuführen.commit --amend
um die Umkehrung des von Kirschen gepflückten Commits zu bewirken.quelle
Dies könnte eine weitere Lösung sein, die für Fälle vorgesehen ist, in denen ein großer Commit vorliegt und eine kleine Menge von Dateien in einen neuen Commit verschoben werden muss. Dies funktioniert, wenn eine Reihe von
<path>
Dateien aus dem letzten Commit bei HEAD extrahiert und alle in ein neues Commit verschoben werden sollen. Wenn mehrere Commits erforderlich sind, können die anderen Lösungen verwendet werden.Erstellen Sie zunächst Patches in den bereitgestellten und nicht bereitgestellten Bereichen, die die Änderungen enthalten, auf die der Code vor und nach der Änderung zurückgesetzt werden soll:
Um zu verstehen, was passieren wird (Pfeil und Kommentare sind nicht Teil des Befehls):
<path>
Änderungen im letzten Commit rückgängig machen :Erstellen Sie ein neues Commit mit
<path>
Änderungen:Dies hat zur Folge, dass ein neues Commit erstellt wird, das die Änderungen enthält, die aus dem letzten Commit extrahiert wurden.
quelle