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
Recommended workflows
Choose one based on your goal and environment.
- 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.
- Stash manually
- Commands:
- git stash push -u -m "wip"
- git pull --rebase
- git stash pop
- Good for: explicit control and conflict handling.
- Commit first
- Commands:
- git add -A && git commit -m "WIP"
- git pull --rebase
- Good for: preserving history in feature branches. Amend/squash later.
- 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
| Situation | Keep untracked files? | Suggested command |
|---|---|---|
| You want a quick pull without thinking | Yes | git pull --rebase --autostash |
| You need full control over stash/apply | Optional | git stash push -u; git pull --rebase; git stash pop |
| You’re ready to record work | N/A | git add -A && git commit -m "WIP"; git pull --rebase |
| Throw away local edits | No | git 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)
- Inspect what’s changed:
- git status
- git diff # unstaged
- git diff --staged # staged
- If you need to keep changes temporarily:
- git stash push -u -m "wip"
- Update your branch safely:
- git pull --rebase
- Restore your work:
- git stash pop
- 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.