Wie speichern Sie nur Dateien, die hinzugefügt wurden?

8

Zum Beispiel gibt ein git status Folgendes:

%Vor%

(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?

    
peter-b 20.05.2015, 20:37
quelle

3 Antworten

11

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:

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

  2. git checkout der Zweig, in dem Sie diese möchten. Jetzt sind Sie auf der rechten Seite.

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

  4. 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:

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

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

  3. 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:

  1. git cherry-pick , um das Commit zu machen, aber auf dem "falschen" Zweig (nennen wir Ihren aktuellen Zweig git commit als Referenz unten).
  2. wrongbr , um die nicht geänderten Änderungen zu speichern (oder, mit git stash save , auch nicht nachverfolgte Dateien).
  3. -u der Zweig, in dem der Commit ausgeführt werden soll, z. B. git checkout .
  4. %Code%. Wenn das gelingt, gut; Wenn nicht, bearbeiten Sie die Dateien nach Bedarf, um nach den Zusammenführungsproblemen aufzuräumen, und dann git checkout rightbr das Ergebnis.
  5. git cherry-pick wrongbr : Wir werden dies nun beheben, indem wir das in Schritt 4 kopierte Commit entfernen.
  6. git commit : Dadurch wird das von uns kopierte Commit gelöscht.
  7. 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.

    
torek 20.05.2015, 22:20
quelle
3

Übernehmen Sie diese Dateien und setzen Sie das Commit neu.

    
Nick Volynkin 20.05.2015 20:49
quelle
1
  1. Verwahren Sie alles, aber behalten Sie den Index git stash --keep-index

  2. Verstecke den Index, der nach dem Stash in Schritt 1 übrig bleibt. git stash

  3. 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}

  4. 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}

kilogic 26.07.2017 17:43
quelle

Tags und Links