A ‘Cry-Laugh’ Situation: Deep in Code, Boss Calls Urgently!
Two in the morning, the server screen blares red with errors, and Slack messages from the boss are incessantly ringing. My heart pounds. I’m developing a new feature on branch feature/abc, the code is messy, incomplete, and not ready to commit. But production errors don’t wait. How can I quickly “clean up” this unfinished code, switch back to the main branch to fix the bug, without losing all the work I’ve just done?
If you’ve ever found yourself in this situation, or faced similar scenarios like:
- Needing to pull new code from
main, but your current branch has uncommitted changes. - Wanting to switch to another branch to check something, then return to your work.
- Experimenting with a new idea and not wanting to commit those experimental changes immediately.
This is exactly when you need a solution to effectively manage those unfinished changes. Your working directory is “dirty” with modified or newly added (staged) files, and you need a way to temporarily “put them aside.”
Comparing Immediate “Firefighting” Methods
Before we get to the most effective solution, let’s look at some immediate workarounds that many fellow developers often use. You’re sure to find some situations that will make you laugh:
Approach 1: A Hasty Commit (WIP commit)
Method: Quickly git add . then git commit -m "WIP: XXXXX" to get it over with. Consider the work saved, then switch to main to fix the bug.
Pros:
- Extremely fast, no time spent thinking.
- Your code is saved in Git history, no worries about losing it.
Cons:
- Clutters commit history: You’ve just added a meaningless, incomplete commit to your branch. Later, you’ll have to use
git rebase -ito clean it up, which can easily cause confusion if you’re not familiar with it. - Difficult to manage: If you have many WIP commits like this, tracking which commit belongs to which feature and its progress becomes very messy.
- Risks during merge/rebase: These unfinished commits can cause unnecessary conflicts when you merge or rebase the branch later.
Approach 2: Create a New Branch to Keep Code
Method: Create a new branch (e.g., git branch fix-prod-issue), then commit your current changes to that branch. After finishing up on main, you return to this branch to continue working.
Pros:
- Clean history: Your
feature/abcbranch isn’t cluttered with incomplete commits. - Safe: Your code is securely stored in a separate branch.
Cons:
- A bit cumbersome: For just “temporarily saving” work for a few minutes or hours, creating a new branch and then having to merge or rebase it later seems a bit overkill.
- Managing many branches: If you frequently use this method, you’ll end up with many temporary branches that will need cleaning up later.
Approach 3: Copy-Pasting Code Elsewhere (OH MY GOD!)
Method: Open File Explorer/Finder, copy the entire project folder or modified files to a temporary directory on your desktop or another drive. Then use git reset --hard to revert to a clean state.
Pros:
- Extremely quick if you only have a few files to deal with.
- No need to remember complex Git commands.
Cons:
- Extremely high risk of losing code: You’re gambling with fate! Forgot to copy a file? Formatted the drive? Deleted by mistake? Disaster!
- No version control: This isn’t Git! All changes are fragmented copies; you can’t track or restore versions.
- Disaster for large projects: Copying a multi-GB project (e.g., a frontend project with a huge
node_modulesdirectory) is agony, not to mention that copying it back into the old project later can easily lead to accidental overwrites or missing files.
I once lost critical code due to accidentally force pushing to the wrong branch. Since then, I’ve always been careful with git push --force. That experience taught me the importance of keeping a clean codebase and having a safe contingency plan for unfinished work, like git stash. This tool helps me avoid rushing to commit incomplete work, minimizing unnecessary risks.
Approach 4: Git stash – The Tool You Need
This is precisely the feature Git provides to solve this problem: temporarily saving unfinished work, cleaning your workspace, and helping you easily switch contexts without needing to commit.
Analyzing the Pros and Cons of Git Stash
Pros of Git stash
- Keeps your workspace clean: Immediately “puts aside” uncommitted changes, reverting the branch to the state of the nearest HEAD commit.
- Easy context switching: You can quickly switch to another branch, pull new code, or fix bugs without worrying about affecting your unfinished work.
- Doesn’t clutter commit history: Changes are saved in a separate Git “drawer,” not appearing in the branch’s commit history.
- Manages multiple stashes: Git allows you to save multiple different “drawers” (stashes), each representing a saved work session.
- Saves untracked files (with option): By default, Git stash only saves tracked files, but you can instruct it to also save newly created files that haven’t been
git added.
Cons of Git stash
- Easy to forget stashes: If you don’t name your stashes or don’t check them regularly, it’s very easy to forget what you’ve stashed and where.
- Conflicts can occur: When you re-apply a stash (
stash applyorstash pop) to a branch that has different changes compared to when the stash was created, merge conflicts can occur. - Not applicable across different repos: Stashes only exist locally in your current repository. You cannot push a stash to a remote or transfer it to another repo.
Choosing the Right Method: When to Use Git stash?
From the above analysis, we see that git stash is an ideal solution for situations where you need to temporarily suspend work without committing. You should use git stash when:
- Need to pull/merge new code: Your current branch has uncommitted changes, and you need to pull new code from
main.git pullwill report an error if there are uncommitted changes. - Need to switch to another branch for urgent work: Like the situation of fixing a production bug at 2 AM mentioned at the beginning of the article.
- Want to run tests on original code: You’re experimenting with a new feature and want to check if old tests still pass on a clean code version.
- Experimenting with an idea: You want to try a small change but are unsure and don’t want to commit it immediately. Stash it, try it, and if it doesn’t work out, drop the stash.
In summary, if you need a clean workspace without losing your unfinished efforts, git stash is the right choice.
Git stash Implementation Guide from A to Z
Now, let’s practice git stash commands to master this useful tool.
git stash save "message" or git stash: Save Work
This is the most basic command to store your current changes in the working directory and staging area into a stash. You should include a message for easy recall later.
# Save all modified and staged files
# Should include a message for easy recall
git stash save "Working on feature XYZ, need to fix urgent prod bug"
# Shorter version, no message
# Git will automatically generate a message based on the HEAD commit
git stash
After running this command, your working directory will be clean, just like when you first cloned the project or checked out a commit. Your changes have been packaged and stored by Git in a drawer.
git stash list: View Stash List
To check what you’ve stashed, this command will display a list of all saved stashes. Each stash will have an index like stash@{n}, where n is the sequence number (the most recent stash is 0).
git stash list
# The result might look like this:
# stash@{0}: On feature/abc: Working on feature XYZ, need to fix urgent prod bug
# stash@{1}: On main: Hotfix: try out new logic for auth
git stash apply [stash@{n}]: Re-apply Stash, Keep in List
This command will take the changes from the stash and apply them to your current working directory. The stash will remain in the stash list.
# Apply the most recent stash (stash@{0})
git stash apply
# Apply a specific stash (e.g., stash@{1})
git stash apply stash@{1}
Use apply when you want to try applying a stash but still want to keep it in the list in case you need to reuse it or apply it to another branch.
git stash pop [stash@{n}]: Re-apply Stash and Remove from List
Similar to apply, but pop will remove the stash from the list immediately after successful application. This is the most common usage when you are sure you no longer need that stash.
# Apply and drop the most recent stash
git stash pop
# Apply and drop a specific stash
git stash pop stash@{1}
If conflicts occur during pop, Git will not remove the stash from the list. You must resolve the conflicts first, then you can manually git stash drop.
git stash drop [stash@{n}]: Delete a Specific Stash
If you decide you no longer need a particular stash, use this command to remove it from the list.
# Delete the most recent stash
git stash drop
# Delete a specific stash
git stash drop stash@{1}
git stash clear: Clear All Stashes
Be careful when using this command! It will delete all your stashes without confirmation.
git stash clear
Only use when you are certain that you no longer need any stashes.
git stash show [stash@{n}]: View Stash Content
If you forget what’s inside a stash, the show command will display the difference (diff) of that stash compared to the original commit.
# View the content of the most recent stash
git stash show
# View detailed content (full diff) of the most recent stash
git stash show -p
# View the content of a specific stash
git stash show stash@{1}
git stash branch <branchname> [stash@{n}]: Create a New Branch from Stash
This command is extremely useful. If you’ve stashed a set of changes and want to develop them into an independent branch, this command will create a new branch, apply the stash to it, and then remove the stash from the list.
# Create branch "new-feature-from-stash" from the most recent stash
git stash branch new-feature-from-stash
# Create branch "hotfix-from-old-stash" from stash@{1}
git stash branch hotfix-from-old-stash stash@{1}
Important Considerations When Using Git Stash
- Resolving conflicts: When using
git stash applyorgit stash pop, if Git cannot automatically merge the changes, you will encounter conflicts. Resolve conflicts as you would during a normal merge/rebase, thengit add .andgit committo complete. - Untracked files: By default,
git stashonly saves tracked files that have been modified or are in the staging area. It does not stash newly created files that haven’t beengit added. To stash untracked files as well, you can usegit stash -uorgit stash --include-untracked. To stash both untracked and ignored files (e.g.,.env,node_modules), usegit stash -aorgit stash --all. - Regularly manage your stash list: Avoid letting your stash list become too long and difficult to manage. Delete stashes that are no longer needed using
git stash drop. - Stash is local only: Don’t forget that stashes only exist on your local machine and are not pushed to the remote repository. Therefore, it’s not a long-term backup solution.
Git stash is more than just a command; it’s a tool that helps you maintain a tidy development environment and always be ready to respond to urgent situations. Personally, I feel much more confident working on projects that demand speed and flexibility. Don’t let unfinished changes slow you down when the system is in trouble. Master git stash!

