本地有改動已 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
就能順利拉取且保留所有本地改動。