git stash --keep-index 可保存暂存区状态并迁移至新分支,因 git checkout -b 或 git switch -c 不携带暂存区内容,直接切换会导致暂存丢失;--keep-index 将暂存内容存入 stash 同时保留在暂存区,切分支后通过 git stash pop 恢复,避免历史污染与冲突。

git stash 保存当前暂存区状态时,为什么不能直接用 git checkout -b 切分支?
因为 git checkout -b(或 git switch -c)默认不带工作区和暂存区变更——它只新建分支指针,但不会把 git add 后的暂存内容一起带走。如果你刚 git add file.js,再切分支,暂存区会清空,修改退回到“已修改未暂存”状态,不是你想要的“已暂存迁移”。
正确做法:先 git stash --keep-index,再切分支并恢复
这个命令专为迁移暂存区设计:--keep-index 表示“把暂存区内容存进 stash,但保留在暂存区里”,实际效果是:暂存区不变,同时生成一条包含暂存内容的 stash 记录。
- 执行
git stash --keep-index(此时暂存区仍存在,stash 中也有一份副本) - 运行
git switch -c new-feature(新分支从当前 HEAD 创建,暂存区内容完好保留) - 执行
git stash pop(把 stash 里的暂存内容合并回来——由于暂存区已有相同内容,通常无冲突,只是补上 stash 中可能包含的未暂存变更)
注意:git stash pop 后如果提示 “The stash entry is kept in case you need it later”,说明应用成功且 stash 已自动删除;若失败,可用 git stash drop 手动清理。
遇到 error: Your local changes to the following files would be overwritten by merge 怎么办?
这通常发生在你没清空暂存区就强行切分支,Git 拒绝覆盖本地修改。根本原因不是“不能切”,而是 Git 发现目标分支对应文件在工作区/暂存区有变更,且和目标提交不一致。
- 别硬用
-f强制切换——会丢弃暂存区 - 优先走
git stash --keep-index路径,它绕过冲突检测 - 如果已出错,先
git stash push -u(-u包含未跟踪文件),再切分支,最后git stash pop
为什么不用 git cherry-pick 或 git commit 后 rebase?
因为你要迁移的是“尚未提交的暂存状态”,不是已有 commit。cherry-pick 需要 commit hash,git commit 会污染原分支历史——尤其当这些修改本就不该属于当前分支时,提前提交再撤销反而增加混乱。
真正干净的做法,就是把暂存区当作一个待迁移的“变更快照”,用 stash --keep-index 锁住它,再换分支还原。过程中没有额外 commit、没有历史污染、也没有丢失暂存状态。
容易被忽略的一点:git stash --keep-index 不保存未暂存修改,只保存暂存区 + 工作区中与暂存区不冲突的部分。如果还有其他未 git add 的改动,得确认是否一并纳入 stash(加 -u 参数),否则它们会留在原分支工作区。


















