Zum Beispiel gibt ein git status
Folgendes:
(Ich habe die Dateinamen ausgeblendet)
Wie würde ich nur die Änderungen speichern, die ich git add
ed habe (d. h. "Änderungen werden festgeschrieben", nicht nicht geänderte Änderungen oder nicht aufgezeichnete Dateien), damit ich sie stattdessen in einen anderen Zweig übertragen kann?
Der grundlegende Speichermechanismus von Git ist "das Commit" - tatsächlich macht% git stash
ein paar etwas ungewöhnliche Commits - also Nick Volynkins Antwort ist richtig. Es könnte vielleicht ein wenig Expansion verwenden, und es gibt einfachere (gut, möglicherweise leichter) Methoden.
Ich bin kein großer Fan von git stash
, aber wenn Sie daran gewöhnt sind, ist hier die einfachste der anderen Methoden:
git stash save
(aka git stash
). Dies schreibt zwei Commits, einen basierend auf dem aktuellen Index und einen zweiten, um noch nicht gespeicherte Arbeitsbaumdateien zu speichern. (Wenn Sie untracked -Dateien aufbewahren müssen, können Sie das Flag -u
hinzufügen, und dann fügt das Stash-Skript noch ein drittes Commit hinzu. Normalerweise können Sie diese nicht verfolgten Dateien einfach in Ihrem Arbeitsbaum herumlaufen lassen untracked, though.) Diese Commits sind auf keinem Zweig, sie sind nur auf / in der speziellen "Stash" Ref. In der Zwischenzeit befinden Sie sich immer noch im "falschen" Zweig, den ich wrongbr
nennen werde.
git checkout
der Zweig, in dem Sie diese möchten. Jetzt sind Sie auf der rechten Seite.
git stash apply --index
. Dies verwendet die speziellen Stash-Commits, die in Schritt 1 gemacht wurden, während sie auch im Stash verbleiben ( apply
). Das --index
ist sehr wichtig: es teilt dem Stash-Skript mit, dass es den Index und die nicht gesicherten Dateien getrennt hält, d. H. Sie gibt Ihnen das gestaffelte und nicht gespeicherte Setup zurück, das Sie zuvor hatten.
Wenn alles gut geht, können Sie jetzt git commit
an der Verzweigung ändern, in der Sie sie haben möchten. Die zuvor gestaffelten Dateien werden erneut bereitgestellt, und die nicht gespeicherten Dateien sind immer noch nicht gespeichert, da Sie% std% %% das Versteck mit apply
verwaltet haben. Durch das Festschreiben werden die gestaffelten Dateien festgeschrieben, sodass die nicht gespeicherten Dateien nicht verschoben werden.
Nun können Sie wieder in den anderen "falschen" Zweig (wo Sie den Stash zuerst gemacht haben) und --index
oder git stash apply
mit oder ohne git stash pop
zurückkehren. Sie müssen eventuell nicht gespeicherte Dateien bereinigen (und es ist sicher, dass sie sich noch im Stash befinden): --index
, gefolgt von git reset --hard
, dann git checkout wrongbr
. Beachte, dass git stash pop
nur pop
gefolgt von apply
ist: wir wollten nicht drop den Stash in Schritt 3 (der Stash hat die einzige Kopie von die ursprünglich modifizierten, aber nicht gesicherten Dateien, weshalb wir drop
dort verwendet haben, aber nun wollen wir (vermutlich) tun den Stash löschen, also ist apply
in Ordnung.
In Schritt 3 gibt es jedoch eine große potentielle Falle: Es ist möglich, dass der Stash nicht korrekt angewendet wird. Wenn ja, müssen Sie eine andere Methode verwenden. Dies ist einer der Gründe, warum ich das pop
System nicht wirklich mag: Es fällt in schweren Fällen hin und es müssen Sie wissen, welche Werkzeuge Sie verwenden können, wenn Sie stash
nicht verwenden. In diesem Fall können Sie diese Tools meistens verwenden ... und dann stash
als bequeme Abkürzung für Fälle verwenden, in denen Sie sicher sind, dass es funktioniert.
Hintergrund: Ein Commit nimmt alles was jetzt im Index ist - stash
zeigt den kompletten Inhalt an, während git ls-files --cached
dies auf die "interessanten" runterzählt und zusätzliche nützliche Informationen hinzufügt - und diese aus Commits macht mit allen notwendigen Baumobjekten und so weiter. Das übergeordnete Commit des neuen Commits ist unabhängig vom aktuellen Commit.
Sie möchten, dass Ihr neues Commit in einem anderen Zweig ausgeführt wird. Eine Möglichkeit, dies zu tun, besteht darin, es jetzt auf dem aktuellen Zweig zu machen; Kopieren Sie dann dieses Commit in ein neues, anderes Commit in einem anderen Zweig. Um den "Copy commit to new, anderen Commit auf verschiedenen Zweigen" zu machen, können Sie git status
verwenden. Es stimmt, dass Sie git cherry-pick
verwenden können: Unter den Deckeln wird git rebase
selbst verwendet. Aber git cherry-pick
ist nicht gerade das richtige Werkzeug: Es ist für das Massen-Rosinenpicken ausgelegt, und Sie haben nur ein Commit; und am Ende benutzt es rebase
, um ein Zweig-Label zu verschieben, aber nicht so, wie Sie es wollen. Sie können es zum Laufen bringen, aber es gibt einige geeignetere Werkzeuge.
Kommen wir nun zum ursprünglichen Problem zurück: Sie wollen den aktuellen Index nehmen und ihn verwenden, um ein neues Commit zu machen, aber in einem anderen Zweig . Dies wäre am einfachsten, wenn Sie jetzt einfach zum anderen Zweig wechseln könnten, ohne etwas anderes zu tun, und dann das neue Commit durchführen.
Die Chancen stehen gut, dass Sie dies tun können. Nur git reset
und dann git checkout otherbranch
. Hier gibt es drei mögliche Fälle:
Der andere Zweig existiert noch nicht. Groß! Verwenden Sie git commit
, um es zu erstellen, ausgehend von wo Sie jetzt sind. Dann git checkout -b newbranch
. Sie sind fertig, es sei denn, Sie möchten, dass der neue Zweig von einem anderen Ort als "wo Sie jetzt sind" gestartet wird. Wenn ja, verwende git commit
für den neuen Zweig. Beachten Sie, dass Sie diese Rebase später ausführen können, nachdem Sie sich um die nicht gespeicherten Dateien gekümmert haben.
Der andere Zweig existiert, und - glücklicherweise - git rebase
funktioniert gut. Mach das und begehe, und du bist fertig. Sie können dann git checkout otherbranch
den gewünschten Zweig für die nicht gespeicherten Dateien angeben.
Der ärgerlichste Fall: Der andere Zweig existiert, aber git checkout
sagt Ihnen, dass Sie etwas überschreiben werden, das Sie nicht festgelegt haben.
Fall 3 ist der Fall, in dem Sie einen Commit-or-stash durchführen müssen.
Was hier zu tun ist, hängt davon ab, mit was Sie sich am wohlsten fühlen. Sie können zum Beispiel die oben beschriebene vierstufige git checkout
-Methode als einfachste Alternative ausprobieren.
Für mich selbst würde ich mich jetzt jedoch auf den "falschen" Zweig festlegen und dann erneut Commit machen (oder stash
verwenden), um die nicht gespeicherten Dateien aus dem Weg zu räumen. Dies gibt mir ein Commit Ich kann git stash
in den rechten Zweig. Hier ist eine Beispielsequenz, die wahrscheinlich funktioniert:
git cherry-pick
, um das Commit zu machen, aber auf dem "falschen" Zweig (nennen wir Ihren aktuellen Zweig git commit
als Referenz unten). wrongbr
, um die nicht geänderten Änderungen zu speichern (oder, mit git stash save
, auch nicht nachverfolgte Dateien). -u
der Zweig, in dem der Commit ausgeführt werden soll, z. B. git checkout
. git checkout rightbr
das Ergebnis. git cherry-pick wrongbr
: Wir werden dies nun beheben, indem wir das in Schritt 4 kopierte Commit entfernen. git commit
: Dadurch wird das von uns kopierte Commit gelöscht. git checkout wrongbr
(oder git reset --hard HEAD^
, was das gleiche tut, die git stash pop
Variante gibt Ihnen einfach die Möglichkeit, das Ergebnis zu überprüfen, bevor Sie git stash apply && git stash drop
das Stash). Beachten Sie Schritt 4 hier: apply
nimmt das benannte Commit (die Spitze von drop
, die das commit-we-will enthält, das einfach auf dem falschen Zweig liegt), vergleicht es mit seinem übergeordneten und versucht dann, das resultierende Diff auf den aktuellen Zweig anzuwenden. Dies kann eine 3-Wege-Zusammenführung erfordern, wenn die Dateien im aktuellen Zweig sich stark von den entsprechenden Dateien in git cherry-pick
unterscheiden. Dies ist der gleiche Ort, an dem die Komplikationen im einfachen Fall auftreten, wenn Sie wrongbr
nur auschecken und initiieren. Das heißt, wir machen diese lange Version, weil der "ärgerlichste" Fall auftrat, als wir vor dem Commit nur wrongbr
versuchten, also besteht eine gute Chance, dass wir etwas reparieren müssen. Dies verursacht wahrscheinlich auch Probleme mit der ursprünglichen 4-stufigen rightbr
-Methode.
Verwahren Sie alles, aber behalten Sie den Index
git stash --keep-index
Verstecke den Index, der nach dem Stash in Schritt 1 übrig bleibt.
git stash
Erstelle oder verlasse den Vorrat, der alles enthält, den aus Schritt 1. (Er wird jetzt als stash@{1}
bezeichnet, weil der Vorrat von step 2.
bei stash@{0}
platziert ist.
%Code%
Oder
git stash pop stash@{1}
Optional (Wenn Sie
git stash drop stash@{1}
den Stash in Schritt git stash pop..
haben, aber 3.
die Dateien, die ursprünglich zum Index hinzugefügt wurden, die in reset
stash@{0}