Git-Stash: "Kann nicht auf einen schmutzigen Arbeitsbaum angewendet werden, bitte stellen Sie Ihre Änderungen bereit"


133

Ich versuche, Änderungen anzuwenden, mit denen ich zuvor verwahrt habe, git stash popund erhalte die folgende Nachricht:

Cannot apply to a dirty working tree, please stage your changes

Irgendwelche Vorschläge, wie man damit umgeht?

Antworten:


196

Wenn ich versteckte Änderungen auf eine schmutzige Arbeitskopie anwenden muss, z. B. mehr als einen Änderungssatz aus dem Stash entfernen möchte, verwende ich Folgendes:

$ git stash show -p | git apply -3 && git stash drop

Grundsätzlich ist es

  1. erstellt einen Patch
  2. leitet das an den Befehl apply weiter
  3. Wenn es Konflikte gibt, müssen diese durch 3-Wege-Zusammenführung gelöst werden
  4. Wenn das Anwenden (oder Zusammenführen) erfolgreich war, wird das gerade angewendete Stash-Element gelöscht ...

Ich frage mich, warum es keine -f(Kraft-) Option gibt, für git stash popdie sich genau wie der Einzeiler oben verhalten sollte.

In der Zwischenzeit möchten Sie diesen Einzeiler möglicherweise als Git-Alias ​​hinzufügen:

$ git config --global --replace-all alias.unstash \
   '!git stash show -p | git apply -3 && git stash drop'
$ git unstash

Vielen Dank an @SamHasler für den Hinweis auf den -3Parameter, mit dem Konflikte direkt über 3-Wege-Zusammenführung gelöst werden können.


Ist git stash show -p | git applyanders als git stash apply?
Faktor Mystic

1
Jo Factor git stash applyübernimmt die versteckten Änderungen nicht, wenn Sie eine schmutzige Arbeitskopie haben. Sie können also sehen, git stash show -p | git applywie eine Art erzwungenes Versteck angewendet wird .
Muhqu

1
hilft nicht aber hilft: git setze HEAD zurück und lösche danach die Änderungen.
Roger Alien

4
Ich erhalte "Fehler: Patch fehlgeschlagen ... Patch gilt nicht" für eine der Dateien. Ich wünschte, es hätte einen Zusammenführungskonflikt gegeben.
Aleksandr Dubinsky

1
Diese Lösung hat bei mir nicht funktioniert, sie ist bei error: <file> does not match indexjeder geänderten Datei fehlgeschlagen . Eine andere Lösung funktionierte jedoch.
Silvenon

57

Ich mache es so:

git add -A
git stash apply

und dann (optional):

git reset

2
+1! Dies ist einfacher als die anderen Lösungen, bei denen Patches generiert oder Commits geändert werden, und Ihre lokalen Änderungen werden sicher von den angewendeten Stash-Änderungen isoliert, bis Sie sicher sind, dass die Änderungen ordnungsgemäß zusammengeführt wurden.
Peterflynn

Ich erhalte die Fehlermeldung "... existiert bereits, keine Kasse ... Unverfolgbare Dateien konnten nicht aus dem Stash wiederhergestellt werden"
Aleksandr Dubinsky

2
Ich habe verwendet git add -u, was so ist, -Aaußer dass es keine nicht verfolgten Dateien hinzufügt.
Brad Cupit

9

Sie können dies tun, ohne Ihre aktuellen Änderungen speichern zu müssen, indem Sie den gewünschten Speicher als Patch-Datei exportieren und manuell anwenden.

Angenommen, Sie möchten stash @ {0} auf einen schmutzigen Baum anwenden:

  1. Exportieren Sie stash @ {0} als Patch:

    git stash show -p stash @ {0}> Stash0.patch

  2. Übernehmen Sie die Änderungen manuell:

    Git anwenden Stash0.patch

Wenn der zweite Schritt fehlschlägt, müssen Sie die Datei Stash0.patch bearbeiten, um Fehler zu beheben, und dann erneut versuchen, git apply anzuwenden.


Dies ist praktisch und praktikabel für den Fall, dass ich ein Verzeichnis umgestaltet habe (es entfernt und einen Symlink mit seinem Namen erstellt habe). Git konnte nicht sagen, was meine Änderungen an der Arbeitskopie waren.
Yclian

1
Das hat super geklappt. Ich konnte keinen Stash anwenden, obwohl ich mir ziemlich sicher bin, dass mein Arbeitsbaum sauber ist.
Shiki

Ja, ich musste Zeilen über eine Binärdatei entfernen.
Dorian

8

Bereinigen Sie entweder Ihr Arbeitsverzeichnis mit git reset, übernehmen Sie die Änderungen oder versuchen Sie Folgendes, wenn Sie die aktuellen Änderungen speichern möchten:

$ git stash save "Beschreibung der aktuellen Änderungen"
$ git stash pop stash @ {1}

Dadurch werden die aktuellen Änderungen gespeichert und dann der zweite Speicher aus dem Stapel gestapelt.


5
Aber dieser Typ möchte, dass die beiden Verstecke angewendet werden!
Elazar Leibovich

@ Elzar Sie lesen in die Frage. Das OP möchte lediglich einen vorherigen Vorrat anwenden. Wenn Sie richtig sind, dass die aktuellen Änderungen beibehalten werden sollen, kann die Lösung wiederholt werden: Pop, Commit, Repeat.
William Pursell

Ich denke, er möchte, dass beide nicht verpflichtet sind. Andererseits kann er sie zweimal festschreiben und zu einem einzigen Festschreiben zusammenfassen.
Elazar Leibovich

Ich erhalte die Fehlermeldung "... existiert bereits, keine Kasse ... Unverfolgbare Dateien konnten nicht aus dem Stash wiederhergestellt werden"
Aleksandr Dubinsky

6

Die Lösung von Mathias kommt definitiv einer Git-Stash-Pop-Force am nächsten (und wirklich, komm schon, Git-Entwickler, lass uns diese Option schon bekommen!)

Wenn Sie jedoch dasselbe nur mit Git-Befehlen tun möchten, können Sie:

  1. git commit -a -m "Fixme"
  2. Git Stash Pop
  3. git commit -a --amend
  4. Git Reset HEAD ~

Mit anderen Worten, machen Sie ein Commit (das wir niemals pushen werden) Ihrer aktuellen Änderungen. Jetzt, da Ihr Arbeitsbereich sauber ist, legen Sie Ihren Vorrat ab. Übernehmen Sie jetzt die Stash-Änderungen als Änderung Ihres vorherigen Commits. Nachdem Sie dies getan haben, haben Sie jetzt beide Änderungssätze in einem einzigen Commit zusammengefasst ("Fixme"). Setzen Sie einfach Ihre Kaufabwicklung auf "Eins vor diesem Festschreiben" zurück (--soft NOT --hard, damit tatsächlich nichts verloren geht), und jetzt haben Sie beide Änderungssätze, die nicht festgeschrieben sind.

** BEARBEITEN * *

Mir ist gerade klar geworden, dass es sogar noch einfacher ist. Sie können Schritt 3 vollständig überspringen, also ...

  1. git commit -a -m "Fixme"
  2. Git Stash Pop
  3. Git Reset HEAD ~

(Übernehmen Sie die aktuellen Änderungen, entfernen Sie die gespeicherten Änderungen und setzen Sie das erste Festschreiben zurück, um beide Änderungssätze in einem nicht festgeschriebenen Zustand zu kombinieren.)


4

Keine dieser Antworten funktioniert tatsächlich, wenn Sie sich in dieser Situation befinden, wie ich es heute getan habe. Egal wie viele git reset --hardich gemacht habe, es hat mich nirgendwohin gebracht. Meine Antwort (keineswegs offiziell) war:

  1. Finden Sie die Hash-Verwendung des Stash heraus git reflog --all
  2. Führen Sie diesen Hash mit dem Zweig zusammen, an dem Sie interessiert sind

1
Vielen Dank Yar. Ich war frustriert darüber, wie sich Git gerade auf meinem lokalen Repo seltsam verhalten hat, das gleiche Problem, das Sie beschrieben haben.
Yclian

4

Ich fand auch, dass die Lösung von Mathias Leppich großartig funktioniert, und fügte meiner globalen .gitconfig einen Alias ​​dafür hinzu

[alias]
        apply-stash-to-dirty-working-tree = !git stash show -p | git apply && git stash drop

Jetzt kann ich einfach tippen

git apply-stash-to-dirty-working-tree

Das funktioniert gut für mich.

(Ihr Kilometerstand kann bei diesem langen Aliasnamen variieren. Aber ich mag eine Portion Ausführlichkeit, wenn es um die Vervollständigung von Bashs geht.)


3

Sie können einen Versteck auf einen "schmutzigen" Baum anwenden, indem git addSie alle vorgenommenen Änderungen vornehmen und so den Baum bereinigen. Dann können Sie git stash popdie versteckten Änderungen problemlos anwenden.


2

Sie haben Dateien, die geändert, aber nicht festgeschrieben wurden. Entweder:

git reset --hard HEAD (to bring everything back to HEAD)

oder, wenn Sie Ihre Änderungen speichern möchten:

git checkout -b new_branch
git add ...
git commit
git checkout -b old_branch
git stash pop

1
@ MikeCooper - Ich denke, er wollte nur hinzufügen, was Sie hinzufügen möchten, bevor Sie sich verpflichten.
sscirrus

0

Ich hatte das gleiche Problem, aber Git hatte keine geänderten Dateien. Es stellte sich heraus, dass ich eine index.lock-Datei hatte, die herumlag. Das Löschen löste das Problem.


0

Ich konnte die meisten davon nicht zum Laufen bringen; Aus irgendeinem Grund glaubt es immer, dass ich lokale Änderungen an einer Datei habe. Ich kann keinen Stash anwenden, Patches werden nicht angewendet checkoutund reset --hardschlagen fehl. Was schließlich funktionierte, war, den Stash als Zweig mit zu speichern git stash branch tempbranchnameund dann eine normale Zweigzusammenführung durchzuführen: git checkout masterund git merge tempbranchname. Von http://git-scm.com/book/en/Git-Tools-Stashing :

Wenn Sie die versteckten Änderungen auf einfachere Weise erneut testen möchten, können Sie den Git-Stash-Zweig ausführen, der einen neuen Zweig für Sie erstellt, das Commit überprüft, bei dem Sie Ihre Arbeit gespeichert haben, Ihre Arbeit dort erneut anwendet und dann den Löschvorgang löscht Verstecken, wenn es erfolgreich angewendet wird

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.