跳至主要内容

Git Stash 全面解析:保存、恢复与管理更改

学习如何使用 git stash 来保存、检查、恢复并管理更改。了解选择性暂存、冲突修复,以及保持流程清晰的最佳实践。
· 9分钟 阅读

使用 AI 探索

您正在为数据管道实现一个新功能,突然收到一个紧急的缺陷报告。工作目录里到处都是尚未完成的更改。您还不准备提交,但又需要立刻切换分支。

在本教程中,我将向您展示如何使用完整的 git stash 命令套件。您将学习如何保存、检查、恢复、选择性暂存以及清理 Git 中的暂存。若想进一步学习,建议您参加我们的 GitHub 概念入门 课程,了解更多关于版本控制以及在 GitHub 上使用仓库的知识。

什么是 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 会忽略从未添加到仓库中的文件。如果您新建了一个测试文件,常规的暂存会把它留在目录中,这在切换分支时可能引发问题。

如何使用 git status 检查工作目录的当前状态。

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

git stash -u

如何使用 git stash 包含未跟踪的更改和新文件。

要包含所有文件(包括 .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

如何使用 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

如何使用 git stash pop 恢复并删除暂存。

运行 pop 后,您的更改会被恢复,同时该暂存被移除。因此,当您确定不再需要该保存状态并希望保持暂存列表整洁时,请使用 pop。

若想更深入地了解 pop 命令,建议查看我们的 Git Stash Pop 教程,学习在仓库中切换分支时如何保存未提交的工作。

git stash apply:应用并保留

如果您想恢复更改但保留暂存以便复用,请按如下使用 apply 命令:

git stash apply stash@{1}

如何使用 git stash apply 恢复并保留暂存。

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

您可以使用 git stash list 确认使用 apply 后该暂存是否仍然存在。

如何使用 git stash list 显示所有暂存。

如何进行选择性暂存

在实际项目中,更改往往相互交织。在这种情况下,您可能只想暂存一部分工作,保留其余部分可用。Git 提供了两种方法来进行细粒度控制。

git stash push -m:暂存特定文件

如果您清楚需要搁置哪些文件,可以通过指定路径只暂存所选文件:

例如,下方命令仅暂存 data_pipeline.py 文件。当您想暂停一个实验性功能的开发,同时保留一个缺陷修复处于已暂存、随时可提交的状态时,这非常有用。

git stash push -m "stash experimental pipeline logic" data_pipeline.py

要检查命令是否成功执行,请使用 git status 显示仓库的前后状态。

如何使用 Git 暂存特定文件。

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 clear 时格外谨慎,因为此操作是永久性的,且无内置撤销。只有在确定不再需要任何暂存内容时才运行它。

git stash branch:将暂存转换为分支

如果自创建暂存以来,当前分支已经发生了较大变化,应用它可能会引发 合并冲突。此时,您可以直接从暂存创建一个新分支:

git stash branch pipeline-fix stash@{1}

如何使用 git stash branch 将暂存转换为分支。

上述命令会执行以下操作:

  • 从创建该暂存时的原始提交上创建一个新分支
  • 应用该暂存
  • 将其从暂存列表中移除

建议您查看我们的 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 中的

应用暂存时发生冲突

当您所在的分支与暂存中的同一代码行都发生了更改时,就会发生冲突。例如,在新分支上修改文件后运行 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,并处理数据管道开发中的复杂版本控制场景与问题。

Allan Ouko

作者

Allan Ouko

数据科学技术写作者,具备数据分析、商业智能和数据科学的一线实践经验。我撰写以行业为导向的实用内容,涵盖 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”?

当您的工作目录是干净的、没有任何已修改或已暂存的受跟踪文件可供暂存时,就会出现该问题。

恢复暂存时产生冲突的原因是什么?

当当前分支与暂存的更改在文件的同一部分都发生了修改时,就会发生冲突。

主题