skip to content

In Git, what is the difference between git stash pop and git stash apply?

level: juniorimportance: must knowfreq 74%

answer

  1. Both restore; one also cleans up
  2. Think about what stays in the list afterwards
  3. Pop equals apply plus drop
  4. A conflict changes the cleanup behaviour
  5. Neither restores staging without --index

basics

~20 s

Both restore a saved stash into your working tree; pop also deletes the stash entry afterwards, while apply leaves it in the list. If a pop hits a conflict, the entry is kept, so nothing is lost.

solid answer

~40 s

`git stash push` shelves your uncommitted tracked changes and leaves a clean working tree; `apply` and `pop` are the two ways to bring them back. `git stash apply` replays the stash's changes into the working tree and leaves the entry in `git stash list`, so you can apply the same stash again — on another branch, for instance. `git stash pop` does the same thing and then drops the entry on success. I default to `apply` when I am not yet sure the restore is right, and `pop` for the ordinary "put my work back" case. One important detail: if the application conflicts, `pop` does **not** drop the entry, so a conflicted pop never loses the stash — you resolve, then `git stash drop` by hand.

code

console · 10 lines
console
$ git stash push -m "parser wip"
Saved working directory and index state On feature: parser wip
$ git stash list
stash@{0}: On feature: parser wip
$ git stash apply
$ git stash list
stash@{0}: On feature: parser wip
$ git stash pop
$ git stash list
$

go deeper

for a junior

Recall the one-liner: pop restores and deletes the entry, apply restores and keeps it. Know that git stash list shows what you have and that both commands default to stash@{0}.

for a middle

Explain that pop is literally apply followed by drop, that restoring is a merge and so can conflict, and that the index is not restored unless you pass --index.

for a senior

Show restore judgment: apply when the target branch is uncertain or the changes are needed twice, pop for the routine case, and a habit of messaging and inspecting stashes rather than accumulating them.

for a principal

Argue about where uncommitted work should live at all — throwaway branches or worktrees give named, reviewable, pushable state, while a deep stash list is undiscoverable work nobody else can see.

## What a stash is for You are halfway through a change when something urgent arrives: a hotfix, a branch to review, a colleague's bug. `git stash push` (or the bare `git stash`) records your uncommitted work, then resets the working tree and index back to `HEAD`, leaving you clean. Later you restore it. By default a stash covers **tracked** files: modifications to tracked files in the working tree and staged changes in the index. Untracked and ignored files are left alone unless you ask for them explicitly. ## The two restore verbs ``` git stash list stash@{0}: WIP on feature: 9a3f21c Add parser skeleton stash@{1}: WIP on main: 47bd0e1 Bump version git stash apply # restore stash@{0}, keep the entry git stash pop # restore stash@{0}, then drop it ``` Both default to the most recent entry, `stash@{0}`, and both accept an explicit one: `git stash apply stash@{2}`. The only difference is the cleanup. `pop` is `apply` followed by `drop`. That is a real convenience — an unpopped stash list is how stashes accumulate for months until nobody knows what is in them — but it means an entry disappears once the restore looks successful. ## When to prefer `apply` - You want the same changes on **more than one** branch: apply, then apply again elsewhere. - You are not sure this is the right branch to restore onto and want a trivial undo: discard the working tree and apply again. - You are restoring an old entry and want the list untouched while you check what came back. The cost is a stash list that grows; clean it with `git stash drop stash@{n}` for one entry, or `git stash clear` for all of them. `clear` is unforgiving — it discards every entry at once. ## Staging is not preserved by default A point interviewers like: restoring does **not** rebuild your index. Everything the stash contained comes back as unstaged working-tree changes, even the parts that were staged when you stashed. If you want the original staged/unstaged split back, pass `--index`: ``` git stash pop --index ``` That can fail where the plain form would succeed, because Git has to reproduce a specific index state as well as the file contents. ## Conflicts and why pop is safer than it looks Restoring is a merge, not a file copy, so it can conflict if the branch moved since you stashed. On conflict, Git writes conflict markers into the affected files and — crucially — **keeps** the stash entry. `pop` only drops after a clean application. So a conflicted pop leaves you with work to resolve *and* the original stash still in the list; after resolving you drop it yourself. ## Addressing entries `stash@{0}`, `stash@{1}` and so on are positions in the stash list, not stable names. Push a new stash and everything shifts down by one. Inspect before you act: ``` git stash list git stash show stash@{1} # summary of changed files git stash show -p stash@{1} # full patch ``` Giving stashes messages when you create them (`git stash push -m "parser wip"`) turns an unreadable list of `WIP on branch:` lines into something you can navigate weeks later. ## Common mistakes - Assuming `pop` restores staging. It does not, unless you pass `--index`. - Assuming `pop` always removes the entry. A conflict keeps it. - Treating the stash as long-term storage. It is a shelf, not a branch — entries carry no branch name in their identity and become impossible to interpret after a few weeks. If work matters, commit it on a branch. - Running `git stash clear` to "clean up" without checking what is in the list. ## What a good answer sounds like "`pop` is `apply` plus `drop`. Use `apply` when you might need the stash again or are unsure about the target branch; use `pop` for the normal restore. Neither restores the index unless you pass `--index`, and a conflicting `pop` keeps the entry so nothing is lost."

  • Does restoring a stash put your staged changes back in the index?
    No. By default everything comes back as unstaged working-tree modifications, even what was staged when you stashed. Pass `--index` to `apply` or `pop` to reproduce the original staged/unstaged split. That form is stricter and can fail where the plain restore succeeds, because Git must recreate a specific index state as well as the file contents.
  • How do you restore an older stash instead of the most recent one?
    Name it: `git stash apply stash@{2}` or `git stash pop stash@{2}`. Check first with `git stash list` and `git stash show -p stash@{2}`, because the numbers are positions, not stable identifiers — creating a new stash shifts every existing entry down by one.
  • Why is git stash clear risky?
    It discards every stash entry at once, and unlike `drop` on a single entry it gives no per-entry confirmation of what you are throwing away. Review `git stash list` first, and drop entries individually when you only mean to prune a few.

Apply is photocopying a note off the shelf and leaving the original there; pop is taking the note down and throwing the shelf copy away once you have it in hand.

saying these in an interview costs you the question

  • Believing apply also removes the stash entry
  • Expecting the staging area to be restored automatically
  • Thinking a conflicted pop deletes the stash anyway
  • Using the stash list as long-term storage for real work
  • Running git stash clear without inspecting the list

context