skip to content

questions

5

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

open as a page

How does Git store a stash internally — what commits and refs does git stash push create?

level: middleimportance: should knowfreq 36%

basics

~20 s

A stash is ordinary commits. git stash push writes a commit whose tree is your working tree, with your HEAD commit as first parent and a commit recording the index state as second; refs/stash points at it, and stash@{n} indexes that ref's reflog.

open as a page

Why does git stash leave new untracked files behind, and which flags include them?

level: middleimportance: should knowfreq 55%

basics

~20 s

By default git stash only records tracked content — index changes and modifications to files Git already knows. Untracked files are invisible to it. Use -u (--include-untracked) to add untracked files, or -a (--all) to include ignored files too.

open as a page

Your git stash pop conflicts — what state is the repository in and how do you finish safely?

level: seniorimportance: should knowfreq 48%

basics

~20 s

You have conflict markers in the affected files, those paths unmerged in the index, and the stash entry still in the list because pop only drops after a clean apply. Resolve, git add the files, then drop the entry by hand.

open as a page

What does git stash push --keep-index do, and when would you use it?

level: seniorimportance: nice to knowfreq 28%

basics

~20 s

It stashes everything as usual but leaves the staged changes in place in the index and working tree, so you can build and test exactly the content you are about to commit, with all unstaged work temporarily out of the way.

open as a page