KhueApps
Home/DevOps/Fix Git error: cannot pull with rebase: You have unstaged changes

Fix Git error: cannot pull with rebase: You have unstaged changes

Last updated: October 07, 2025

What this error means

Git blocks a rebase-based pull when your working tree has unstaged changes. Command that triggers it:

  • git pull --rebase

You’ll see:

  • error: cannot pull with rebase: You have unstaged changes
  • error: please commit or stash them

Git refuses to rewrite history (rebase) while your working directory isn’t clean.

Quickstart

Pick one of these depending on your intent:

  • Keep changes for later: git pull --rebase --autostash
  • Temporarily shelve changes: git stash push -u -m "wip" && git pull --rebase && git stash pop
  • Commit your changes first: git add -A && git commit -m "WIP" && git pull --rebase
  • Discard local changes: git restore --worktree . && git clean -df # destructive

To make autostash the default for rebase-based pulls:

  • git config --global rebase.autoStash true

Minimal working example (reproduce and fix)

# Set up a tiny repo with a remote and trigger the error
set -euo pipefail

# 1) Create a bare remote
rm -rf /tmp/demo-remote.git /tmp/demo-A /tmp/demo-B
mkdir -p /tmp && cd /tmp
git init --bare demo-remote.git

# 2) First clone: seed repository
git clone demo-remote.git demo-A
cd demo-A
echo "v1" > app.txt
git add app.txt && git commit -m "init"
git push origin HEAD:main

# 3) Second clone: will simulate unstaged changes
cd /tmp
git clone demo-remote.git demo-B
cd demo-B

# Make remote advance (from clone A)
cd /tmp/demo-A
echo "v2" >> app.txt
git commit -am "remote update"
git push

# Back in clone B, create an unstaged change
cd /tmp/demo-B
echo "local edit" >> app.txt
# Now try a rebase-based pull
if git pull --rebase; then echo SHOULD_HAVE_FAILED; fi
# Fix: stash, pull, restore
git stash push -u -m "wip"
git pull --rebase
git stash pop

Choose one based on your goal and environment.

  1. Keep your change, pull safely (autostash)
  • One-off: git pull --rebase --autostash
  • Permanent: git config --global rebase.autoStash true
  • Good for: routine pulls with small local edits.
  1. Stash manually
  • Commands:
    • git stash push -u -m "wip"
    • git pull --rebase
    • git stash pop
  • Good for: explicit control and conflict handling.
  1. Commit first
  • Commands:
    • git add -A && git commit -m "WIP"
    • git pull --rebase
  • Good for: preserving history in feature branches. Amend/squash later.
  1. Discard everything (destructive)
  • Commands:
    • git restore --worktree .
    • git clean -df # remove untracked files and dirs
  • Alternative nuclear option: git reset --hard && git clean -df
  • Good for: ephemeral workspaces or CI agents.

Decision guide

SituationKeep untracked files?Suggested command
You want a quick pull without thinkingYesgit pull --rebase --autostash
You need full control over stash/applyOptionalgit stash push -u; git pull --rebase; git stash pop
You’re ready to record workN/Agit add -A && git commit -m "WIP"; git pull --rebase
Throw away local editsNogit restore --worktree . && git clean -df

Notes:

  • -u in git stash includes untracked files.
  • git clean -df is destructive; review with git clean -dn first.

Numbered steps (safe, general-purpose)

  1. Inspect what’s changed:
    • git status
    • git diff # unstaged
    • git diff --staged # staged
  2. If you need to keep changes temporarily:
    • git stash push -u -m "wip"
  3. Update your branch safely:
    • git pull --rebase
  4. Restore your work:
    • git stash pop
  5. Resolve any conflicts, then continue:
    • git status; git add <resolved-files>
    • git rebase --continue

CI/CD and DevOps tips

  • Immutable workspaces: Prefer clean clones; run git reset --hard && git clean -ffd before pulls.
  • Non-interactive pulls: Use git pull --rebase --autostash to avoid failures due to transient workspace edits by build steps.
  • Submodules: Update with git submodule update --init --recursive before pulling to reduce surprises.
  • Fast, idempotent steps: Replace git pull with separate fetch + rebase for clearer logs:
    • git fetch --prune --tags
    • git rebase origin/$(git rev-parse --abbrev-ref HEAD)

Pitfalls and how to avoid them

  • Stash conflicts: git stash pop may conflict. If so, resolve and git add, then continue. If you need to keep the stash, use git stash apply instead of pop.
  • Losing untracked files: Without -u, untracked files aren’t stashed. Use git stash -u if you care about them.
  • Dirty index left behind: git rebase can stop mid-way. Check with git status. Abort with git rebase --abort if needed.
  • Mixing merge and rebase: If your repo policy uses merges, prefer git pull (merge) or set pull.rebase=false.
  • Hooks and tools: Pre-commit or formatters may create files during builds; ignore them or clean before pulls.

Performance notes

  • Large repos: git status can be slow. Use git status -uno to skip untracked checks when appropriate.
  • Shallow clones: CI can speed pulls by using --depth=50 and periodic full fetches.
  • Avoid repeated stashes: Enable rebase.autoStash to reduce extra I/O for common pulls.
  • Minimize file churn: Ignore build artifacts to keep the working tree clean and status faster.

FAQ

  • Why does Git block rebase with unstaged changes?
    • Rebase rewrites commits; local edits could be overwritten or misapplied. Git requires a clean working tree for safety.
  • Is --autostash safe?
    • Yes, it automatically stashes and reapplies your changes. Conflicts may still occur; resolve them as usual.
  • What’s the difference between staged and unstaged?
    • Unstaged: modified in working dir. Staged: added to index and ready to commit.
  • Can I just use merge instead of rebase?
    • Yes: git pull (merge) tolerates a clean or dirty tree differently in some flows, but a clean tree is still best practice.
  • How do I prevent this error?
    • Keep a clean tree, enable rebase.autoStash, or commit before pulling.

Series: Git

DevOps