As developers, our work is constantly evolving. New features, bug fixes, experiments – our progress is made incrementally through an iterative process. This means our working tree often contains unfinished changes that aren‘t ready to be committed.
Git stash is the perfect mechanism to temporarily store these changes and clean up our working tree. Later on, we can reapply these changes when we‘re ready to resume work.
Why Git Stash is Useful
There are many instances where stashing your work makes sense:
- Switching contexts – Moving between features or fixing a quick bug
- Collaborating with others – Sharing incomplete solutions via branch/PR
- Testing rigorously – Stash allows precise control for isolation
- Transferring changes – Stash changes to apply on another machine
According to recent data from StackOverflow, Git stash is used regularly by 68% of developers who use Git:
Source: StackOverflow 2021 Developer Survey
With such ubiquitous usage, truly understanding Git stash can make you more efficient. Let‘s dig deeper!
How Git Stash Works
When executing git stash
, Git will:
- Save all uncommitted changes (staged and unstaged) to a new stash entry
- Remove those changes completely from your working tree and index
- Record the stash entry in your repo‘s stash stack for later retrieval
Here‘s a quick visualization of this process:
Source: Atlassian
Looking closely at each step:
1. Capturing Changes
By default, stash will capture:
- All modifications to tracked files
- New file additions staged with
git add
But it will not capture:
- Untracked new files
- Ignored file changes
The -u
and -a
options can alter this behavior to also stash untracked/ignored files.
2. Resetting State
Once the changes are captured, Git will reset your state back to match HEAD commit by:
- Removing all changes from files
- Resetting index to HEAD commit
- Leaving untracked files alone
This puts your tree in a git clean
state.
3. The Stash Stack
The stashes are stored in reverse chronological order, with most recent stash first.
This stack structure allows easily accessing stashes by index: stash@{0}
Underneath, they are implemented as normal Git commits in the .git/refs/stash
reference.
Inspecting Your Stash
With so many actions occurring under the hood, inspecting our stash is critical for proper usage:
# See list of stashed changes
$ git stash list
# Show stash diff metadata
$ git stash show -p
# Show full file diff for first stash
$ git stash show stash@{0} -p
show
after git stash
to view changes as they are stashed!
$ git stash show
These read-only commands give visibility into our saved stash changes:
- List – Displays high-level metadata per stash
- Show – Reports file diffs applied in the stash commit
- Show -p – Renders full file differences and patch content
Between list, show, and show -p you can audit a stash almost as effectively as inspecting a regular commit.
Applying Stashed Changes
Once we‘ve stored away changes, eventually we need to reapply them.
This can be done with apply
or pop
:
# Apply most recent stash
$ git stash apply
# Apply 3rd stash in list, leaves index/tree intact
$ git stash apply stash@{2}
# Apply stash and remove from stack
$ git stash pop
The apply
route will:
- Apply the stashed diffs to your working tree and index
- Leave the stash commit intact on the stash stack
Meanwhile, pop
will:
- Apply and remove the stash from your stack
- Essentially runs
apply
+drop
in sequence
Between these two choices you can choose whether keeping the stash around is useful or not.
Advanced Git Stash Techniques
Up to this point we‘ve covered the basics – now let‘s explore some advanced strategies.
Managing Multiple Stashes
When stashing repeatedly, your list can grow long:
$ git stash list
stash@{0}: WIP modal component
stash@{1}: Fix sidebar rendering
stash@{2}: New file upload module
To clean up, use:
git stash drop
– Discard a specific stash safelygit stash clear
– Remove all stashes
And if existing stashes need reusable:
git stash branch <branch> stash@{2}
– Creates branch from stash content for further work
Interactive Stashing
By default git stash
captures all changes. To "cherry-pick" changes to stash, use interactive mode:
$ git stash -p
This will go file-by-file and hunk-by-hunk prompting if you want to stash/keep changes – very handy and precise.
git stash -p
to selectively manage chunks of files rather than all or nothing!
Creative Stash Usage
Stash commits can also be:
- Shared via push/pull allowing collaboration similar to patches
- Used as throwaway branches to encapsulate logical units of work
- Leveraged to gather forensic data after a failure – stash, then inspect
Don‘t limit yourself to just temporary storage!
Comparing Stash With Checkout & Commit Amending
A key decision developers face regularly:
Should I commit my changes or stash them for later?
Understanding the key differences helps guide when to use each tool.
Git Checkout
Discarding current changes can be done via:
$ git checkout -- <target>
However this is:
- Destructive – uncommitted modifications are permanently deleted
- Limited – only works on individual files
Overall git checkout
is ideal for wiping small incremental changes.
Git Commit Amend
Amending the previous commit is an option as well:
$ git add .
$ git commit --amend
But this has challenges around:
- Rewriting history – avoid on public branch commits
- Confusion – old commit SHAs change
Amending works nicely to augment previous local commits.
Git Stash
Unlike these other approaches, git stash
is:
- Reversible – changes are stored and can be reapplied
- Flexible – handles both file additions and deletions
- Non-destructive – nothing is lost, changes are shelved in stash
The full recoverability of stash makes it preferential in many cases.
Wrap Up
In summary, Git stash enables storing, tracking, and reusing in-flight changes – a uniquely useful ability in decentralized version control systems. Integrating git stash save
and git stash pop
into your toolkit unlocks new possibilities:
- Make urgent fixes without messy commits
- Collaborate through shared stashes
- Test theories by stashing experiments
- Keep in-progress changes resumable
The added control of having "on-demand shelf space" for changes revolutionizes the developer workflow.
While other tools like commit amending or git checkout have their place, they lack stash‘s surgical precision and non-destructive nature. Through clever use of branching, interactive selection, and the versatile apply/pop behaviors meaningful ways to utilize stashes are endless.
As you embark on your next feature branch or experimental idea, keep Git stash top of mind. Once mastered, it can help optimize our ever-changing work trees!