Close

git stash – Tutorial

Der git stash-Code bewirkt, dass Änderungen an deiner Arbeitskopie zeitweise zurückgestellt (oder auch gestasht) werden, damit du dich anderen Aufgaben widmen und die Änderungen später aufspielen kannst. Die Verwendung von "git stash" kann praktisch sein, wenn du mitten in einer Codeänderung steckst, zum Committen aber noch nicht bereit bist und schnell an etwas ganz Anderem weiterarbeiten musst.


Anlegen eines Stash mit "git stash"


Der git stash-Code speichert deine nicht committeten Änderungen (egal, ob sie sich in der Staging-Umgebung befinden oder nicht) zur späteren Verwendung und setzt dann deine Arbeitskopie zurück. Ein Beispiel:

$ git status
On branch main
Changes to be committed:

    new file:   style.css

Changes not staged for commit:

    modified:   index.html

$ git stash
Saved working directory and index state WIP on main: 5002d47 our new homepage
HEAD is now at 5002d47 our new homepage

$ git status
On branch main
nothing to commit, working tree clean
git branch
Zugehöriges Material

git branch

Bitbucket-Logo
Lösung anzeigen

Git kennenlernen mit Bitbucket Cloud

Nun kannst du Änderungen vornehmen, neue Commits erstellen, Branches wechseln und alle anderen Git-Funktionen nutzen. Wenn du schließlich bereit bist, wendest du deinen Stash wieder an.

Beachte, dass das in deinem Git-Repository ein lokaler Stash ist und deine Stashes beim Pushen nicht an den Server übermittelt werden.

Im Stash aufbewahrte Änderungen mit "git stash" wieder anwenden


Zuvor aufbewahrte Änderungen kannst du mit git stash pop erneut anwenden:

$ git status
On branch main
nothing to commit, working tree clean
$ git stash pop
On branch main
Changes to be committed:

    new file:   style.css

Changes not staged for commit:

    modified:   index.html

Dropped refs/stash@{0} (32b3aa1d185dfe6d57b3c3cc3b32cbf3e380cc6a)

Wenn du deinen Stash poppst, werden die Änderungen aus deinem Stash entfernt und erneut auf deine Arbeitskopie angewendet.

Du kannst aber auch die Änderungen erneut auf deine Arbeitskopie anwenden und sie weiterhin in deinem Stash aufbewahren. Hierfür gibst du git stash apply ein:

$ git stash apply
On branch main
Changes to be committed:

    new file:   style.css

Changes not staged for commit:

    modified:   index.html

Das ist nützlich, wenn du dieselben gestashten Änderungen auf mehrere Branches anwenden willst.

Nachdem du nun die Grundlagen zum Stashing kennst, solltest du dir noch über einen kleinen Nachteil von git stash bewusst werden: In den Standardeinstellungen bewahrt Git keine Änderungen an u nicht verfolgten oder ignorierten Dateien im Stash auf.

Aufnehmen von unverfolgten oder ignorierten Dateien mit "git stash"


In den Standardeinstellungen wird beim Ausführen von git stash Folgendes in den Stash verschoben:

  • Änderungen, die deinem Index hinzugefügt wurden (in der Staging-Umgebung)
  • Änderungen an Dateien, die aktuell von Git verfolgt werden (noch nicht in der Staging-Umgebung)

Nicht in den Stash verschoben wird Folgendes:

  • Neue Dateien in deiner Arbeitskopie, die sich noch nicht in der Staging-Umgebung befinden
  • Dateien, die ignoriert werden

Wenn wir also dem obigen Beispiel eine dritte Datei hinzufügen, diese aber nicht in die Staging-Umgebung verschieben (d. h. wir führen git add nicht aus), wird git stash die Datei nicht dem Stash hinzufügen.

$ script.js

$ git status
On branch main
Changes to be committed:

    new file:   style.css

Changes not staged for commit:

    modified:   index.html

Untracked files:

    script.js

$ git stash
Saved working directory and index state WIP on main: 5002d47 our new homepage
HEAD is now at 5002d47 our new homepage

$ git status
On branch main
Untracked files:

    script.js

Durch Hinzufügen der Option -u (oder --include-untracked) werden mit git stash auch deine nicht verfolgten Daten gestasht:

$ git status
On branch main
Changes to be committed:

    new file:   style.css

Changes not staged for commit:

    modified:   index.html

Untracked files:

    script.js

$ git stash -u
Saved working directory and index state WIP on main: 5002d47 our new homepage
HEAD is now at 5002d47 our new homepage

$ git status
On branch main
nothing to commit, working tree clean

Die Änderungen ignorierter Dateien können miteinbezogen werden, indem du die Option -a (oder --all) an den Befehl git stash anfügst.

Git Stash – Optionen

Verwalten mehrerer Stashes mit "git stash"


Du musst dich nicht auf einen einzigen Stash beschränken. Du kannst git stash mehrmals ausführen, um mehrere Stashes zu erstellen und diese anschließend mit git stash list ansehen. Standardmäßig werden Stashes an der Spitze des Branch und Commits, von dem du den Stash erstellt hast, einfach als "WIP", also Work in Progress, identifiziert. Nach einer Weile kann es schwierig werden, sich daran zu erinnern, was in dem jeweiligen Stash enthalten ist:

$ git stash list
stash@{0}: WIP on main: 5002d47 our new homepage
stash@{1}: WIP on main: 5002d47 our new homepage
stash@{2}: WIP on main: 5002d47 our new homepage

Zur Bereitstellung von mehr Kontextinformationen ist es sinnvoll, deine Stashes mithilfe von git stash save "Nachricht"mit einer Beschreibung zu versehen:

$ git stash save "add style to our site"
Saved working directory and index state On main: add style to our site
HEAD is now at 5002d47 our new homepage

$ git stash list
stash@{0}: On main: add style to our site
stash@{1}: WIP on main: 5002d47 our new homepage
stash@{2}: WIP on main: 5002d47 our new homepage

Standardmäßig wird mit git stash pop der zuletzt erstellte Stash erneut angewendet: stash@{0}

Du kannst aber wählen, welcher Stash erneut angewendet werden soll, indem du dessen Kennung als letztes Argument anfügst, z. B.:

$ git stash pop stash@{2}

Ansehen von Stash-Diffs


Mit git stash show wird eine Zusammenfassung für einen Stash angezeigt:

$ git stash show
 index.html | 1 +
 style.css | 3 +++
 2 files changed, 4 insertions(+)

Du kannst aber auch die Option -p (oder --patch) angeben, um den vollständigen Diff eines Stashes anzuzeigen:

$ git stash show -p
diff --git a/style.css b/style.css
new file mode 100644
index 0000000..d92368b
--- /dev/null
+++ b/style.css
@@ -0,0 +1,3 @@
+* {
+  text-decoration: blink;
+}
diff --git a/index.html b/index.html
index 9daeafb..ebdcbd2 100644
--- a/index.html
+++ b/index.html
@@ -1 +1,2 @@
+<link rel="stylesheet" href="style.css"/>

Partielle Stashes


Du kannst auch nur eine einzige Datei, mehrere Dateien oder auch beliebige Änderungen aus Dateien stashen. Wenn du die Option -p (oder --patch) für git stash angibst, wird der Befehl für jeden geänderten "Hunk" in deiner Arbeitskopie wiederholt und du musst angeben, ob du ihn stashen willst:

$ git stash -p
diff --git a/style.css b/style.css
new file mode 100644
index 0000000..d92368b
--- /dev/null
+++ b/style.css
@@ -0,0 +1,3 @@
+* {
+  text-decoration: blink;
+}
Stash this hunk [y,n,q,a,d,/,e,?]? y
diff --git a/index.html b/index.html
index 9daeafb..ebdcbd2 100644
--- a/index.html
+++ b/index.html
@@ -1 +1,2 @@
+<link rel="stylesheet" href="style.css"/>
Stash this hunk [y,n,q,a,d,/,e,?]? n
Git Stash -p

Wenn du auf das ? klickst, erhältst du eine vollständige Liste der Hunk-Befehle. Diese hier sind besonders nützlich:

Befehl

Beschreibung

/

Beschreibung

Suche nach einem Hunk mit einem regulären Ausdruck

?

Beschreibung

Hilfe

n

Beschreibung

Diesen Hunk nicht in den Stash verschieben

q

Beschreibung

beenden (von Englisch "quit"): Alle bereits ausgewählten Hunks werden gestasht.

s

Beschreibung

Diesen Hunk in kleinere Hunks aufteilen

y

Beschreibung

Diesen Hunk in den Stash verschieben

Es gibt zwar keinen ausdrücklichen Befehl zum "Abbrechen", aber mit Strg-C (SIGINT) kannst du den Stash-Prozess abbrechen.

Erstellen eines Branch von deinem Stash


Wenn die Änderungen an deinem Branch von den Änderungen in deinem Stash abweichen, kann es zu Konflikten kommen, wenn du deinen Stash anwendest. Stattdessen kannst du mit git stash branch einen neuen Branch erstellen, auf den du die Änderungen aus deinem Stash anwendest:

$ git stash branch add-stylesheet stash@{1}
Switched to a new branch 'add-stylesheet'
On branch add-stylesheet
Changes to be committed:

    new file:   style.css

Changes not staged for commit:

    modified:   index.html

Dropped refs/stash@{1} (32b3aa1d185dfe6d57b3c3cc3b32cbf3e380cc6a)

Hiermit werden ein neuer Branch auf Basis des Commits, auf dem du deinen Stash erstellt hast, ausgecheckt und dann die aufbewahrten Änderungen eingefügt.

Bereinigen des Stash


Wenn du einen bestimmten Stash nicht mehr benötigst, kannst du ihn mit git stash drop löschen:

$ git stash drop stash@{1}
Dropped stash@{1} (17e2697fd8251df6163117cb3d58c1f62a5e7cdb)

Oder du löschst alle deine Stashes mit:

$ git stash clear

Funktionsweise von git stash


Wenn du lediglich wissen wolltest, wie man den git stash-Code verwendet, brauchst du ab hier nicht weiterzulesen. Wenn es dich aber interessiert, was bei Git (und git stash) hinter den Kulissen passiert, dann solltest du dieses "git stash"-Tutorial unbedingt weiterlesen!

Stashes sind übrigens in deinem Repository als Commit kodiert. Die spezielle Referenz .git/refs/stash verweist auf deinen zuletzt erstellten Stash, früher erstellte Stashes werden über das Reflog der stash-Referenz referenziert. Deshalb referenzierst du Stashes über stash@{n}: Du referenzierst eigentlich den n-ten Reflog-Eintrag für den stash. Da ein Stash einfach ein Commit ist, kannst du ihn mit git log untersuchen:

Je nachdem, was du stashst, werden in einem einzigen git stash-Vorgang entweder zwei oder drei neue Commits durchgeführt. Im Beispiel oben gibt es folgende Commits:

  • stash@{0}, ein neuer Commit zum Speichern der verfolgten Dateien, die sich beim Ausführen von git stash in deiner Arbeitskopie befanden
  • Der erste übergeordnete Commit von stash@{0}, d. h. der vorher bereits bestehende Commit, der sich am HEAD befand, als du git stash ausgeführt hast
  • Der zweite Parent von stash@{0}, ein neuer Commit, der den Index von dem Zeitpunkt repräsentiert, als du git stash ausgeführt hast
  • Der dritte Parent von stash@{0}, ein neuer Commit, der die unverfolgten Dateien repräsentiert, die sich in deiner Arbeitskopie befanden, als du git stash ausgeführt hast. Der dritte Parent wird nur unter folgenden Voraussetzungen erstellt:
    • Deine Arbeitskopie enthält unverfolgte Dateien und
    • du hast die Option --include-untracked oder --all an git stash angefügt.

So codierst du mit git stash deinen Arbeitsbaum und deinen Index in Commits um:

  • Vor dem Stashing kann dein Arbeitsbaum Änderungen an verfolgten, nicht verfolgten und ignorierten Dateien enthalten. Einige dieser Änderungen befinden sich ggf. auch im Index (in der Staging-Umgebung).
Vor dem Erstellen eines Stash
  • Bei der Verwendung von git stash werden alle Änderungen an verfolgten Dateien als zwei neue Commits in deinem DAG (gerichteten azyklischen Graphen) kodiert: ein Commit für die Änderungen, die sich nicht in der Staging-Umgebung befinden und ein Commit, für die Änderungen, die sich in der Staging-Umgebung (Index) befinden. Die spezielle Referenz refs/stash wird aktualisiert, um auf diese Commits zu verweisen.
git stash – Tutorial
  • Mit der Option --include-untracked kannst du auch alle Änderungen an nicht verfolgten Dateien in einen weiteren Commit umkodieren.
Git stash --include-untracked
  • Die Option --all schließt Änderungen an ignorierten Dateien genauso wie Änderungen an unverfolgten Dateien im selben Commit ein.
Git Stash --all

Wenn du git stash pop ausführst, werden die Änderungen aus den obigen Commits zur Aktualisierung deiner Arbeitskopie und deines Index verwendet und der hervorgeholte Commit wird aus dem Stash-Reflog entfernt. Beachte, dass die hervorgeholten Commits nicht sofort gelöscht werden, sondern zu Kandidaten für die nächste Bereinigung werden.


Diesen Artikel teilen
Nächstes Thema

Lesenswert

Füge diese Ressourcen deinen Lesezeichen hinzu, um mehr über DevOps-Teams und fortlaufende Updates zu DevOps bei Atlassian zu erfahren.

Mitarbeiter arbeiten mit unzähligen Tools zusammen

Bitbucket-Blog

Abbildung: DevOps

DevOps-Lernpfad

Demo Den: Feature-Demos mit Atlassian-Experten

So funktioniert Bitbucket Cloud mit Atlassian Open DevOps

Melde dich für unseren DevOps-Newsletter an

Thank you for signing up