Lesson 4 - Stashing Work in Progress
Welcome to Stashing Work in Progress
You’re halfway through editing SkyLog — the change isn’t finished, it doesn’t work yet, and committing it now would leave an ugly, broken snapshot in your history. Then an urgent bug report lands. You need a clean working tree right now: maybe to switch branches, pull a fix, or check something on main. But Git won’t let you walk away from a mess without dealing with it, and you’re not ready to commit. This is exactly what git stash is for. It shelves your unfinished changes, hands you a clean tree, and keeps your work safe until you ask for it back.
We’ll keep using the SkyLog repository.
By the end of this lesson, you will be able to:
- Recognize when uncommitted work is blocking you and reach for
git stash - Shelve changes with
git stashto get a clean working tree - See what you’ve shelved with
git stash list - Restore your work with
git stash pop(and know howgit stash applydiffers)
Let’s begin.
The Problem, and git stash
Imagine you’re partway through editing skylog.py. The file is modified but not committed, so git status --short flags it with M:
$ git status --short
M skylog.pyRight now you can’t cleanly switch contexts — your change is in the way and it isn’t ready to commit. Run git stash to set it aside:
$ git stash
Saved working directory and index state WIP on main: b6aab84 Initial SkyLog
$ git status --shortThe second command prints nothing — your working tree is clean. Git saved your modifications as a WIP (“work in progress”) entry and rolled skylog.py back to its last committed state. The message tells you which branch and commit the stash was made from. Your half-finished work isn’t lost; it’s just shelved, waiting for you. Now you’re free to deal with the interruption on a tidy tree.
Seeing What You’ve Shelved
Stashed changes don’t vanish into thin air — they’re recorded in a list you can inspect at any time with git stash list:
$ git stash list
stash@{0}: WIP on main: b6aab84 Initial SkyLogEach line is one stash entry. The label stash@{0} is its reference; 0 is the most recent stash. The rest of the line repeats the branch and commit it came from, so you can tell entries apart when you have more than one.
Restoring Your Work: git stash pop vs git stash apply
With the urgent fix done and committed as a normal commit, it’s time to pick your unfinished work back up. git stash pop restores the most recent stash and removes it from the list:
$ git stash pop
On branch 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: skylog.py
no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (b1b8f11adbe3ac4ced67bad57fc53c3019af5688)
$ git status --short
M skylog.pyYour modification to skylog.py is back, exactly as you left it, and the Dropped refs/stash@{0} line confirms Git removed that entry after re-applying it. Check the list and it’s empty:
$ git stash list(no output)
The close cousin git stash apply does the same restore but keeps the stash in the list, which is handy if you want to apply the same shelved work to more than one branch.
pop drops it; apply keeps it
git stash pop re-applies your changes and deletes the stash entry — great for the common “shelve, handle the interruption, resume” flow. Use git stash apply instead when you want the entry to stay around. And remember that stashing is meant for short-term shelving while you switch contexts. For work you’ll keep coming back to over days, create a branch and commit to it instead — a stash is easy to forget.
The Stash Is a Stack
You can stash more than once, and Git treats your stashes as a stack. Each new git stash pushes a fresh entry onto the top as stash@{0}, bumping the older ones down (stash@{1}, stash@{2}, and so on). git stash pop always takes the most recent one off the top first, so the order is last-in, first-out. If you need a specific older entry, you can name it — for example git stash pop stash@{1}. In day-to-day work, though, you’ll usually have just one stash at a time: shelve a change, deal with the interruption, and pop it straight back.
Practice Exercises
Exercise 1: From messy to clean
You have an unfinished edit to skylog.py and a teammate asks you to quickly check something on main. You run git stash. What happens to skylog.py, and what does git status --short show afterward?
Hint
git stash shelves the change and rolls skylog.py back to its last committed state, leaving a clean working tree. So git status --short prints nothing — there are no modified files to report.
Exercise 2: Where did my change go?
After stashing, you panic that your work is gone. Which command proves it’s safe, and what does the output look like?
Hint
Run git stash list. It shows your shelved entries, e.g. stash@{0}: WIP on main: .... The entry confirms your changes are stored and tells you which branch and commit they came from.
Exercise 3: pop or apply?
You shelved a change and now want to bring it back. You only need it on the current branch and don’t want a leftover entry cluttering the list. Which command do you use, and how can you tell it worked?
Hint
Use git stash pop — it re-applies the change and removes the stash entry. You can tell it worked from the Dropped refs/stash@{0} (...) line in its output, and git stash list will then print nothing. (Use git stash apply only if you wanted to keep the entry.)
Summary
git stash shelves your uncommitted changes and restores a clean working tree, so you can switch branches or handle an urgent fix without committing half-finished work. git stash list shows your shelved entries (each labeled stash@{0}, stash@{1}, …), and git stash pop brings the most recent one back and removes it from the list — confirmed by the Dropped refs/stash@{0} line. Use git stash apply when you’d rather keep the entry. Stashes behave like a stack (last-in, first-out), so you can shelve more than once, though most of the time you’ll have just one entry: stash, interrupt, pop.
Key Concepts
git stash— shelves uncommitted changes and restores a clean working tree.- WIP entry — the saved “work in progress” snapshot, tied to its branch and commit.
git stash list— shows stashed entries;stash@{0}is the most recent.git stash pop— re-applies the latest stash and removes it from the list.git stash apply— re-applies the latest stash but keeps it in the list.- Stack — stashes are last-in, first-out; you can stash multiple times.
Why This Matters
Interruptions are the norm in real work — an urgent bug, a quick review, a teammate’s request — and they almost always arrive mid-change. Without stashing, your only options are to commit something broken or lose your progress. git stash gives you a third, better path: park the work safely, get a clean tree to do whatever’s urgent, and resume exactly where you left off. It’s a small command that smooths over one of the most common friction points in everyday Git.
Next Steps
Continue to Lesson 5 - Guided Project: Two Features, One Conflict
Put branching, merging, conflict resolution, and stashing together in a hands-on project.
Back to Module Overview
Return to the Branching and Merging module overview
Continue Building Your Skills
You can now shelve unfinished work, switch contexts on a clean tree, and bring your changes back with a single command. Next, you’ll combine everything from this module — branching, merging, resolving a conflict, and stashing — in a guided project that mirrors a real day of development.