# Fix Git Stash Pop Conflict Overwriting Uncommitted Changes

You have uncommitted changes in your working directory, pop a stash, and get a conflict:

bash
git stash pop
bash
Auto-merging config.py
CONFLICT (content): Merge conflict in config.py

Your 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:

bash
git status
# Both modified:      config.py

View the conflict markers:

bash
cat config.py

You will see:

bash
<<<<<<< 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:

python
DATABASE_URL = "postgresql://localhost:5432/staging"

Then mark as resolved:

bash
git add config.py

Important: 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:

bash
git stash drop
# Drops the most recent stash (stash@{0})

Or if you resolved against a specific stash entry:

bash
git stash drop stash@{3}

Verify the stash is removed:

bash
git stash list

Step 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:

bash
git stash apply stash@{0}

If there are conflicts, the stash entry is preserved. After resolving:

bash
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:

bash
git config merge.conflictstyle diff3
git stash pop

With diff3 conflict style, you see three versions:

bash
<<<<<<< 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. 1.Commit before stashing: Commit your working directory changes before popping a stash
  2. 2.Apply to a clean branch: Create a temporary branch, apply the stash there, then cherry-pick
  3. 3.Use worktrees: git worktree add ../temp-branch to apply the stash in an isolated directory
bash
# 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 branch

The 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.