One of the biggest promises of AI is helping developers work on multiple tasks at once. Whether you are debugging a mobile app, reviewing a pull request, writing documentation, or experimenting with a new feature, AI can reduce the mental overhead of context switching. But long before AI became part of our daily workflow, developers relied on a much older multitasking technique: Git stash. Imagine you are halfway through a feature when an urgent bug report arrives. You need to switch branches immediately, but your current work is not ready to commit — half the functions are stubs, the tests are failing, and committing it would pollute your history. Traditionally the solution was to shelve your work with Git stash, deal with the fire, and come back later. This article walks through Git stash from the basics to the advanced recovery tricks most developers never learn, then looks at how AI changes the multitasking equation.
Why This Matters Beyond the Code
An interruption is expensive because of what happens in the developer's head. Picking up a complex task means holding a lot of context at once: what you were building, why, what you had already tried, and what comes next. An urgent interruption wipes that mental picture, and rebuilding it can take fifteen or twenty minutes after the interruption itself is over. Multiply that by a few interruptions a day across a whole team and it turns into a real drag on how fast the company ships. So the tools and habits in this article are ultimately about protecting focus, which is what actually moves work out the door.
Stashing and Worktrees, in Plain English
Git stash and git worktree both solve the same basic problem: not losing your place when you have to stop what you are doing. Think of a developer's workspace like a desk. Stashing is sweeping your half-finished paperwork into a drawer so you can clear the desk for something urgent, then pulling those same papers back out later, exactly as you left them. A worktree is different — instead of clearing the desk, you set up a second desk in another room and work on two things at once without packing anything away. The rest of this article is really just two ideas dressed up as commands: stash to pause one task, and worktree to run two side by side.
What Is a Git Stash?
A Git stash is a temporary storage area where you can safely shelve uncommitted changes without making a formal commit. Running "git stash" takes the modified, tracked files in your working directory, saves them onto a local stack-like structure, and reverts your workspace back to its last clean commit state. That lets you switch tasks, change branches, investigate a bug, or pull updates without losing current work, and restore those changes exactly where you left off later. Think of it as a developer's pause button. It also helps to understand what is happening under the hood: a stash is just a commit, or a few. When you stash, Git creates commit objects recording the state of your working directory and index, then points the refs/stash reference at them. The stash list is effectively a stack of these hidden commits. This matters for two reasons. Because stashes are real commits they can be inspected, diffed, and even recovered after deletion. And because they live in refs/stash rather than on any branch, they never show up in your normal history and are never pushed to a remote. You can prove it to yourself by running "git stash" and then "git log -g refs/stash", which shows the stash reflog with each stash as a commit. One note on syntax: older tutorials use "git stash save" with a message. That form is now obsolete. The modern, recommended command is "git stash push", which is more flexible — it accepts pathspecs, patch mode, and more. Every example below uses push. From here on this gets more hands-on: the actual commands you will use day to day.
Creating Stashes
The basic stash is just "git stash", which stashes tracked, modified files and resets your working tree to the last commit. By default Git only stashes tracked files, so brand-new files it has never seen are left behind — a surprisingly common trap. To include them, use "git stash -u", or the long form "git stash --include-untracked". If you also need files matched by .gitignore, such as build artefacts or local config, use "git stash -a" or "git stash --all", but use it sparingly because it can sweep up a large node_modules or dist folder. When you are juggling several tasks, unnamed stashes become a guessing game, so always add a description: "git stash push -m 'refactor pipeline config handling'" means stash@{0} will still tell you what it contains a week from now. You do not have to stash everything either — pass a pathspec to stash only the files you name, as in "git stash push -m 'wip on auth service' -- src/auth/ tests/auth.test.js", and everything else stays in your working directory. That is invaluable when one file is ready to keep working on and another is in a broken state you would rather set aside. Sometimes a single file contains two unrelated changes and you only want to stash one; patch mode walks you through each hunk and asks, via "git stash push -p -m 'experimental logging only'", prompting with options like y to stash the hunk, n to keep it, s to split it into smaller hunks, and q to quit. That gives you surgical control over what gets shelved. There is also a common workflow where you have staged exactly what you want to commit and want to run tests against only that staged state: "git add ." then "git stash --keep-index", run your tests, then "git stash pop" to restore the rest. And since Git 2.35 you can invert that and stash only the staged changes with "git stash push --staged -m 'the part that is ready to set aside'", leaving unstaged work untouched.
Inspecting Stashes
Run "git stash list" to see what you have. Typical output looks like "stash@{0}: On main: refactor pipeline config handling" and "stash@{1}: On feature/login: fix oauth callback" — the number in braces is the stash's position on the stack, and stash@{0} is always the most recent. Before applying a stash it is worth reviewing what is in it so you do not restore the wrong set of changes. "git stash show stash@{0}" gives you a summary of changed files, and "git stash show -p stash@{0}" gives you the full diff. If you stashed untracked files and want them included in that diff, Git 2.32 and later supports "git stash show -p --include-untracked stash@{0}".
Restoring Your Work
When you are ready to pick up where you left off, "git stash pop" applies the most recent stash to your current branch and removes it from the stack. If you might want to reuse the same stash — applying the same work-in-progress to two different branches, for instance — use "git stash apply stash@{1}" instead, which leaves the stash in place. If the branch has moved on since you stashed, pop or apply may produce merge conflicts, and two things are worth knowing. First, on conflict git stash pop does not drop the stash; your safety net stays in the list until you have resolved everything and confirmed the result. Second, you resolve these conflicts exactly like a merge — edit the conflicted files, git add them, and then clean up manually, because pop did not drop the stash. In practice that looks like "git stash pop", resolving the conflicts in your editor, "git add resolved-file.js", and then "git stash drop" to remove the stash you just finished applying by hand.
Cleaning Up
Once a stash is no longer needed, remove it. "git stash drop" deletes the most recent stash, "git stash drop stash@{2}" deletes a specific one, and "git stash clear" deletes all of them. A clean stash list makes future multitasking far less confusing. Just be careful with clear — it is irreversible through normal commands, though the recovery section below is a genuine escape hatch.
Converting a Stash into a Branch
One of the most underrated Git features is turning a stash into its own branch: "git stash branch pipeline-fix stash@{1}". Git creates a new branch from the commit where the stash was originally created, applies the stash onto it, and drops the stash if the operation succeeds. This is perfect for two situations — when a quick interruption grows into a real project that deserves its own branch, and when a stash will not apply cleanly to the branch you are currently on.
Recovering a "Lost" Stash
This is the trick that turns Git stash from useful into trustworthy. Because stashes are commits, dropping or clearing one does not immediately erase it; the commit becomes unreachable but lingers until Git's garbage collection runs, which is typically not for weeks. If you dropped a stash by mistake, find the dangling commit with "git fsck --no-reflog | awk '/dangling commit/ {print $3}'", inspect each candidate with "git show" and the commit SHA to find your work, and then restore it as if it were still a stash using "git stash apply" with that SHA. Knowing this exists means you can use drop and clear without anxiety.
When Stash Isn't the Right Tool: Git Worktrees
Stash is great for brief interruptions. But if you frequently need to work on two branches at the same time — building a feature while a long review cycle drags on, say — constantly stashing and popping gets tedious and error-prone. Git worktrees solve this differently. Instead of shelving your work, they give you a second working directory checked out to a different branch, both backed by the same repository: "git worktree add ../project-hotfix hotfix/login-bug". You now have two folders side by side. Your feature work stays untouched in your main directory and the hotfix lives in ../project-hotfix. Open both in separate editor windows and switch by changing windows rather than by stashing. Manage them with "git worktree list" and "git worktree remove ../project-hotfix". The rule of thumb: use stash for a quick pause-and-come-right-back interruption, and use worktrees when two contexts need to stay alive in parallel for a while.
Why This Isn't Just a Developer Problem
The reason any of this matters has nothing to do with Git syntax. It is about how much time and focus get burned every time someone gets pulled off one task and dropped onto another. That cost shows up outside the terminal too — a project manager re-explaining a feature's status after an interruption, a client noticing a task took three days instead of one, a handoff that goes sideways because the next person cannot tell what was finished from what was just a placeholder. It is the same problem Git stash solves for code, just further up the chain: protect the train of thought, and the team loses less time to interruptions.
Real-World Use Cases
A few scenarios where reaching for stash, or a worktree, pays off. The urgent hotfix: you are mid-feature when production breaks, so "git stash -u", switch to main, branch off, fix, ship, then "git stash pop" back into your feature — no throwaway WIP commit polluting history. Pulling with a dirty tree: you want the latest from origin/main but git pull refuses because of local changes, so stash, "git pull --rebase", pop. Does this bug exist without my changes: you suspect your work-in-progress introduced a bug, so stash it to get a clean baseline, try to reproduce, then pop your changes back — a fast way to isolate cause from coincidence. Started on the wrong branch: you began editing on main instead of a feature branch, so "git stash", "git switch -c feature/correct-branch", "git stash pop". Reviewing a colleague's PR: to run someone's branch locally without losing your work, stash, check out their branch, test it, then return and pop. And splitting tangled work: you have accidentally bundled two features in one working tree, so use patch-mode stashing to peel off one feature at a time and commit them separately.
How AI Changes the Game
Git stash preserves code. What it cannot preserve is the thing that actually costs you time after an interruption: the mental state of why you were making a change, what you had already tried, and what you intended to do next. You come back to a clean diff and spend twenty minutes remembering what to do. Those minutes add up fast across a team. When context survives an interruption, people spend less time decoding half-finished work and more time shipping; it becomes easier to run several workstreams at once without anyone losing their mental model, and the intent behind a change stays attached to it rather than living only in the diff. Multiply that across a team and preserving context stops being personal housekeeping and becomes a real lever on delivery speed. This is where AI assistants add a genuinely new layer, because they can preserve and reconstruct context rather than just changes. Summarise unfinished work before you stash by asking the assistant to read your diff and write a few sentences on what the change does and what is left. Generate the stash message itself from the actual diff instead of writing "stuff". Reconstruct context when you return days later by feeding the diff back and asking what you were doing and what the obvious next step is. Explain prior decisions when picking up old work, including flagging anything half-finished or risky. Review before you commit with a quick AI pass over the staged diff to catch leftover debug logging, missing error handling, or an unresolved TODO. And produce documentation in parallel, letting the assistant draft the docstring, README section, or changelog entry while you keep coding. A practical combined workflow: review the diff or pass it to your assistant, then "git stash push -u -m 'auth refactor: token validation done, refresh flow TODO'", handle the interruption, and on returning run "git stash show -p stash@{0}", ask the assistant to summarise it and suggest the next step, then "git stash pop". Git stash remains an essential multitasking tool and worktrees extend it for parallel work; AI does not replace either, it complements them by preserving the reasoning behind the code so returning to a task is about continuing rather than remembering. The result is less time spent reconstructing where you left off and more time spent building.
Key Takeaways
Stash lets you pause unfinished work and pick it back up exactly where you left it, without committing broken code. Worktrees are for running two branches side by side over time, not just pausing one task briefly. Neither one keeps the reasoning behind the work — why you made a call, what is still left to do — and that is the gap AI now fills. And a cleaner Git history is nice, but the real win is less time lost to interruptions and to handoffs that hold everything up.
What Multitasking Is Really About
Multitasking has always been part of building software; the only question is what you lose each time you switch. Git gave us a way to protect the code — stash it, branch it, come back to it clean. That solved half the problem. The other half was the reasoning: the half-formed plan and the reason you chose one approach over another. That used to live only in your head, and it evaporated the moment something urgent pulled you away. For a team building a product, that shift is bigger than any single command. When both the code and the thinking behind it are preserved, switching tasks stops being a tax. Work moves in parallel without piling up half-finished; people hand off to each other without losing the thread; and the team spends its energy on the product instead of on remembering where it was. That is the standard we hold ourselves to on every BitIngenuity engagement — context is owned, handoffs are clean, and focus stays on shipping. The tools change, but the goal stays the same: protect focus, lose less to the switch, and keep building.
Conclusion
Git stash is the pause button, worktrees are the second desk, and AI is the thing that finally remembers why you were doing any of it. Learn the handful of commands above — patch-mode stashing, --keep-index, stash branch, and dangling-commit recovery — and interruptions stop costing you a clean history or a lost afternoon. Layer an AI assistant on top to capture intent alongside the diff, and the twenty minutes you normally spend rebuilding context largely disappears. If you want an engineering partner that treats context and clean handoffs as part of the deliverable rather than an afterthought, that is how BitIngenuity runs every build.


