Ich habe zwei Zweige, master
und forum
und ich habe gerade einige Änderungen vorgenommen forum
in die ich gerne reinpicke master
. Aber leider enthält der Commit, den ich mir aussuchen möchte, auch einige Modifikationen, die ich nicht möchte.
Die Lösung wäre wahrscheinlich, den falschen Commit irgendwie zu löschen und ihn durch zwei separate Commits zu ersetzen, einen mit Änderungen, die ich übernehmen möchte master
die andere mit den restlichen Änderungen.
Ich habe es versucht
git reset --hard HEAD^
wodurch alle Änderungen gelöscht wurden, also musste ich mit zurückgehen
git reset ORIG_HEAD
Also meine Frage ist, wie geht das am besten Teilt das letzte Commit in zwei separate Commits?
Sie sollten den Index verwenden. Nach einem gemischten Reset (“git zurücksetzen HEAD^”), füge den ersten Satz von Änderungen in den Index ein und übertrage sie dann. Übertrage dann den Rest.
Sie können “git hinzufügen“, um alle in einer Datei vorgenommenen Änderungen in den Index aufzunehmen. Wenn Sie nicht jede in einer Datei vorgenommene Änderung bereitstellen möchten, sondern nur einige davon, 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 aufteilen möchte, und ich möchte, dass die Einfügung der ersten Zeile im ersten Commit erfolgt und die Einfügung der letzten Zeile im zweiten Commit.
Zuerst gehe ich zurück zu HEADs übergeordnetem Element, aber ich möchte die Änderungen im Dateisystem behalten, also verwende ich “git reset” ohne Argument (was einen sogenannten “gemischten” Reset durchführt):
$ git reset HEAD^
myfile: locally modified
$ cat myfile
1
something
something else
something again
2
Jetzt verwende ich “git add -p”, um die Änderungen, die ich festschreiben möchte, dem Index hinzuzufügen (= ich stelle sie bereit). “git add -p” ist ein interaktives Tool, das Sie fragt, welche Änderungen an der Datei dem Index hinzugefügt werden sollen.
$ 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 übertrage 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 Zahl “2” in der letzten Zeile):
$ 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 zu sehen, 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
Ziele:
- Ich möchte einen vergangenen Commit aufteilen
$splitme
in zwei.
- ich will Behalten Sie die Commit-Nachricht bei.
Planen:
- Rebasen Sie Interactive auf den übergeordneten Commit von
$splitme
Markierung $splitme
als edit
.
- Unstage die Dateien, die nicht Teil des ersten Commit sein sollen.
- Ändern Sie das aktuelle Commit, behalten Sie die Commit-Nachricht bei und ändern Sie sie bei Bedarf.
- Stellen Sie die Dateien zurück, die beim ersten Commit ausgelassen wurden.
- Commit, mit einer neuen Nachricht.
- Rebase fortsetzen.
Die Rebase-Schritte (1 und 7) können übersprungen werden, wenn die $splitme
ist das neueste Commit.
git rebase -i $splitme^ # mark $splitme as edit
git reset HEAD^ -- $files
git commit --amend
git add $files
git commit
git rebase --continue
Wenn ich die Dateien im ersten Commit mit den Dateien im zweiten Commit austauschen wollte, würde ich dann wieder interaktiv rebasen und ihre Commit-Zeile austauschen.
Um den aktuellen Commit in zwei Commits zu ändern, können Sie etwa Folgendes tun.
Entweder:
git reset --soft HEAD^
Dies macht den letzten Commit rückgängig, lässt aber alles inszeniert. Sie können dann bestimmte Dateien aus der Staging-Phase entfernen:
git reset -- file.file
Optional können Sie Teile dieser Dateien erneut inszenieren:
git add -p file.file
Machen Sie einen neuen ersten Commit:
git commit
Stellen Sie die restlichen Änderungen bereit und übertragen Sie sie in einem zweiten Commit:
git commit -a
Oder:
Machen Sie alle Änderungen seit dem letzten Commit rückgängig und entfernen Sie die Bereitstellung:
git reset HEAD^
Selektiv die erste Änderungsrunde inszenieren:
git add -p
Begehen:
git commit
Übernehmen Sie die restlichen Änderungen:
git commit -a
(Wenn Sie in beiden Schritten einen Commit rückgängig gemacht haben, der eine brandneue Datei hinzugefügt hat, und diese zum zweiten Commit hinzufügen möchten, müssen Sie sie manuell als hinzufügen commit -a
stellt nur Änderungen an bereits verfolgten Dateien bereit.)
Laufen git gui
wählen Sie das Optionsfeld “Letzten Commit ändern” und heben Sie die Bereitstellung auf (Commit > Unstage From Commit oder Strg–U) Änderungen, die Sie nicht in den ersten Commit aufnehmen möchten. Ich denke, das ist der einfachste Weg, dies zu tun.
Eine andere Sache, die Sie tun könnten, ist, die Änderung herauszupicken, ohne sich zu verpflichten (git cherry-pick -n
) und dann entweder manuell oder mit git gui
Wählen Sie die gewünschten Änderungen aus, bevor Sie sie bestätigen.
git reset HEAD^
das –hard ist das, was Ihre Änderungen zerstört.
Ich bin überrascht, dass niemand vorgeschlagen hat git cherry-pick -n forum
. Dadurch werden die Änderungen vom letzten inszeniert forum
begehen, aber nicht begehen – dann können Sie reset
Entfernen Sie die Änderungen, die Sie nicht benötigen, und schreiben Sie fest, was Sie behalten möchten.