This Git error prevents rebasing when you have modified files that aren't staged or committed. Git requires a clean working directory to safely apply commits during a rebase. The solution is to either stash your changes temporarily, commit them, or discard them if they're not needed.
This error occurs when you attempt to run `git rebase` while having modifications in your working directory that have not been staged (added to the index) or committed. Git is protecting you from potentially losing your local changes. During a rebase operation, Git needs to checkout different commits, apply your branch's commits on top of another branch, and potentially modify files in your working directory. If you have unstaged changes, these could be overwritten or conflict with the rebase process, leading to data loss or confusing states. Git enforces a clean working tree requirement for rebase operations to ensure that your local modifications are safely preserved and that the rebase can proceed without complications. The error message suggests two solutions: committing your changes to make them part of your Git history, or stashing them to temporarily save them aside.
First, identify what files Git is referring to:
# View status to see modified files
git status
# You'll see output like:
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: src/config.js
# modified: README.mdTo see the actual changes:
# Show diff of unstaged changes
git diff
# Show diff for a specific file
git diff src/config.jsIf you want to keep your changes but proceed with the rebase, use git stash:
# Save your changes to the stash
git stash
# Now perform the rebase
git rebase main
# After rebasing, restore your stashed changes
git stash popThe stash command saves your modifications and reverts your working directory to match HEAD. After the rebase completes, stash pop restores your changes on top of the rebased code.
Note: If your stashed changes conflict with the rebased code, you'll need to resolve those conflicts when running git stash pop.
Git 2.9+ supports the --autostash flag that automatically stashes and restores your changes:
# Rebase with automatic stashing
git rebase --autostash main
# For pull with rebase
git pull --rebase --autostashTo make this the default behavior:
# Enable autostash for all rebases
git config --global rebase.autoStash true
# Enable autostash for pull --rebase
git config --global pull.rebase true
git config --global rebase.autoStash trueWith these settings, Git will automatically stash before rebasing and pop afterward, making the process seamless.
If your changes are complete and ready to be part of your commit history:
# Stage all changes
git add .
# Or stage specific files
git add src/config.js README.md
# Commit with a message
git commit -m "Work in progress: describe your changes"
# Now rebase
git rebase mainTip: If you want to clean up this commit later, you can use interactive rebase to squash or amend it:
# After rebasing, squash the WIP commit with another
git rebase -i HEAD~2If the unstaged changes are not important and you want to throw them away:
# Discard changes in a specific file
git checkout -- src/config.js
# Discard all unstaged changes
git checkout -- .
# Or using the newer restore command (Git 2.23+)
git restore src/config.js
git restore .Warning: This permanently discards your changes. Make sure you don't need them before proceeding.
For a more aggressive reset that also removes untracked files:
# Reset to HEAD and remove all changes
git reset --hard HEAD
# Also remove untracked files (be careful!)
git clean -fdWhen using git pull --rebase, you may encounter this error frequently. Here are solutions:
# Manual approach
git stash
git pull --rebase
git stash pop
# Automatic approach
git pull --rebase --autostash
# Or configure defaults
git config --global pull.rebase true
git config --global rebase.autoStash true
# Then simply use
git pullThis is especially common when working with tools like Oh My Zsh that update via git pull --rebase.
### Understanding Git's Working Directory Protection
Git requires a clean working directory for rebase operations because:
1. Commit Checkout: Rebase needs to checkout commits from the target branch, which would overwrite your working directory
2. Conflict Resolution: If conflicts arise during rebase, having existing unstaged changes would complicate the resolution
3. Atomicity: Git wants rebase to be an atomic operation that can be cleanly aborted if needed
### Difference Between Staged and Unstaged Changes
| State | Description | Command to Check |
|-------|-------------|------------------|
| Unstaged | Modified but not added | git diff |
| Staged | Added but not committed | git diff --cached |
| Committed | Part of Git history | git log |
Both unstaged and staged changes will block a rebase. The error message specifically mentions "unstaged" because that's the most common case.
### Stash vs Commit: When to Use Which
Use `git stash` when:
- Changes are incomplete or experimental
- You want to temporarily set aside work
- You're not sure if you want to keep the changes
Use `git commit` when:
- Changes are logical units of work
- You want them in your Git history
- You plan to push them eventually
### The Autostash Feature
The --autostash option (Git 2.9+) creates a stash entry, performs the rebase, and then applies the stash. If applying the stash causes conflicts, you'll need to resolve them manually.
Git version check:
git --version### Dealing with Stash Conflicts
If git stash pop after rebase causes conflicts:
# The stash is kept if pop fails
git stash list # See the stash is still there
# Resolve conflicts in the files
# Then drop the stash manually
git stash drop### Workflow Best Practices
1. Commit early, commit often: Make small commits to avoid accumulating large unstaged changes
2. Use feature branches: Keep work isolated so rebasing is cleaner
3. Configure autostash: git config --global rebase.autoStash true
4. Check status before rebase: Always run git status before rebasing
### Partial Stashing
If you only want to stash some files:
# Interactive stash - choose which changes to stash
git stash push -p
# Stash specific files only
git stash push src/config.js
# Stash with a message for clarity
git stash push -m "Config changes for later" src/config.jswarning: BOM detected in file, this may cause issues
UTF-8 Byte Order Mark (BOM) detected in file
fatal: Server does not support --shallow-exclude
Server does not support --shallow-exclude
warning: filtering out blobs larger than limit
Git partial clone filtering large blobs warning
fatal: Server does not support --shallow-since
Server does not support --shallow-since in Git
kex_exchange_identification: Connection closed by remote host
Connection closed by remote host when connecting to Git server