GIT-STASH(1)
π GIT-STASH(1) β Git Manual π
β¨ NAME β¨
git-stash β stash the changes in a dirty working directory away. π
β¨ SYNOPSIS β¨
git stash list [<log-options>]
git stash show [-u | --include-untracked | --only-untracked] [<diff-options>] [<stash>]
git stash drop [-q | --quiet] [<stash>]
git stash pop [--index] [-q | --quiet] [<stash>]
git stash apply [--index] [-q | --quiet] [--label-ours=<label>] [--label-theirs=<label>] [--label-base=<label>] [<stash>]
git stash branch <branchname> [<stash>]
git stash [push] [-p | --patch] [-S | --staged] [-k | --[no-]keep-index] [-q | --quiet]
[-u | --include-untracked] [-a | --all] [(-m | --message) <message>]
[--pathspec-from-file=<file> [--pathspec-file-nul]]
[--] [<pathspec>...]
git stash save [-p | --patch] [-S | --staged] [-k | --[no-]keep-index] [-q | --quiet]
[-u | --include-untracked] [-a | --all] [<message>]
git stash clear
git stash create [<message>]
git stash store [(-m | --message) <message>] [-q | --quiet] <commit>
git stash export (--print | --to-ref <ref>) [<stash>...]
git stash import <commit>
β¨ DESCRIPTION β¨
okay so bestie, use git stash when you want to record the current state of the working directory and the index, but you also want to go back to a clean working directory. The command saves your local modifications away and reverts the working directory to match the HEAD commit. β¨
The modifications stashed away by this command can be listed with git stash list, inspected with git stash show, and restored (potentially on top of a different commit) with git stash apply. Calling git stash without any arguments is equivalent to git stash push. A stash is by default listed as "WIP on <branchname> ...", but you can give a more descriptive message on the command line when you create one. π
The latest stash you created is stored in refs/stash; older stashes are found in the reflog of this reference and can be named using the usual reflog syntax (e.g. stash@{0} is the most recently created stash, stash@{1} is the one before it, stash@{2.hours.ago} is also possible). Stashes may also be referenced by specifying just the stash index (e.g. the integer <n> is equivalent to stash@{<n>}). π¦
β¨ COMMANDS β¨
πΈ push πΈ
push [-p | --patch] [-S | --staged] [-k | --[no-]keep-index] [-u | --include-untracked] [ -a | --all] [-q | --quiet] [(-m|--message) <message>] [--pathspec-from-file=<file> [--pathspec-file-nul]] [--] [<pathspec>...]
Save your local modifications to a new stash entry and roll them back to HEAD (in the working tree and in the index). The <message> part is optional and gives the description along with the stashed state. π
For quickly making a snapshot, you can omit "push". In this mode, pathspec elements are only allowed after a double hyphen -- to prevent a misspelled subcommand from making an unwanted stash entry. π
π save π
save [-p | --patch] [-S | --staged] [-k | --[no-]keep-index] [-u | --include-untracked] [-a | --all] [-q | --quiet] [<message>]
This option is deprecated in favour of git stash push. It differs from "stash push" in that it cannot take pathspec. Instead, all non-option arguments are concatenated to form the stash message. π
π¦ list π¦
list [<log-options>]
List the stash entries that you currently have. Each stash entry is listed with its name (e.g. stash@{0} is the latest entry, stash@{1} is the one before, etc.), the name of the branch that was current when the entry was made, and a short description of the commit the entry was based on. π
stash@{0}: WIP on submit: 6ebd0e2... Update git-stash documentation
stash@{1}: On master: 9cc0589... Add git-stash
The command takes options applicable to the git log command to control what is shown and how. See git-log(1). β¨
π show π
show [-u | --include-untracked | --only-untracked] [<diff-options>] [<stash>]
Show the changes recorded in the stash entry as a diff between the stashed contents and the commit back when the stash entry was first created. By default, the command shows the diffstat, but it will accept any format known to git diff (e.g., git stash show -p stash@{1} to view the second most recent entry in patch form). If no <diff-option> is provided, the default behavior will be given by the stash.showStat, and stash.showPatch config variables. You can also use stash.showIncludeUntracked to set whether --include-untracked is enabled by default. π«Ά
πΈ pop πΈ
pop [--index] [-q | --quiet] [<stash>]
Remove a single stashed state from the stash list and apply it on top of the current working tree state, i.e., do the inverse operation of git stash push. The working directory must match the index. β
Applying the state can fail with conflicts; in this case, it is not removed from the stash list. You need to resolve the conflicts by hand and call git stash drop manually afterwards. π
π§ apply π§
apply [--index] [-q | --quiet] [<stash>]
Like pop, but do not remove the state from the stash list. Unlike pop, <stash> may be any commit that looks like a commit created by stash push or stash create. π
π branch π
branch <branchname> [<stash>]
Creates and checks out a new branch named <branchname> starting from the commit at which the <stash> was originally created, applies the changes recorded in <stash> to the new working tree and index. If that succeeds, and <stash> is a reference of the form stash@{<revision>}, it then drops the <stash>. π
This is useful if the branch on which you ran git stash push has changed enough that git stash apply fails due to conflicts. Since the stash entry is applied on top of the commit that was HEAD at the time git stash was run, it restores the originally stashed state with no conflicts. β¨
π clear π
Remove all the stash entries. Note that those entries will then be subject to pruning, and may be impossible to recover (see EXAMPLES below for a possible strategy). π
π
drop π
drop [-q | --quiet] [<stash>]
Remove a single stash entry from the list of stash entries. π«Ά
π create π
Create a stash entry (which is a regular commit object) and return its object name, without storing it anywhere in the ref namespace. This is intended to be useful for scripts. It is probably not the command you want to use; see "push" above. β
π₯ store π₯
Store a given stash created via git stash create (which is a dangling merge commit) in the stash ref, updating the stash reflog. This is intended to be useful for scripts. It is probably not the command you want to use; see "push" above. π
πΈ export πΈ
export ( --print | --to-ref <ref> ) [<stash>...]
Export the specified stashes, or all of them if none are specified, to a chain of commits which can be transferred using the normal fetch and push mechanisms, then imported using the import subcommand. π¦
π import π
import <commit>
Import the specified stashes from the specified commit, which must have been created by export, and add them to the list of stashes. To replace the existing stashes, use clear first. π«Ά
β¨ OPTIONS β¨
Ok bestie, this is the big one β every flag, what it's for, and which commands even accept it. Read the "only valid for" bits, they're doing heavy lifting π
-a,--allβ only valid forpushandsave. Stashes all your ignored and untracked files too, then cleans them up withgit clean. Yes, cleanup β be sure you meant it π-u,--include-untracked,--no-include-untrackedβ two moods, depending on the command. Withpushandsave: all untracked files get stashed too, then cleaned up withgit clean. Withshow: shows the untracked files in the stash entry as part of the diff.--only-untrackedβ only valid forshow. Shows only the untracked files in the stash entry as part of the diff.--indexβ only valid forpopandapply. Tries to reinstate not just the working tree's changes but the index's too. Warning though: this can fail when you have conflicts (conflicts live in the index, so you can no longer apply the changes as they originally were) π«--label-ours=<label>,--label-theirs=<label>,--label-base=<label>β only valid forapply. Use your own labels in conflict markers instead of the defaults"Updated upstream","Stashed changes", and"Stash base". Heads up:--label-baseonly does anything withmerge.conflictStyle=diff3.-k,--keep-index,--no-keep-indexβ only valid forpushandsave. Everything already added to the index is left intact. Untouched, unbothered, thriving β¨-p,--patchβ only valid forpushandsave. Interactively pick hunks from the diff betweenHEADand the working tree to be stashed. The stash entry is built so its index state matches your repo's index state, and its worktree holds only the changes you picked interactively. Those selected changes then get rolled back from your worktree. Wanna know how to actually drive--patchmode? See the "Interactive Mode" section of git-add(1).
Also: --patch implies --keep-index. If you don't want that, use --no-keep-index to override it.
-U<n>,--unified=<n>β makes diffs with<n>lines of context. That number defaults todiff.context, or3if that config variable isn't set. And yeah β-Uwithout<n>is silently accepted as a synonym for-pbecause of a historical accident π (we don't talk about it).--inter-hunk-context=<n>β shows the context between diff hunks, up to the given<number>of lines, fusing hunks that are close together. Defaults todiff.interHunkContext, or0if that config option isn't set.-S,--stagedβ only valid forpushandsave. Stashes only what's currently staged. Basically like a regulargit commit, except the state goes into the stash instead of the current branch. And--patchhas priority over this one, so don't fight it.--pathspec-from-file=<file>β only valid forpush. The pathspec comes from<file>instead of commandline args. If<file>is exactly-, standard input is used. Pathspec elements are separated by LF or CR/LF, and they can be quoted exactly as explained for the config variablecore.quotePath(see git-config(1)). Also peep--pathspec-file-nuland the global--literal-pathspecs.--pathspec-file-nulβ only valid forpush. Only meaningful alongside--pathspec-from-file. Pathspec elements get separated by a NUL character and everything else is taken literally (newlines and quotes included).-q,--quietβ only valid forapply,drop,pop,push,save,store. Quiet mode, suppresses feedback messages. For when you want it to just happen π€«--printβ only valid for theexportcommand. Builds the chain of commits representing the exported stashes without storing it anywhere in the ref namespace, and prints the object ID to standard output. Made for scripts, fr fr.--to-refβ only valid for theexportcommand. Builds the chain of commits representing the exported stashes and stores it to the specified ref.--β only valid forpush. Separates your pathspec from your options so there's no ambiguity.<pathspec>...β only valid forpush. The new stash entry records modified states only for the files matching the pathspec. Then the index entries and working tree files get rolled back to the state inHEADβ again, only for those files β leaving everything that doesn't match the pathspec completely intact π«Ά
For more deets, see the pathspec entry in gitglossary(7).
<stash>β only valid forapply,branch,drop,pop,show, andexport. It's a reference of the formstash@{<revision>}. Don't pass one and the latest stash is assumed (akastash@{0}).
π¬ DISCUSSION π¬
So how is a stash entry actually stored? Picture it as a commit whose tree records the state of the working directory, and whose first parent is the commit at HEAD back when the entry was created. The tree of the second parent records the state of the index at the moment the entry was made, and that second parent is made a child of the HEAD commit. The ancestry graph is giving this:
.----W
/ /
-----H----I
where H is the HEAD commit, I is a commit that records the state of the index, and W is a commit that records the state of the working tree. Little family photo ππ
πΈ EXAMPLES πΈ
Pulling into a dirty tree
You're mid-something, and you find out there are upstream changes that might matter to what you're doing. If your local changes don't conflict with the upstream ones, a plain git pull just carries you forward. Iconic, no notes.
But sometimes your local changes do conflict with upstream, and git pull refuses to overwrite them. In that case you stash your changes away, do the pull, then unstash, like so:
$ git pull
...
file foobar not up to date, cannot merge.
$ git stash
$ git pull
$ git stash pop
Interrupted workflow
You're in the middle of something and your boss walks in demanding you fix a thing immediately. The old-school way was making a commit on a temporary branch to park your changes, then going back to your original branch to do the emergency fix, like this:
# ... hack hack hack ...
$ git switch -c my_wip
$ git commit -a -m "WIP"
$ git switch master
$ edit emergency fix
$ git commit -a -m "Fix in a hurry"
$ git switch my_wip
$ git reset --soft HEAD^
# ... continue hacking ...
git stash lets you simplify all of that into this:
# ... hack hack hack ...
$ git stash
$ edit emergency fix
$ git commit -a -m "Fix in a hurry"
$ git stash pop
# ... continue hacking ...
Same energy, way less drama β¨
Testing partial commits
Use git stash push --keep-index when you want to make two or more commits out of the changes in your work tree and you want to test each change before committing it:
# ... hack hack hack ...
$ git add --patch foo # add just first part to the index
$ git stash push --keep-index # save all other changes to the stash
$ edit/build/test first part
$ git commit -m 'First part' # commit fully tested change
$ git stash pop # prepare to work on all other changes
# ... repeat above five steps until one commit remains ...
$ edit/build/test remaining parts
$ git commit foo -m 'Remaining parts'
Trust the process π§
Saving unrelated changes for future use
You're deep in massive changes and you spot some unrelated issue you don't wanna forget to fix. So do the change(s), stage them, and run git stash push --staged to stash them away for later. It's like committing the staged changes, except the commit ends up in the stash and not on the current branch. Chef's kiss π
# ... hack hack hack ...
$ git add --patch foo # add unrelated changes to the index
$ git stash push --staged # save these changes to the stash
# ... hack hack hack, finish current changes ...
$ git commit -m 'Massive' # commit fully tested changes
$ git switch fixup-branch # switch to another branch
$ git stash pop # to finish work on the saved changes
Recovering stash entries that were cleared/dropped erroneously
Real talk: if you accidentally drop or clear stash entries, they cannot be recovered through the normal safety mechanisms. But you can try this little incantation to get a list of stash entries that are still in your repository but no longer reachable:
git fsck --unreachable |
grep commit | cut -d\ -f3 |
xargs git log --merges --no-walk --grep=WIP
Not guaranteed, but it's something π―οΈ
βοΈ CONFIGURATION βοΈ
Everything below this line in this section is selectively included from the git-config(1) documentation. The content is the same as what's found there:
stash.indexβ if set totrue,git stash applyandgit stash popbehave as if--indexwas supplied. Defaults tofalse.stash.showIncludeUntrackedβ if set totrue, thegit stash showcommand will show the untracked files of a stash entry. Defaults tofalse.stash.showPatchβ if set totrue, thegit stash showcommand without an option will show the stash entry in patch form. Defaults tofalse.stash.showStatβ if set totrue, thegit stash showcommand without an option will show a diffstat of the stash entry. Defaults totrue.
π¦ EXIT STATUS π¦
The git stash subcommands exit with status 0 on success. The subcommands that apply a stash entry β that's apply, pop, and branch β exit with status 1 when applying the stash entry resulted in conflicts, in which case the stash entry is left in place π«Ά. They exit with a non-zero status other than 1 when they fail for other reasons.
π SEE ALSO π
git-checkout(1), git-commit(1), git-reflog(1), git-reset(1), git-switch(1)
π GIT π
Part of the git(1) suite. Obviously π
That's the whole page, bestie β go forth and stash responsibly π¦
Source: Git 2.56.0 Β· dated 2026-09-27 β that's the version and date of this manual page, mwah π
π¦ where this page comes from
- arch rolling: git 2.56.0-1 Β· GPL-2.0-only
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms