Warum kann Stash nicht auf das Arbeitsverzeichnis angewendet werden?

96

Ich kann Stash nicht wieder auf das Arbeitsverzeichnis anwenden.

Kleine Geschichte:

Zuerst habe ich versucht, einige festgeschriebene Änderungen zu pushen, aber es hieß: "Nein, kannst du nicht, zieh zuerst" ... OK, dann werde ich Dinge von GitHub ziehen und dann meine Änderungen pushen. Als ich versuchte zu ziehen, hieß es, ich hätte Änderungen, die überschrieben würden, und ich sollte meine Änderungen aufbewahren. OK, ich habe die Änderungen versteckt ... habe den Pull ausgeführt und die festgeschriebenen Änderungen gepusht. Aber jetzt kann ich die nicht festgeschriebenen Änderungen, an denen ich gearbeitet habe, nicht wiederherstellen.

Dies ist der Fehler:

MyPath/File.cs already exists, no checkout
Could not restore untracked files from stash

Sicher verstehe ich noch nicht alle Konzepte von Git, sie verwirren mich ein bisschen ... vielleicht habe ich etwas falsch gemacht.

Es wäre großartig, wenn mir jemand bei der Lösung dieses Problems helfen könnte ... Ich habe seit mehr als einer Stunde nach Google und allem gesucht und bin noch nicht zu einer Lösung gekommen.

Hilfe wird sehr geschätzt. Vielen Dank!

Miguel Angelo
quelle

Antworten:

74

Es hört sich so an, als ob Ihr Vorrat eine nicht verfolgte Datei enthielt, die anschließend dem Repo hinzugefügt wurde. Wenn Sie versuchen, es auszuchecken, lehnt git dies zu Recht ab, da es eine vorhandene Datei überschreiben würde.

Um dies zu beheben, können Sie beispielsweise diese Datei löschen (es ist in Ordnung, sie befindet sich noch im Repo), Ihren Stash anwenden und dann die versteckte Version der Datei durch die entsprechende In-Repo-Version ersetzen.

Bearbeiten: Es ist auch möglich, dass die Datei nur im Arbeitsbaum erstellt wurde, ohne dem Repo hinzugefügt worden zu sein. Löschen Sie in diesem Fall nicht einfach die lokale Datei, sondern:

  1. Bewegen Sie es woanders hin
  2. wende den Vorrat an
  3. Führen Sie die beiden Dateiversionen manuell zusammen (Arbeitsbaum vs. verschoben).
blahdiblah
quelle
2
Gibt es eine Möglichkeit, die ich in Zukunft vermeiden muss, Dinge zu verstauen? Ich komme von SVN und es sieht so nach vorne aus. Sie aktualisieren, lösen Konflikte und legen dann fest. Git kann nicht so schwer sein, dass ich dem Zyklus 2 Schritte hinzufügen muss. Danke noch einmal!
Miguel Angelo
2
@ Miguel: Verstecken ist kein Hindernis. Es ist ein zusätzliches Tool von Git, mit dem Sie Ihren Workflow verbessern und Konflikte und unreine Commits vermeiden können. git-scm.com/docs/git-stash
Koraktor
8
Während die Antwort gültig ist, bin ich mir wirklich nicht sicher, ob Git in dieser Hinsicht "richtig" ist. Die Dateien befinden sich im Repo, sodass keine Gefahr eines Datenverlusts besteht. Warum nicht einfach die Änderungen anwenden? Siehe diesen Thread - git.661346.n2.nabble.com/stash-refuses-to-pop-td7453780.html
studgeek
5
Ich denke, diese Antwort ist nicht die hilfreichste. git stashsollte helfen, lokale Änderungen schnell zu sichern. Das manuelle Löschen einer Reihe von Dateien, um sie wiederherzustellen, unterbricht den Datenfluss. Der git stash branchAnsatz in der anderen Antwort klingt besser, aber immer noch viel manueller als gewünscht.
Bentolor
Diese Antwort funktionierte am besten für mich, wenn ich mich in derselben Situation befand. Nachdem ich den Vorrat geknallt hatte, ging ich durch eine Fusion, wie ich es von Anfang an erwartet hätte.
Billy Lazzaro
58

Der sicherste und einfachste Weg wäre wahrscheinlich, die Dinge wieder zu verstauen:

git stash -u             # This will stash everything, including unstaged files
git stash pop stash@{1}  # This will apply your original stash

Wenn Sie mit dem Ergebnis zufrieden sind, können Sie anschließend anrufen

git stash drop

um Ihren "sicheren" Vorrat zu entfernen.

Koraktor
quelle
2
Danke dafür, hat mich vor vielen Schmerzen und Leiden gerettet!
Danjarvis
9
Stash Pop wird angewendet und Ihr ursprünglicher Stash wird gelöscht. Nur um sicher zu gehen applystatt pop.
Hilbrand Bouwkamp
2
In der Tat popist eine Kombination von applyund drop, wird aber nur, dropwenn die applyohne Konflikte funktioniert. Aber ja, applyist normalerweise sicherer.
Koraktor
2
Dies setzt voraus, dass das Arbeitsverzeichnis keine weiteren Änderungen enthält, die Sie beibehalten möchten. Für diese spezielle Frage impliziert er (sagt aber nicht ausdrücklich), dass er sich in einem sauberen Zustand befindet, aber ich wollte darauf hinweisen, dass andere mit lokalen Veränderungen hierher kommen.
Studgeek
1
Dies löst das Problem nur, wenn die widersprüchlichen Probleme nicht begangen wurden . Sie erhalten genau die gleiche Nachricht, wenn sie festgeschrieben wurden (z. B. mit einer sauberen Kasse), und dann ändert dies nichts ...
Jasper
56

Wie von @bentolo erwähnt, können Sie die beanstandeten Dateien manuell löschen, Zweige wechseln und sie dann manuell wieder hinzufügen. Aber ich persönlich bleibe lieber "in git".

Der beste Weg, dies zu tun, besteht darin, den Stash in einen Zweig umzuwandeln. Sobald es sich um einen Zweig handelt, können Sie mit den normalen Techniken / Werkzeugen, die Sie kennen und lieben, normal in Git arbeiten. Dies ist eine nützliche allgemeine Technik für die Arbeit mit Verstecken, auch wenn Sie den aufgeführten Fehler nicht haben. Es funktioniert gut, weil ein Stash wirklich ein Commit unter der Decke ist (siehe PS).

Konvertieren eines Stashs in einen Zweig

Im Folgenden wird ein Zweig basierend auf dem HEAD erstellt, als der Stash erstellt wurde, und dann wird der Stash angewendet (er schreibt ihn nicht fest).

git stash branch STASHBRANCH

Arbeiten mit dem "Stash Branch"

Was Sie als Nächstes tun, hängt von der Beziehung zwischen dem Stash und dem Ort ab, an dem sich Ihr Zielzweig (den ich ORIGINALBRANCH nennen werde) jetzt befindet.

Option 1 - Stash-Zweig normal neu starten (viele Änderungen seit Stash)

Wenn Sie viele Änderungen an Ihrem ORIGINALBRANCH vorgenommen haben, behandeln Sie STASHBRANCH wahrscheinlich am besten wie jede lokale Niederlassung. Übernehmen Sie Ihre Änderungen in STASHBRANCH, setzen Sie sie erneut auf ORIGINALBRANCH, wechseln Sie dann zu ORIGINALBRANCH und starten Sie die STASHBRANCH-Änderungen erneut. Wenn es Konflikte gibt, behandeln Sie diese normal (einer der Vorteile dieses Ansatzes besteht darin, dass Sie Konflikte sehen und lösen können).

Option 2 - Setzen Sie den ursprünglichen Zweig zurück, um ihn an den Stash anzupassen (begrenzte Änderungen seit dem Stash).

Wenn Sie nur etwas gespeichert haben, während Sie einige bereitgestellte Änderungen beibehalten haben, dann festgeschrieben, und alles, was Sie tun möchten, ist, die zusätzlichen Änderungen zu erhalten, die beim Speichern nicht bereitgestellt wurden. Sie können Folgendes tun. Es wird zu Ihrem ursprünglichen Zweig und Index zurückgeschaltet, ohne dass Ihre Arbeitskopie geändert wird. Das Endergebnis sind Ihre zusätzlichen Änderungen in Ihrer Arbeitskopie.

git symbolic-ref HEAD refs/heads/ORIGINALBRANCH
git reset

Hintergrund

Stashes sind Commits wie Zweige / Tags (keine Patches)

PS: Es ist verlockend, sich einen Stash als Patch vorzustellen (genau wie es verlockend ist, sich ein Commit als Patch vorzustellen), aber ein Stash ist tatsächlich ein Commit gegen den HEAD, als es erstellt wurde. Wenn Sie sich bewerben / popen, tun Sie etwas Ähnliches wie das Kirschpflücken in Ihrem aktuellen Zweig. Beachten Sie, dass Zweige und Tags eigentlich nur Verweise auf Commits sind. In vielerlei Hinsicht sind Stashes, Zweige und Tags nur verschiedene Arten, auf ein Commit (und seinen Verlauf) zu verweisen.

Wird manchmal benötigt, auch wenn Sie keine Änderungen am Arbeitsverzeichnis vorgenommen haben

PPS, Möglicherweise benötigen Sie diese Technik, nachdem Sie nur stash mit --patch und / oder --include-untracked verwendet haben. Selbst ohne die Arbeitsverzeichnisse zu ändern, können diese Optionen manchmal einen Stash erstellen, den Sie nicht einfach zurück anwenden können. Ich muss zugeben, ich verstehe nicht ganz warum. Weitere Informationen finden Sie unter http://git.661346.n2.nabble.com/stash-refuses-to-pop-td7453780.html .

studgeek
quelle
5
Diese Antwort sollte als Lösung markiert werden, da sie die hilfreichsten Hinweise dazu bietet, wie ein gesperrter Stash am effektivsten aufgelöst werden kann. Vielleicht verbessern Sie es, indem Sie zuerst die 'einfache Löschlösung' und die Zweiglösung als zweite Option erwähnen.
Bentolor
8
"git stash branch STASHBRANCH" scheint nicht zu funktionieren, wenn Sie mit diesem Szenario konfrontiert sind (genau die gleiche Fehlermeldung wie bei pop). Möglicherweise müssen Sie vorher einige Git-Resets durchführen.
+1 Ich habe mich in ein Spaghetti-Chaos mit Commits und Änderungen und Verstecken usw. usw. verwickelt. Dies hat mich davon abgehalten, indem ich das Versteck in eine Filiale gesteckt habe, danke studgeek
RobbZ
Vielen Dank für die Klarstellung, dass Verstecke keine Patches sind und wie sie (zum Zeitpunkt des Versteckens) mit dem KOPF verbunden sind. Das macht sehr viel Sinn. - Also ... Ich nehme an, dass es Fälle gibt, in denen es flexibler / portabler / bequemer ist, einen Patch anstelle eines Stashs zu erstellen (wie Sie bereits erwähnt haben: bei vielen Änderungen), damit er überall angewendet werden kann (und ist) nur eine Frage der Lösung von Konflikten). Vielleicht git stash show -philft es dort, Stash zu machen -> * Patch *.
Kamafeather
39

Die Lösung: Sie müssen die betreffende Datei löschen und dann versuchen, Pop / Apply erneut zu speichern, und es sollte durchlaufen werden. Löschen Sie keine anderen Dateien, sondern nur die durch den Fehler genannten.

Das Problem: Git saugt manchmal. Bei der Ausführung git stash -uenthält es untracked Dateien (cool!) , Aber es nicht entfernen , diese untracked Dateien und nicht wissen , wie die verstaute untracked Dateien auf der Oberseite der Reste anwenden (nicht cool!), Das wirklich das macht -uOption ziemlich nutzlos.

qwertzguy
quelle
3
Ich hätte diese Antwort akzeptiert, wenn es meine Frage gewesen wäre. Danke @qwertzguy, Ihre Antwort hat mein Problem gelöst,
Kobus Myburgh
Ich bin selbst auf dasselbe Problem gestoßen, Git Stash Pop wurde erst angewendet, nachdem ich die fraglichen Dateien gelöscht hatte. Dann stieß ich auf einen Konflikt mit einer Datei, der dazu führte, dass der Stash abgelehnt wurde. Aber anstatt die nicht verfolgten Dateien zu entfernen, wurden sie zurückgelassen. Beachten Sie also, dass Sie sich von zukünftigen Personen fernhalten solltengit stash -u
notzippy
Schlechter Rat, wenn Sie Teile aus beiden Versionen der betroffenen Dateien benötigen.
Walf
2
"Diese nicht verfolgten Dateien werden nicht entfernt" ... und sie werden nicht aufgelistet git stash show. Diese Antwort ließ die Glühbirne angehen.
Jscs
2
plus eins für Git saugt manchmal.
Harish
29

Verwenden Sie den folgenden Befehl, um die Codeunterschiede im Stash stattdessen als Patch anzuwenden:

git stash show --patch | patch -p1
Chiffrierimian
quelle
11
Normalerweise ist es besser, eine Lösung zu erklären, als nur einige Zeilen anonymen Codes zu veröffentlichen. Sie können lesen, wie ich eine gute Antwort schreibe und wie Sie vollständig codebasierte Antworten erklären .
Massimiliano Kraus
Dies funktioniert für mich, da der Patch von git stash show --patchnicht die nicht verfolgten Dateien enthält.
Steven Shaw
Diese Antwort hat mir sehr geholfen, da ich meinen Vorrat aufgrund vieler Änderungen in meinem Repo seit dem Verschieben des Vorrats nicht mehr öffnen konnte.
Erik Finnman
1

Das ist mir schon oft passiert, ich habe nicht verfolgte Dateien mit git stash -u denen sie dem Repo hinzugefügt werden, und ich kann die versteckten Änderungen nicht mehr anwenden.

Ich konnte keine Möglichkeit finden, git stash pop/applydas Ersetzen der Dateien zu erzwingen. Daher entferne ich zuerst die lokalen Kopien der nicht verfolgten Dateien, die gespeichert wurden ( seien Sie vorsichtig, da alle nicht festgeschriebenen Änderungen gelöscht werden ), und wende dann die gespeicherten Änderungen an ::

rm `git ls-tree -r stash@{0}^3 --name-only`
git stash apply

Schließlich benutze ich git status,git diff und andere Werkzeuge zu überprüfen und Teile von den gelöschten Dateien wieder hinzufügen , wenn es etwas fehlt.


Wenn Sie nicht festgeschriebene Änderungen haben, die Sie beibehalten möchten, können Sie zuerst ein temporäres Festschreiben erstellen:

git add --all
git commit -m "dummy"
rm `git ls-tree -r stash@{0}^3 --name-only`
git stash apply

Verwenden Sie die für Sie geeigneten Tools, um die zuvor festgeschriebenen Änderungen wieder in den lokalen Dateien zusammenzuführen und das Dummy-Commit zu entfernen:

git reset HEAD~1
Helder Pereira
quelle
0

Meine ähnlich blockierte Pop-Operation war, weil übrig gebliebene ignorierte Dateien (siehe die .gitignore-Datei). Der Git-Status zeigte mir, dass ich verfolgt und nicht verfolgt wurde, aber meine Aktivitäten bereinigten die ignorierten Dateien nicht.

Details: Ich hatte git stash save -aden Master verwendet, um das ursprüngliche Verhalten zu kompilieren und zu sehen, und dann versucht, alles zurückzusetzen, um die Bearbeitung fortzusetzen. Als ich meinen Zweig auscheckte und versuchte zu platzen, waren meine ignorierten Dateien noch vor dem Speichern des Stashs vorhanden. Dies liegt daran, dass das Auschecken des Masters nur festgeschriebene Dateien betraf - die ignorierten Dateien wurden nicht gelöscht. Der Pop schlug also fehl und sagte im Wesentlichen, dass er meine versteckten ignorierten Dateien nicht zusätzlich zu den Dateien wiederherstellen wollte, die noch vorhanden waren. Es ist bedauerlich, dass ich keinen Weg gefunden habe, eine Zusammenführungssitzung mit ihnen zu starten.

Letztendlich habe ich git clean -f -d -xdie ignorierten Dateien entfernt. Interessanterweise blieben von meinen ~ 30 noch 4 Dateien nach der Bereinigung (in Unterverzeichnissen vergraben). Ich muss herausfinden, in welcher Kategorie sie sich befinden, dass sie manuell gelöscht werden mussten.

Dann war mein Pop erfolgreich.

deaktiviert
quelle
0

Versuche dies:

git checkout stash -.

Nalan Madheswaran
quelle
-1

Andere Lösung:

cd to/root/your/project

# Show what git will be remove
git clean -n

# If all is good
git clean -f

# If not all is good, see
git clean --help

# Finish
git stash pop
ktretyak
quelle
Der in der Frage erwähnte Fehler wird durch eine Datei verursacht, die sowohl im Stapel als auch im Arbeitsverzeichnis vorhanden ist. Das Bereinigen behebt das Problem nur, wenn diese Datei nicht verfolgt wird, was sicherlich nicht immer der Fall ist (und nicht der Fall des OP, da er die Datei von einem Pull erhalten hat).
Xavier Poinas
-1

Mit Git 2.14.x / 2.15 (Q3 2017) wird die Lösung von qwertzguy aus dem Jahr 2014 nicht mehr benötigt.

Vor dem dritten Quartal 2017 mussten Sie die betreffende Datei löschen und dann erneut versuchen, Pop / Apply zu speichern.
Mit der nächsten Git-Version müssen Sie das nicht mehr tun.

Siehe Commit bbffd87 (11. August 2017) von Nicolas Morey-Chaisemartin ( nmorey) .
(Zusammengeführt von Junio ​​C Hamano - gitster- in Commit 0ca2f32 , 23. August 2017)

stash: Bereinigen Sie nicht verfolgte Dateien vor dem Zurücksetzen

Wenn Sie git stash -uein Repo aufrufen , das eine Datei enthält, die aufgrund einer aktuellen Änderung der gitignoreDatei nicht mehr ignoriert wird , wird diese Datei gespeichert, aber nicht aus dem Arbeitsbaum entfernt.
Dies ist darauf zurückzuführen, dass git-stashzuerst ein reset --hardVorgang ausgeführt wird, bei dem die Dateimodifikation .gitignoregelöscht und dann aufgerufen wird git clean, wobei die Datei unberührt bleibt.
Dies führt git stash popzu einem Fehlschlag aufgrund der vorhandenen Datei .

Dieser Patch wechselt einfach die Reihenfolge zwischen Bereinigen und Zurücksetzen und fügt einen Test für diesen Anwendungsfall hinzu.

VonC
quelle
-1

Der sicherste Weg, um dem Verstecken zu folgen

git stash -u

Dadurch werden alle Daten gespeichert, einschließlich nicht bereitgestellter Änderungen

Git Stash Drop

Nachdem Sie mit der Arbeit fertig sind, entfernen Sie Ihren "sicheren" Vorrat.

RahulMohan Kolakandy
quelle
Wie unter stackoverflow.com/a/23743125/6309 erläutert , funktioniert dies mit Git 2.14 oder weniger nicht immer. Es wird mit Git 2.15 funktionieren
VonC