Programming and IT

git stash

The stash is a temporary shelf for unfinished edits. You put everything you have done there, get a clean working copy, deal with the urgent thing and then bring the work back. The shelf is shared by the whole repository and works like a stack: the last thing you put on it sits on top.

Updated
In this article

When you need it#

A typical situation: you are halfway through an edit and an urgent task arrives on another branch. You do not want to commit half-finished work, and you certainly do not want to lose it. The stash lifts the changes off your working copy and saves them in the repository as ordinary Git objects, which means safely.

The second reason is a branch switch that Git blocks because of conflicting edits. The third is checking how the program behaves without your changes: stash, check, bring back.

An important caveat: by default only changes to tracked files are stashed. A new file Git has never seen stays in the folder, and that regularly surprises people.

Syntax#

git stash push -m "half of the payment form"   # stash with a clear label
git stash push -u                           # including new files
git stash push -- src/api.py                # stash only the given paths
git stash list                              # what is on the shelf
git stash show -p stash@{1}                 # look inside an entry
git stash apply stash@{1}                   # bring back, keep the entry
git stash pop                               # bring back the top one and remove it
git stash drop stash@{0}                    # throw an entry away
git stash branch fix-payment stash@{0}      # a new branch from a stash

Plain git stash with no words is the same as git stash push. Always add a label with -m: two days later, unlabelled entries differ only by number and hash.

Example: set aside and bring back#

$ git status -s
 M templates/checkout.html
 M billing/forms.py
$ git stash push -m "half of the payment form"
Saved working directory and index state On main: half of the payment form
$ git status -s
$ git stash list
stash@{0}: On main: half of the payment form

The working copy is clean; you can switch branches and fix the urgent thing. When you come back:

$ git stash pop
On branch main
Changes not staged for commit:
        modified:   billing/forms.py
        modified:   templates/checkout.html

Dropped refs/stash@{0} (1f9a3b8c4d2e5f60718293a4b5c6d7e8f9a0b1c2)

The edits are back and the entry is gone from the shelf. The hash on the last line is not decoration: with it you can bring the entry back even if you removed it by mistake.

Example: stashing new files#

$ git status -s
 M report.py
?? templates/pdf.html
$ git stash push -u -m "print draft"
Saved working directory and index state On main: print draft
$ git status -s
$

Without -u, templates/pdf.html would have stayed in the folder. With the flag it went onto the shelf along with the rest. If you also need ignored files, there is the broader -a, but with it you can easily drag a build folder of hundreds of megabytes onto the shelf.

Pop or apply#

Both commands bring back the contents of an entry. The difference is what happens to the entry itself: pop deletes it, apply keeps it.

It is safer to use apply and run drop only after you have made sure the edits landed where they should and the project builds. Then any surprise — applied on the wrong branch, resolved a conflict badly — costs one git checkout ., because the copy is still on the shelf.

On a conflict, pop behaves carefully: conflict markers appear in the files, but the entry is not removed from the shelf. You resolve it like any other conflict — the routine is described in how to resolve a merge conflict.

Another tidy option is to create a branch straight away:

$ git stash branch feature-pdf stash@{0}

Git creates a branch from the commit the stash was made on, applies the edits and removes the entry. This is the best way out when the stashed work has been sitting for a long time and no longer fits on the current tip.

Common mistakes#

Forgetting the shelf is shared. Stashes are not tied to a branch: you can put something on the shelf on one branch and take it off on another, and Git will not object. Putting the branch name in the label saves you from confusion.

git stash pop after switching to another branch. The edits are applied where you are now. If that is not what you wanted, put them back: git stash push -m "wrong place" and take them off again on the right branch.

An entry deleted by mistake. git stash drop and git stash clear print the hash of the deleted object, and the object lives in the database until garbage collection. You can restore it like this:

$ git stash drop
Dropped refs/stash@{0} (1f9a3b8c4d2e5f60718293a4b5c6d7e8f9a0b1c2)
$ git stash apply 1f9a3b8c4d2e5f60718293a4b5c6d7e8f9a0b1c2

If the hash was lost along with the terminal window, all that is left is searching unreachable objects: git fsck --unreachable | grep commit. It does not always work, so do not rely on it.

A stash instead of a branch. The shelf is good for hours, not weeks: its contents are not visible in history, are not pushed to the server and are lost with the disk. Work that outlives a day deserves a commit on its own branch — creating one takes a second, see git branch.

Step-by-step plan

  1. See what you are stashinggit status -s: are there new files among your edits — that decides whether you need -u.
  2. Stash with a labelgit stash push -m "clear text", with -u if needed.
  3. Do the urgent thingThe working copy is clean: switching branches and building work without trouble.
  4. Bring the work backgit stash list, then git stash apply stash@{N} on the right branch.
  5. Tidy the shelfMake sure everything landed correctly, then git stash drop; move long-running work to a branch.

Start learning this in your own space

The plan goes into your repository: tick off stages, keep notes — the change history shows how far you have come.

Start the plan

Check yourself

1.How does git stash pop differ from git stash apply?

2.Which flag stashes a new, untracked file together with your edits?

3.Stashed work has been sitting for a week and no longer fits on the current tip. What is the most convenient thing to do?

Sources

Was this helpful?

More articles

Programming and IT git commit A commit is a saved state of your project with an author, a timestamp and a message. git commit takes what you selected beforehand with git add and writes it into history as one indivisible piece. Programming and IT git merge Merging brings work from one branch into another. git merge takes the branch you name and joins its history with the current one — sometimes by just moving a pointer, sometimes by creating a separate commit, and sometimes by stopping and asking for help. Programming and IT Git commands Git has well over a hundred commands, but on an ordinary day you use about twenty. Here they are in the order you need them — from your first copy of a repository to undoing a bad step — with one line of explanation each. Programming and IT Git branches A Git branch is a movable pointer to a commit, not a copy of your files. That is why creating one costs nothing, and the git branch command is what you use to list, create, rename and delete branches. Programming and IT git checkout Historically `git checkout` does several unrelated things at once: it moves your working copy to another branch, creates a branch and pulls a single file out of a commit. Because it was so overloaded, Git 2.23 added two separate commands — `switch` and `restore`. Here are both sides: the old way and its modern replacement. Programming and IT git rebase git rebase moves the commits of your branch as if you had started work not from an old state but from the current one. History becomes linear, but the commits are created anew — with new hashes. That leads to the main rule: you can only rebase what nobody else is using.

More solutions