报错场景
git pull --rebase
输出:
error: cannot pull with rebase: You have unstaged changes.
error: please commit or stash them.
这是 Git 在执行 rebase 前的保护机制:工作区有未提交修改时,rebase 可能覆盖这些改动,所以拒绝继续。
先确认修改范围:
git status
方案一:暂存后拉取再恢复(最常用)
保留改动,暂时藏起来:
git stash
git pull --rebase
git stash pop
stash pop 会把改动重新应用到工作区。如果有冲突,手动解决后 git stash drop 清掉暂存记录。
查看所有 stash:
git stash list
# stash@{0}: WIP on main: abc1234 last commit message
恢复指定 stash(保留记录):
git stash apply stash@{0}
方案二:提交后再 rebase
如果改动已经完整,直接提交:
git add .
git commit -m "WIP: 临时提交"
git pull --rebase
rebase 会把这次提交放在远端最新提交之后,之后可以 git commit --amend 修改提交信息或 git rebase -i HEAD~2 整理提交记录。
方案三:丢弃本地修改
如果这些修改确定不要了:
git reset --hard HEAD
git pull --rebase
如果还有未跟踪的文件也想清掉:
git clean -fd
reset --hard和clean -fd都是不可逆操作,请确认后执行。
方案四:开启自动 stash(推荐长期配置)
新版 Git 支持 --autostash 标志,在 rebase 前自动暂存、完成后自动恢复:
git pull --rebase --autostash
一次性使用;也可以永久开启:
git config --global rebase.autoStash true
开启后 git pull --rebase 自动执行以下流程:
stash → pull --rebase → stash pop
场景速查
| 情况 | 推荐方案 |
|---|---|
| 改动要保留,不想提交 | stash → pull → stash pop |
| 改动完整,可以提交 | commit → pull --rebase |
| 改动不需要了 | reset --hard → pull |
| 日常频繁拉取 | rebase.autoStash = true |
常见追问
stash pop 有冲突怎么办?
手动解决冲突后:
git add <冲突文件>
git stash drop # 清掉 stash 记录
为什么不直接 git pull 而是 --rebase?
git pull 默认是 fetch + merge,会产生 merge commit;--rebase 把本地提交移到远端之后,保持线性历史,更干净。
git stash 会暂存未跟踪文件吗?
默认不会。加 -u 参数:
git stash -u # 包含 untracked files
git stash -a # 包含 untracked + ignored files