1. Introduction
With either git stash pop or git stash apply, we can retrieve and apply a stashed state. So, on the surface, they may appear to do the same thing. However, they’re not exactly the same.
In this tutorial, we compare and contrast git stash pop and git stash apply.
2. Creating a Stash for Illustration
To show the differences between git stash pop and git stash apply, let’s create a local repo using git init:
$ git init
In our repo, let’s create a file, file.txt:
$ echo "Hello World" > file.txt
Finally, let’s stage the file and commit it to the local repo using git add and git commit, respectively:
$ git add . && git commit -m "initial commit"
Now that we’ve committed the file to our local repo, we can start stashing changes to it.
2.1. Stashing Changes
For our first change, let’s replace the content of file.txt with “Hello Baeldung” using echo:
$ echo "Hello Baeldung" > file.txt
Now, let’s stash this change away using git stash push:
$ git stash push
Saved working directory and index state WIP on main: d344c10 initial commit
After stashing the change away, file.txt reverts to its initial content, “Hello World”:
$ cat file.txt
Hello World
Let’s make a second change, this time replacing the content of the file with “Hello Git”:
$ echo "Hello Git" > file.txt
Let’s stash this away, too:
$ git stash push
Saved working directory and index state WIP on main: d344c10 initial commit
file.txt will revert to its initial state as before.
After stashing those two changes away, we’ll have our git stash list:
$ git stash list
stash@{0}: WIP on main: d344c10 initial commit
stash@{1}: WIP on main: d344c10 initial commit
With our stash list in place, we can proceed with our objective: comparing and contrasting git stash apply and git stash pop.
3. git stash apply
git stash apply applies a stashed state from the working directory’s stash list without removing the applied entry.
When we run git stash apply without specifying a particular stash, it applies the latest entry in the stash list:
$ git stash apply
On branch main
Your branch is up to date with 'origin/main'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: file.txt
no changes added to commit (use "git add" and/or "git commit -a")
The last change we stashed away was the “Hello Git” change to file.txt. So, when we ran git stash apply, it changed the content of file.txt back to “Hello Git”:
$ cat file.txt
Hello Git
Of course, if we run git stash apply on a specific stash entry, it will apply that entry.
Now that we’ve run git stash apply, let’s check on our stash list:
$ git stash list
stash@{0}: WIP on main: d344c10 initial commit
stash@{1}: WIP on main: d344c10 initial commit
As shown, our stash list remains unchanged even after running git stash apply.
4. git stash pop
git stash pop removes a stashed state from the working directory’s stash list and applies it.
When we run git stash pop without referencing a particular stash, it applies and removes the most recent entry into the stash list:
$ git stash pop
On branch main
Your branch is up to date with 'origin/main'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: file.txt
no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (2dd4ffe4f0c000bf7a0b116cbf965ea0d91d601d)
Naturally, when we run git stash pop on a specific stash, it applies and removes the specified stash.
From the last line of the command output, we can see that the applied stash was dropped. Also, if we check our stash list, we should have only one entry now:
$ git stash list
stash@{0}: WIP on main: d344c10 initial commit
5. Differences Between git stash pop and git stash apply
git stash pop and git stash apply are similar in that they both apply a stashed state from the working directory’s stash list. Both commands also handle conflicts in the same way – Git stops their execution when there’s a conflict and prompts for manual resolution. However, there are some crucial differences between them.
5.1. Effect and Use Case
git stash pop changes the content of a list of stash entries but git stash apply doesn’t. In most cases, we would probably stick to using git stash apply since we wouldn’t have to worry about mistakenly removing a stash that we still need.
But then, in situations where we’re confident that we wouldn’t need a stash entry after applying it, git stash pop would work just fine. That being said, we can recover a stash dropped by git stash pop. Of course, we’d rather avoid those extra steps, so we’d stick with git stash apply until we’re quite sure.
git stash pop offers the added advantage of not having to delete stash entries manually. Essentially, git stash pop is like running git stash apply and git stash drop in a single command.
5.2. Predictability
Since it doesn’t change the stash entries list, git stash apply is more predictable than git stash pop. In the absence of conflicts, an execution of git stash apply on an unchanged stash list will produce the same effect every time.
git stash pop applies a different stash state with each execution. So, it is a bit unpredictable.
6. Conclusion
In this article, we discussed git stash pop and git stash apply, mentioning their similarities and going over their differences.
The primary distinction between git stash pop and git stash apply lies in alterations to stash lists. While git stash pop modifies stash lists, git stash apply doesn’t. Of course, this makes git stash apply more predictable.