# Fix Git Stash Pop Conflict Overwriting Uncommitted Changes
You have uncommitted changes in your working directory, pop a stash, and get a conflict:
git stash popAuto-merging config.py
CONFLICT (content): Merge conflict in config.pyYour working directory now contains a mixture of your original changes and the stashed changes, with conflict markers in the affected files. The stash entry is NOT removed from the stash list (Git preserves it when conflicts occur).
Understanding Stash Pop Conflicts
git stash pop is essentially a merge operation: it merges the stashed changes into your current working directory. If both your working directory and the stash modified the same lines of the same files, Git cannot auto-merge and creates conflict markers.
Unlike a regular merge conflict, the "other side" of the conflict is your stash, not another branch.
Step 1: View the Conflict
Check which files have conflicts:
git status
# Both modified: config.pyView the conflict markers:
cat config.pyYou will see:
<<<<<<< Updated upstream
DATABASE_URL = "postgresql://localhost:5432/prod"
=======
DATABASE_URL = "postgresql://localhost:5432/dev"
>>>>>>> Stashed changes"Updated upstream" is your working directory changes. "Stashed changes" is the stashed content.
Step 2: Resolve the Conflict
Edit the file to resolve the conflict, keeping the correct version:
DATABASE_URL = "postgresql://localhost:5432/staging"Then mark as resolved:
git add config.pyImportant: Do NOT run git commit. Stash pop is not a merge commit -- you are just resolving the conflict in your working directory.
Step 3: Drop the Stash Entry
After resolving, the stash entry is still in the list. Remove it:
git stash drop
# Drops the most recent stash (stash@{0})Or if you resolved against a specific stash entry:
git stash drop stash@{3}Verify the stash is removed:
git stash listStep 4: Abort and Restore Original State
If you want to abort the stash pop and restore your original working directory:
```bash # First, undo the stash pop merge git checkout --theirs . # Accept stashed version git checkout --ours . # OR accept working directory version
# Or reset everything git checkout HEAD -- . git clean -fd ```
The stash entry is still in the stash list (since pop only drops on success). You can try again later with a clean working directory.
Step 5: Apply Instead of Pop
To avoid accidental stash loss during conflicts, use apply instead of pop:
git stash apply stash@{0}If there are conflicts, the stash entry is preserved. After resolving:
git stash drop stash@{0}This two-step approach is safer because the stash is not automatically removed.
Step 6: Preview Stash Before Popping
Always preview what the stash contains before popping:
```bash # List all stashes git stash list
# Show the diff of a specific stash git stash show -p stash@{0}
# Show only file names git stash show stash@{0} ```
This helps you identify potential conflicts before they happen. If the stash modifies the same files as your working directory, resolve your working directory changes first (commit or stash them), then pop.
Step 7: Three-Way Stash Pop
For better conflict resolution, use the three-way merge strategy:
git config merge.conflictstyle diff3
git stash popWith diff3 conflict style, you see three versions:
<<<<<<< Updated upstream
DATABASE_URL = "postgresql://localhost:5432/dev"
||||||| constructed merge base
DATABASE_URL = "postgresql://localhost:5432/local"
=======
DATABASE_URL = "postgresql://localhost:5432/prod"
>>>>>>> Stashed changes- "Updated upstream" = current working directory
- "constructed merge base" = the common ancestor
- "Stashed changes" = the stash
This makes it much easier to understand what changed on each side and make the correct resolution.
Preventing Stash Conflicts
- 1.Commit before stashing: Commit your working directory changes before popping a stash
- 2.Apply to a clean branch: Create a temporary branch, apply the stash there, then cherry-pick
- 3.Use worktrees:
git worktree add ../temp-branchto apply the stash in an isolated directory
# Safe stash application workflow
git stash list
git stash show -p stash@{0} # Preview
git stash branch temp-branch stash@{0} # Creates and checks out a new branch
# Resolve any conflicts on the temp branch
# Then merge or cherry-pick into your main branchThe git stash branch command creates a new branch from the commit where the stash was created, then applies the stash. This is the safest way to apply stashes with potential conflicts.