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:

Chart showing 68% of Git users leverage stash

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:

  1. Save all uncommitted changes (staged and unstaged) to a new stash entry
  2. Remove those changes completely from your working tree and index
  3. Record the stash entry in your repo‘s stash stack for later retrieval

Here‘s a quick visualization of this process:

git stash process diagram

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
Pro Tip: Add 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 safely
  • git 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.

Pro Tip: Use 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!

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *