本地有改动已 git add
到暂存区(stage),但是还没 commit,同时远端有 28 个新提交需要拉取。
直接 git pull
会冲突或被拒绝,因为你本地有 staged 修改。
处理步骤有几种方案,我给你推荐最稳妥的几种:
✅ 方法 1:用 git stash --staged
把暂存的改动保存起来 → 拉取远端 → 再恢复改动
# 把已暂存的改动存到 stash
git stash push --staged -m "my staged changes"# 拉取远端更新
git pull# 恢复暂存的改动
git stash pop
这样你就能在保持本地修改的同时,顺利更新远端代码。
✅ 方法 2:临时取消暂存(不动文件)
# 取消暂存,但文件改动还在工作区
git reset# 拉取最新
git pull# 再次把之前改动加回暂存区
git add .
这种方式适合你只是想本地改动保持原样,但不想现在提交。
✅ 方法 3:临时建一个 commit,再回滚
# 临时提交
git commit -m "temp commit"# 拉取远端
git pull# 把临时 commit 撤销回暂存状态
git reset HEAD~
这样能保证不丢改动,但比 stash 稍微麻烦。
⚠️ 推荐你用 方法 1(stash --staged),既不会丢改动,也不会搞乱历史。
git reset 操作
git reset
要看你后面跟的参数:
-
git reset
(不带参数,默认--mixed
)
👉 只是把 暂存区 清空(unstage),文件里的修改依旧保留在 工作区。- 已经改过的文件内容不会丢。
- 只是从 staged → unstaged。
举个例子:
# 文件改了并 add git add myfile.java# 此时 git status 显示在 staged 区 git reset# 现在变回 unstaged,但 myfile.java 的修改还在
-
git reset --hard
👉 这是危险的,会丢掉工作区和暂存区的修改,直接回滚到某个 commit。
(所以不要乱用--hard
) -
git reset --soft
👉 回退 commit,但保留暂存区和工作区。
所以如果你用的是:
git reset
它 只会取消暂存,不会动你已经改过的代码,等你 git pull
完成后再 git add .
就能恢复原状。
pull 时用 rebase(pull.rebase=true),而 rebase 不允许工作区有未暂存的改动
git pull
error: cannot pull with rebase: You have unstaged changes.
error: Please commit or stash them.
’
解决办法
这里 git pull
被拒绝,是因为配置是 pull 时用 rebase(pull.rebase=true
),而 rebase 不允许工作区有未暂存的改动。所以即使你 git reset
把改动从暂存区移出来了,依然会被拦下。
最省心的两种做法(任选其一):
方法 A:一条命令自动处理(推荐)
git pull --rebase --autostash
含义:先自动 stash 你的本地改动 → 拉取并 rebase → 再自动把改动套回来。
(如果你觉得好用,可以永久打开:
git config --global pull.rebase true
git config --global rebase.autostash true
)
方法 B:手动 stash 再恢复
# 1) 把当前所有改动(含未跟踪文件)先存起来
git stash push -u -m "wip before pull"# 2) 拉取最新
git pull --rebase# 3) 把改动取回来
git stash pop
如果
stash pop
时有冲突:按文件解决冲突 →git add <file>
→ 若出现 rebase 流程提示就git rebase --continue
(或直接完成后再继续你的开发流程)。
小结:
git reset
本身不会丢修改,但由于你的pull
走 rebase,工作区必须干净。- 用
--autostash
或手动stash push/pop
就能顺利拉取且保留所有本地改动。