什么是 Git stash?
git stash 是一个 Git 命令,用于临时搁置未提交的更改,让您在不创建 Git 提交 的情况下回到一个干净的工作目录。这使得您可以轻松切换分支或处理紧急工作,同时不丢失进度。
暂存以后进先出(LIFO)栈的形式保存。最新的暂存始终是 stash@{0},接着是 stash@{1},以此类推。
默认情况下,git stash 会保存已修改的受跟踪文件和已暂存的更改(来自索引)。但它不会包含新的未跟踪文件以及像 .gitignore 中那样被忽略的文件。
如何使用 git stash 保存更改
本节将带您了解三种常见的暂存方式。我们使用同一个场景:假设您正在一个数据管道项目中工作,包含 data_pipeline.py、config.yaml 和 tests/test_pipeline.py 文件。
暂存受跟踪的更改
由于 git stash 会保存已修改或已暂存的更改,请先运行 git status 检查工作目录中文件的状态。运行 git stash 后,已暂存和未暂存的受跟踪更改都会被保存,您的工作目录将变为 干净 状态。

包含未跟踪的更改和新文件
默认情况下,git stash 会忽略从未添加到仓库中的文件。如果您新建了一个测试文件,常规的暂存会把它留在目录中,这在切换分支时可能引发问题。

如果您直接运行 git stash,该文件会保留。要将其包含在内,请使用 -u 或 --include-untracked 命令:
git stash -u

要包含所有文件(包括 .gitignore 明确忽略的文件),您可以使用 git stash --all 或 -a。但请谨慎使用,因为这可能会无意中把日志或构建产物等文件也一并暂存。
为暂存命名
使用 git stash 时,像 WIP on main 这样的默认信息在有多个暂存时会令人困惑。为避免此问题,在您想要 推送 暂存时,请务必添加一条描述性信息。
git stash push -m "refactor pipeline config handling."
您可以使用 git stash list 命令查看并对比暂存列表。注意带名字的暂存与默认暂存之间的区别。

清晰的消息可以让您在后续更容易找到正确的暂存,尤其是在同时处理多项任务或与团队协作时。
我建议您体验我们的 GitHub 基础 和 Git 基础 技能路径,从基础到高级工作流全面学习 Git 版本控制,包括跟踪更改、管理仓库以及高效协作。
如何查看和检查您的暂存
在盲目应用一个暂存之前,验证其中内容非常重要。这一步常被跳过,但它有助于避免混淆或意外覆盖。
git stash list:列出所有暂存
使用下方命令查看您的暂存栈:
git stash list

您现在应当知道,暂存遵循 LIFO(后进先出)顺序。最新的暂存总是 stash@{0},每创建一个新的暂存,旧的就会被推到栈底。
git stash show:在应用前检查暂存
要快速概览某个暂存中的更改,您可以对特定暂存使用 show 命令。例如,下方命令显示最新暂存中的更改:
git stash show stash@{0}

若要查看实际代码更改(完整 diff),使用下方命令显示该暂存中逐行的所有更改。
git stash show -p stash@{0}

作为最佳实践,请在应用暂存前先检查,尤其是当它已经放了几天或您不确定其中包含什么时。
如何恢复已暂存的更改
使用 git stash 保存工作后,您需要一种方式把它取回。主要有两种方法来恢复暂存,包括如何通过索引定位到特定的暂存。
git stash pop:应用并移除
这是最常见的恢复方式。它会取出顶部暂存(stash@{0}),将更改应用到当前分支,然后从栈中删除该暂存。
git stash pop

运行 pop 后,您的更改会被恢复,同时该暂存被移除。因此,当您确定不再需要该保存状态并希望保持暂存列表整洁时,请使用 pop。
若想更深入地了解 pop 命令,建议查看我们的 Git Stash Pop 教程,学习在仓库中切换分支时如何保存未提交的工作。
git stash apply:应用并保留
如果您想恢复更改但保留暂存以便复用,请按如下使用 apply 命令:
git stash apply stash@{1}

请注意,通过索引 stash@{1} 引用某个暂存,可以精准地恢复该项。当您需要在多个分支之间应用相同的更改时(例如需要同时进入 main 和 staging 的共享配置微调),这一方法非常有用。
您可以使用 git stash list 确认使用 apply 后该暂存是否仍然存在。

如何进行选择性暂存
在实际项目中,更改往往相互交织。在这种情况下,您可能只想暂存一部分工作,保留其余部分可用。Git 提供了两种方法来进行细粒度控制。
git stash push -m:暂存特定文件
如果您清楚需要搁置哪些文件,可以通过指定路径只暂存所选文件:
例如,下方命令仅暂存 data_pipeline.py 文件。当您想暂停一个实验性功能的开发,同时保留一个缺陷修复处于已暂存、随时可提交的状态时,这非常有用。
git stash push -m "stash experimental pipeline logic" data_pipeline.py
要检查命令是否成功执行,请使用 git status 显示仓库的前后状态。

git stash push -p -m:交互式暂存特定分块
有时,“稳定”代码和“进行中(WIP)”的代码会在同一个文件中。这种情况下,使用 -p 或 --patch 标志触发交互式会话。它允许您选择文件中的特定更改块(“hunks”)。
git stash push -p -m "Selective stash of pipeline logic"

您会看到“Stash this hunk”的提示及以下选项:
-
y:是,暂存此更改块 -
n:否,跳过此更改块 -
q:退出;不暂存此更改块或任何剩余更改块。 -
a:全部;暂存此更改块及文件中的所有后续更改块。 -
d:删除;不暂存此更改块及文件中的任何后续更改块。 -
?:帮助
请注意,该工作流与 git add -p 非常相似。当同一文件中的更改彼此无关、需要分别处理时,这非常有用。
如何清理您的暂存
暂存应该是短期的。如果任其堆积,后续会更难找到合适的那一项,也会在最终应用时增加发生冲突的风险。
git stash drop:删除特定暂存
要移除单个暂存,请使用带索引的 git stash drop。例如,下方命令会删除列表中的第 4 项暂存。
git stash drop stash@{3}

从上面的示例可以看到,暂存列表被缩减,删除后其余暂存会重新编号。
git stash clear:清空所有暂存
要一次性移除所有暂存,请使用:
git stash clear
该命令成功执行后不会输出,您可以通过运行 git stash list 来验证。

我建议在使用 git stash clear 时格外谨慎,因为此操作是永久性的,且无内置撤销。只有在确定不再需要任何暂存内容时才运行它。
git stash branch:将暂存转换为分支
如果自创建暂存以来,当前分支已经发生了较大变化,应用它可能会引发 合并冲突。此时,您可以直接从暂存创建一个新分支:
git stash branch pipeline-fix stash@{1}

上述命令会执行以下操作:
- 从创建该暂存时的原始提交上创建一个新分支
- 应用该暂存
- 将其从暂存列表中移除
建议您查看我们的 Git 分支 教程,了解更多关于管理分支以提升开发与协作的内容。
值得了解的其他 Git Stash 命令
除了常见工作流外,以下是一些您应该了解的高级 git stash 命令:
-
git stash create:创建一个暂存对象,但不将其加入暂存列表 -
git stash store:将通过 create 创建的暂存保存到列表 -
git stash export:将暂存导出为引用或打印出来 -
git stash import:从现有提交中导入一个暂存
常见错误及其修复方法
尽管 git stash 很直观,但一些常见问题仍可能让您栽跟头。以下是我遇到过的一些错误,以及如何快速识别并修复它们。
No local changes to save
这是最常见的“非错误”错误。当您在一个干净的工作目录中运行 git stash,且没有已修改或已暂存的受跟踪文件时,就会出现该提示。
要解决此问题,请运行 git status,如果没有任何输出可暂存,那就说明没有内容可暂存。

应用暂存时发生冲突
当您所在的分支与暂存中的同一代码行都发生了更改时,就会发生冲突。例如,在新分支上修改文件后运行 git stash pop,很可能会出现错误消息:

随后您可能会在文件中看到冲突标记:

要解决该问题,您可以执行以下任一操作:
- 在文件中手动解决冲突
- 将已解决的文件加入暂存区
git add data_pipeline.py
- 使用
git stash drop手动删除该暂存(如果在冲突时未被自动移除)
如果冲突过于混乱,请使用下方命令将更改应用到一个干净的起点。
git stash branch recovery-branch stash@{0}
不小心暂存了并非意图暂存的文件
有时您可能在未检查工作目录的情况下运行了 git stash,之后才发现把原本想提交的修复也给埋起来了。
为避免此类失误,请始终明确指定要暂存的文件。例如,下方命令只会暂存 data_pipeline.py,而不是工作目录中的所有内容。
git stash push data_pipeline.py
您也可以使用 git stash -p 进入交互(patch)模式,从而只暂存文件中的某些更改部分,而非整个文件。
作为预防措施,请在暂存前始终检查 git status。
结语
经验法则是,让暂存保持短期存在,并始终使用描述性消息。如果您一天之内不会回到这项工作,创建一个 WIP 分支会更安全,因为它可以推送到远程且不会丢失。
为更系统地提升 Git 技能,我建议您参加我们的 Git 进阶 课程,学习 Git 中的协作。我也推荐我们的 Git 高级 课程,学习如何在大型项目中使用 Git,并处理数据管道开发中的复杂版本控制场景与问题。

数据科学技术写作者,具备数据分析、商业智能和数据科学的一线实践经验。我撰写以行业为导向的实用内容,涵盖 SQL、Python、Power BI、Databricks 和数据工程,并以真实的分析工作为基础。我的写作兼顾技术深度与业务影响,帮助专业人士将数据转化为自信的决策。
Git Stash 常见问答
git stash 会保存未跟踪的文件吗?
不,默认情况下,git stash 只会保存受跟踪的文件。若要包含未跟踪的文件,请使用 git stash -u。
git stash 会影响我的提交历史吗?
不会,暂存与您的提交历史相互独立,不会出现在分支日志中。
git stash pop 与 git stash apply 有何区别?
git stash pop 会应用暂存并将其移除,而 git stash apply 会应用暂存但保留在暂存列表中。
为什么 Git 会提示“No local changes to save”?
当您的工作目录是干净的、没有任何已修改或已暂存的受跟踪文件可供暂存时,就会出现该问题。
恢复暂存时产生冲突的原因是什么?
当当前分支与暂存的更改在文件的同一部分都发生了修改时,就会发生冲突。
您正在为数据管道实现一个新功能,突然收到一个紧急的缺陷报告。工作目录里到处都是尚未完成的更改。您还不准备提交,但又需要立刻切换分支。
在本教程中,我将向您展示如何使用完整的
git stash命令套件。您将学习如何保存、检查、恢复、选择性暂存以及清理 Git 中的暂存。若想进一步学习,建议您参加我们的 GitHub 概念入门 课程,了解更多关于版本控制以及在 GitHub 上使用仓库的知识。