git stash: Änderungen zwischenspeichern und wiederherstellen
git stash legt nicht committete Änderungen in einem separaten Speicher ab und setzt das Arbeitsverzeichnis auf den letzten Commit zurück, damit Sie zu einer anderen Aufgabe wechseln können. Zurück holen Sie die Änderungen mit git stash pop (anwenden und aus dem Speicher entfernen) oder git stash apply (anwenden und behalten); einen Befehl git unstash gibt es nicht.
Wozu braucht man git stash?
Eine typische Situation: Sie stecken mitten in einer Aufgabe, Dateien sind geändert, für einen Commit ist es zu früh – und dann sollen Sie dringend einen Bug in einem anderen Branch beheben. Der Wechsel klappt nicht, oder Sie haben Angst, Ihre Änderungen zu verlieren. git stash steckt alle nicht committeten Änderungen „in die Tasche“ und setzt das Arbeitsverzeichnis auf den Stand des letzten Commits zurück.
$ git stash
Saved working directory and index state WIP on feature/login: 3f2a1c4 Login-Formular
$ git status
On branch feature/login
nothing to commit, working tree clean
Jetzt können Sie wechseln, den Bug beheben, zurückkehren und das Zurückgelegte wieder hervorholen. Jede Sicherung ist ein Eintrag im Stash-Stack; intern speichert Git ihn als speziellen Commit – die Daten sind also zuverlässig gesichert und unabhängig vom Branch.
Änderungen sichern: die wichtigsten Varianten
Mit aussagekräftiger Beschreibung
Die Standardbeschreibung „WIP on branch“ sagt Ihnen in einer Woche gar nichts mehr. Beschriften Sie deshalb Ihre Stashes:
git stash push -m "Formularvalidierung, E-Mail noch offen"
git stash ohne Argumente ist die Kurzform von git stash push. Die veraltete Form git stash save "Nachricht" funktioniert noch, in neuen Abläufen sollten Sie aber push -m verwenden.
Inklusive neuer Dateien (untracked)
Standardmäßig nimmt stash nur getrackte Dateien mit – geänderte und solche, die im Index liegen. Neue Dateien, die noch nie per git add hinzugefügt wurden, bleiben im Arbeitsverzeichnis. Das sorgt oft für Überraschungen.
git stash -u # --include-untracked: plus untracked Dateien
git stash -a # --all: plus Dateien aus .gitignore
Vorsicht mit -a: Dann wandern auch node_modules, Build-Ergebnisse und lokale Konfigurationen in die Tasche. Meist genügt -u.
Nur einen Teil der Änderungen
git stash push -m "Konfig" src/config.js # nur die angegebenen Dateien
git stash -p # Abschnitte interaktiv auswählen
git stash --staged # nur, was im Index liegt (Git 2.35+)
git stash --keep-index # alles wegpacken, Index aber im Verzeichnis lassen
--keep-index ist vor einem Commit nützlich: Im Arbeitsverzeichnis bleibt nur, was Sie committen wollen; Sie lassen die Tests laufen und stellen sicher, dass der Commit für sich allein funktioniert.
Änderungen zurückholen (git unstash)
Einen Befehl git unstash gibt es in Git nicht – unter diesem Begriff wird meist gesucht, wie man Zurückgelegtes wieder hervorholt. Dafür gibt es zwei Befehle.
| Befehl | Wirkung | Eintrag im Stack |
|---|---|---|
git stash pop | Wendet die zuletzt gesicherten Änderungen an | Wird entfernt, wenn ohne Konflikte angewendet |
git stash apply | Wendet die zuletzt gesicherten Änderungen an | Bleibt erhalten |
git stash pop stash@{2} | Wendet einen bestimmten Eintrag an | Wird entfernt |
git stash apply --index | Stellt auch die Aufteilung in Index und Arbeitsverzeichnis wieder her | Bleibt erhalten |
$ git stash pop
On branch feature/login
Changes not staged for commit:
modified: src/auth.js
modified: src/form.js
Dropped refs/stash@{0} (8c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d)
Beachten Sie: Standardmäßig kommt selbst das, was zum Zeitpunkt des Stashs im Index lag, als normale ungestagete Änderung zurück. Wenn Ihnen der vorbereitete Index wichtig ist, ergänzen Sie --index.
pop oder apply?
Für den Alltag ist pop bequem: rausholen und vergessen. apply wählen Sie, wenn Sie dieselben Änderungen in mehreren Branches anwenden wollen oder nicht sicher sind, dass alles glattgeht – der Eintrag bleibt als Absicherung und lässt sich später mit git stash drop löschen.
Mit der Stash-Liste arbeiten
$ git stash list
stash@{0}: On feature/login: Formularvalidierung, E-Mail noch offen
stash@{1}: WIP on main: 9b7e0d2 Abhängigkeiten aktualisieren
stash@{2}: On feature/api: Cache-Experiment
Der Stack funktioniert nach dem Prinzip „last in, first out“: stash@{0} ist immer der neueste Eintrag, und die Nummern verschieben sich nach jedem push und drop.
| Befehl | Zweck |
|---|---|
git stash show | Kurze Änderungsstatistik des letzten Eintrags |
git stash show -p stash@{1} | Vollständiger Diff eines bestimmten Eintrags |
git stash drop stash@{1} | Einen Eintrag löschen |
git stash clear | Alle Einträge auf einmal löschen |
git stash branch name stash@{0} | Branch vom Commit anlegen, auf dem gestasht wurde, Eintrag anwenden und löschen |
Damit git stash show standardmäßig statt der Statistik den vollständigen Diff und auch untracked Dateien zeigt, gibt es die Einstellungen stash.showPatch und stash.showIncludeUntracked.
Schritt für Schritt: dringender Bug mitten in der Aufgabe
- Legen Sie die aktuelle Arbeit samt neuer Dateien zur Seite:
git stash push -u -m "Login: Entwurf". - Wechseln Sie auf den Hauptbranch und legen Sie einen Branch für den Fix an:
git switch main,git pull,git switch -c hotfix/null-email. - Beheben Sie den Fehler, committen Sie und schicken Sie ihn ins Review.
- Kehren Sie zur Aufgabe zurück:
git switch feature/login. - Holen Sie Ihre Änderungen zurück:
git stash pop. Prüfen Sie mitgit status– alles ist wieder da.
Viele nutzen für dieses Szenario inzwischen git worktree: Ein zweites Arbeitsverzeichnis für dasselbe Repo erspart das Zurücklegen komplett. Für einen schnellen Wechsel von fünf Minuten ist stash aber nach wie vor einfacher.
Konflikte beim Anwenden eines Stashs
Haben sich nach dem Stash im Branch dieselben Zeilen geändert, endet das Anwenden mit einem Konflikt:
$ git stash pop
Auto-merging src/auth.js
CONFLICT (content): Merge conflict in src/auth.js
The stash entry is kept in case you need it again.
Der Eintrag wird in diesem Fall nicht gelöscht, auch nicht bei pop. Lösen Sie den Konflikt in der Datei wie gewohnt, markieren Sie die Lösung mit git add (oder git restore --staged, wenn die Änderungen nicht im Index bleiben sollen) und löschen Sie den nun überflüssigen Eintrag mit git stash drop.
Bei einem komplizierten Konflikt ist ein Umweg bequemer: git stash branch tmp-login. Git legt einen Branch genau von dem Commit an, auf dem Sie gestasht haben – dort lassen sich die Änderungen konfliktfrei anwenden, und mit dem Hauptbranch führen Sie sie dann per normalem Merge zusammen.
Versehentlich gelöschten Stash wiederherstellen
Sie haben aus Versehen git stash drop oder clear ausgeführt? Noch ist nicht alles verloren. Der Eintrag war ein Commit, und solange die Garbage Collection ihn nicht entfernt hat, finden Sie ihn unter den „dangling“-Objekten:
git fsck --no-reflog | grep "dangling commit"
git show 8c1d2e3 # prüfen, ob es der richtige Stash ist
git stash apply 8c1d2e3
Haben Sie den Eintrag gerade erst per drop oder pop entfernt, steht der Hash direkt in der Ausgabe des Befehls – in der Zeile Dropped refs/stash@{0} (...). Den müssen Sie nur an git stash apply übergeben.
Wie stash intern funktioniert
Wer den Aufbau versteht, verliert die Angst vor Datenverlust. Jeder Stash-Eintrag ist ein gewöhnlicher Commit, auf den die Referenz refs/stash zeigt. Er hat zwei Parents: den HEAD-Commit, auf dem Sie standen, und einen separaten Commit mit dem Zustand des Index. Mit -u kommt ein dritter Parent mit den untracked Dateien hinzu. Die Liste stash@{N} ist schlicht das Reflog der Referenz refs/stash.
Daraus ergeben sich einige praktische Konsequenzen. Einen Stash können Sie jedem Befehl übergeben, der einen Commit akzeptiert: git diff stash@{0}, git show stash@{0}:src/auth.js (Inhalt einer einzelnen Datei aus dem Eintrag) oder git checkout stash@{0} -- src/auth.js, um eine einzelne Datei zu holen, ohne den ganzen Eintrag anzuwenden. Und ein gelöschter Eintrag bleibt in der Objektdatenbank, bis die Garbage Collection ihn entfernt.
Stash und andere Git-Befehle
Manche Befehle können Änderungen selbst wegpacken. git rebase --autostash und git pull --rebase --autostash legen nicht committete Änderungen vor dem Start zur Seite und spielen sie nach dem Ende wieder ein. Dauerhaft aktivieren lässt sich das mit den Einstellungen rebase.autoStash true und merge.autoStash true. Gibt es beim Zurückspielen einen Konflikt, legt Git den Eintrag im normalen Stash-Stack ab und weist Sie darauf hin.
Auch ein Branch-Wechsel per git switch erfordert nicht immer einen Stash: Überschneiden sich Ihre Änderungen nicht mit Dateien, die sich zwischen den Branches unterscheiden, nimmt Git sie einfach mit. Stash brauchen Sie, wenn Git mit „Your local changes would be overwritten by checkout“ antwortet oder wenn Sie die Änderungen nicht in den anderen Branch mitnehmen wollen.
Häufige Fehler
- Neue Dateien wurden „nicht weggepackt“. Sie sind untracked, Sie brauchen
-u. - Stash als Langzeitspeicher. Nach einem Monat stehen zehn namenlose „WIP on main“ in der Liste, und niemand weiß mehr, was drin ist. Für längere Arbeit committen Sie in einem eigenen Branch – den können Sie wenigstens pushen.
- Vergessen, dass der Eintrag nach einem Konflikt geblieben ist – und ihn später ein zweites Mal angewendet. Nach dem Lösen eines Konflikts immer
dropausführen. - Stash wird nicht mit dem Server synchronisiert. Er liegt nur in Ihrem lokalen Repository,
git pushüberträgt ihn nicht. Löschen Sie den Projektordner, ist der Stash weg. - Falschen Eintrag angewendet. Sehen Sie sich vor
popgit stash listundgit stash show -pan.
Fazit
git stash ist der schnelle Weg, das Arbeitsverzeichnis freizuräumen, ohne nicht committete Änderungen zu verlieren: git stash push -u -m "Beschreibung" zum Zurücklegen und git stash pop zum Zurückholen. Nutzen Sie apply, wenn Sie eine Absicherung brauchen, git stash list und show -p, um den Überblick zu behalten, und machen Sie den Stash nicht zum Lager – für alles Längerfristige gibt es Commits und Branches. Den Wechsel zwischen Aufgaben mit stash üben Sie praktisch im Git-Kurs.
Häufige Fragen
Kann ich einen Stash in einem anderen Branch anwenden?
Ja, ein Stash ist an keinen Branch gebunden: Wechseln Sie in den gewünschten Branch und führen Sie git stash pop oder apply aus. Passen die Änderungen nicht, entsteht ein normaler Konflikt.
Sichert git stash auch Änderungen im Index?
Ja, aber bei einem normalen pop oder apply kommt alles als ungestagete Änderung zurück. Um auch den Index wiederherzustellen, verwenden Sie git stash apply --index.
Wie viele Einträge kann der Stash enthalten?
Ein festes Limit gibt es nicht, aber Einträge, die älter als die Aufbewahrungsfrist des Reflogs sind, können bei der Garbage Collection entfernt werden. In der Praxis sollten nicht mehr als ein paar frische Einträge im Stack liegen.
Wie stashe ich nur eine einzelne Datei?
Geben Sie den Pfad nach zwei Bindestrichen oder direkt nach push an: git stash push -m Beschreibung -- src/config.js. Nur diese Datei landet im Stash, alle anderen Änderungen bleiben im Arbeitsverzeichnis.
Was unterscheidet einen Stash von einem temporären Commit?
Ein Commit lebt in einem Branch, lässt sich auf den Server pushen und später per amend oder rebase korrigieren. Ein Stash liegt nur lokal in einem separaten Stack und eignet sich für kurze Wechsel.
Dieses Thema wird im Kurs „Git vom Anfänger zum versierten Entwickler“ ausführlich mit Praxis behandelt.
Zum Kurs