由于有写了一半但是又得有同时修另外一个分支代码的需求,所以就得用stash了
当你执行 git stash 时,Git 会做两件事:
- 保存:将你当前工作区(Working Directory)和暂存区(Staging Area)中所有已跟踪文件的修改保存到一个栈(Stack)中。
- 还原:将你的工作目录还原到上一次提交(
HEAD)时的干净状态。
此时,你的工作区是干净的,你可以随意切换分支。
2. 基础命令详解
2.1 暂存修改 (Stash)
最简单的用法,保存当前所有修改(不包含未跟踪的新文件):
git stash # 或者 git stash push2.2 查看暂存列表 (List)
你可以多次执行 stash,它们会像“栈”一样堆叠起来。查看所有保存的记录:
git stash list输出示例:
stash@{0}: WIP on master: 049d078 added the index file
stash@{1}: WIP on master: c264051 Revert "added file_size"
stash@{2}: WIP on master: 21d80a5 added number to log
stash@{0}是最新的记录。WIP意思是 Work In Progress(进行中的工作)。
2.3 恢复并删除 (Pop) —— 最常用
将最新的暂存内容应用回工作区,并从栈中删除这条记录:
git stash pop如果恢复过程中出现冲突,Git 不会删除这条 stash,你需要解决冲突后手动删除。
2.4 恢复但这保留 (Apply)
将最新的暂存内容应用回工作区,但保留栈中的记录(适合你想在多个分支应用同一套修改):
git stash apply如果要应用指定的某一条(例如第2条):
git stash apply stash@{1}2.5 删除暂存 (Drop & Clear)
删除最新的一条:
git stash drop删除指定的一条:
git stash drop stash@{1}清空所有暂存记录(慎用!不可撤销):
git stash clear3. 进阶用法 (解决痛点)
3.1 痛点一:新创建的文件没有被 Stash?
默认情况下,git stash 只保存被 Git 跟踪(Tracked)的文件。如果你新建了一个文件 NewFile.js 但还没 git add 过,执行 git stash 后,这个文件还会留在工作区,不会被收纳。
解决方法:包含未跟踪文件
git stash -u
# 或者全写
git stash --include-untracked注:还有一个 -a (--all) 选项,连 .gitignore 忽略的文件也会一起 stash,通常不建议使用,因为可能会把编译生成的垃圾文件也存起来。
3.2 痛点二:stash@{0} 分不清是啥?
默认的 stash 备注是最后一次 commit 的信息,很难区分。
解决方法:给 Stash 加注释
git stash push -m "修复了登录按钮的样式,但逻辑还没写完"
# 旧版本 git 可能使用: git stash save "注释信息"这样 git stash list 就会显示你的备注,清晰明了。
3.3 痛点三:只想暂存一部分文件?
假设你改了 A 和 B 两个文件,只想暂存 A,继续在 B 上工作。
解决方法:交互式暂存
git stash push -pGit 会进入交互模式,逐个询问你每个文件的修改块(Hunk)是否要 stash(输入 y 或 n)。这和 git add -p 的逻辑一样。
4. 常见工作流场景
场景 A:紧急修复 Bug
- 正在
dev分支开发功能,改了5个文件。 - 老板大喊:“线上有个 Bug,快修!”
- 执行
git stash -u -m "开发到一半的功能A"。工作区变干净。 - 执行
git checkout master->git checkout -b fix-bug。 - 修复 Bug,提交,合并。
- 切回开发分支:
git checkout dev。 - 恢复现场:
git stash pop。继续干活。
场景 B:代码写错分支了
- 你以为你在
dev分支,写了一下午代码。 - 突然发现:“卧槽,我在
master分支上!” - 千万别提交。
- 执行
git stash。 - 切换到对的分支:
git checkout dev。 - 把代码移过来:
git stash pop。 - 完美转移。
5. 从 Stash 创建分支
如果你 stash 了一堆修改,过了很久才想起来去 pop,结果发现现在的代码和当时 stash 的代码差异巨大,执行 git stash pop 产生了极其复杂的冲突。
这时候,与其在当前分支解决冲突,不如把这个 stash 拿出来单独变成一个新分支:
git stash branch <新分支名> stash@{n}例子:
git stash branch recover-work stash@{1}这个命令的神奇之处在于: 它会创建一个新分支,检出的基准点是当初你执行 stash 时所在的那个 Commit,而不是当前的 HEAD。这样能保证必定没有冲突地还原现场。
6. 总结速查表
| 目的 | 命令 |
|---|---|
| 保存进度 | git stash |
| 保存进度(含新文件) | git stash -u |
| 保存并加备注 | git stash -m "备注信息" |
| 查看列表 | git stash list |
| 恢复并删除 | git stash pop |
| 恢复但保留 | git stash apply |
| 删除指定记录 | git stash drop stash@{n} |
| 清空所有 | git stash clear |
文章评论