跳至主要内容

Git Stash Pop:在切换分支时保留工作

学习如何在切换分支时保存未提交的工作,并在稍后无损恢复代码。
· 15分钟 阅读

使用 AI 探索

如果您有尚未完成、不适合提交的工作,但此刻必须切换上下文,请不要来一个“WIP”提交。也别像 2005 年那样把改动复制粘贴到文本文件里。git stash 就足够了。

该命令是切换上下文时保留未提交工作的首选方式。它允许您临时存储改动,在其他分支处理紧急任务,并将一切原样恢复到您离开时的状态。

本文将带您了解 git stash pop 的工作方式、何时优先于 git stash apply 使用它,以及如何在不可避免的冲突出现时进行恢复。

如果您刚接触 Git,觉得 stash 的概念有些困惑,请先打好基础。我们的 Introduction to Git 和 Introduction to GitHub 课程将帮助您迅速上手。

理解 Git Stash

Git stash 是用于存放未提交更改的临时储物间。

把它想成您的工作剪贴板。工作区有一些还没准备好提交的改动,但您需要切换分支或从远程拉取更新。与其丢失工作或做一个 WIP 提交,不如把它们 stash 起来。

该命令会保存您的修改,并将工作区还原为与 HEAD 提交一致。

Git 中的 stashing 思想

Stashing 解决了一个简单问题:Git 不允许在存在未提交更改时切换分支。

假设您在开发一个功能时收到一个缺陷报告。您需要立刻切到另一个分支,但手头有未写完的代码和被修改的文件。提交不合适,因为工作未完成。强制 checkout 又会丢失更改。

这时就该用 stash。

以下是 stash 能帮上忙的常见场景:

  1. 为紧急工作切换分支: 正在开发中途却需要修复线上缺陷。
  2. 拉取远程更新: 同事推送了更新需要拉取,但您有本地修改。
  3. 避免凌乱提交: 还没准备提交,但需要一个干净的工作区来 rebase 或合并。
  4. 保存试验性代码: 想尝试不同思路,又不想丢失当前工作

Stashing 快速且可逆——无需思考提交信息或分支名。

stash 栈的架构

Git 以后进先出(LIFO)的栈维护 stashes。

每次 stash,Git 都会在栈顶创建一个新条目。最新的 stash 是 stash@{0},旧的依次下移:stash@{1}、stash@{2},以此类推。

在幕后,每个 stash 实际上是一个提交——更准确地说,是一组提交。Git 会创建一个多父提交结构,用于存储:

  1. 您的工作区更改
  2. 已暂存的更改(索引)
  3. 未跟踪文件(若使用了u 标志)

这意味着 stash 不只是快照。它们是完整的提交,Git 之后可以将其重新合并到您的工作区。

您可以两种方式引用 stash——用 stash@{0} 这种索引语法,或用 git stash list 找到您给的消息并引用那个特定的 stash。最近的条目用索引更快,但当保存了多个 stash 时,用消息更好。

典型的 stash 栈如下所示:

图片 1 - 示例 git stash list 输出

前缀 WIP on 表示您在不带消息的情况下使用了 git stash。前缀 On 表示您通过 git stash push -m 提供了自定义消息。

Stash 只存在于您的本地仓库——不会被推送到远程。这让您的临时工作待在该待的地方:您的机器上,随时可恢复。

创建、管理与检查 Stash

基本的 git stash 命令足以起步,但也有点偷懒。您最终会得到一堆“WIP on branch-name”的条目,完全看不出里面是什么。六周后,您不会记得哪个 stash 是缺陷修复、哪个是半截重构。

下面我来展示如何一开始就把事情做对。

用合适的元数据创建 stash

最简单的 stash 方式是直接输入 git stash:

git stash

这会保存您的更改,但“WIP on main”的信息不够 informative。您不检查就看不出里面是什么。

改用带描述信息的 git stash push -m:

git stash push -m "Updated file.txt"

现在您的 stash 列表就真正有信息量了:

图片 2 - 带消息与不带消息的 Git stash 对比

差异一目了然。一个条目能准确告诉您做了什么,另一个只能让您猜。

写消息时,就像在给未来的自己留便条。“添加认证逻辑”“修复导航栏缺陷”或“尝试新 API 设计”都比泛泛的 WIP 强得多。

包含未跟踪或被忽略的文件

默认情况下,git stash 只保存已跟踪的文件——即 Git 已认识的文件。

未跟踪文件会留在工作区。这常让人措手不及:他们以为 stash 后切换分支会很干净,却发现新文件还在那儿。

实际发生的是:

echo "new_feature.py" > new_feature.py
git stash

该文件没有被 stash,因为 Git 尚未跟踪它:

图片 3 - 试图 stash 未跟踪文件

要解决这个问题,使用 -u 标志以 stash 未跟踪文件:

git stash push -u -m "Added a Python file for a new cool feature"

这样会同时 stash 已跟踪与未跟踪文件。您的工作区会变得完全干净。

图片 4 - Stash 未跟踪文件

提示:您也可以加上 -a 标志以包含被忽略的文件。它会 stash 已跟踪、未跟踪以及 .gitignore 中的文件。除非调试构建问题或想保存一个真正“全干净”的快照,否则很少需要。

这里有一份速查表,便于您判断何时用哪个标志:

  1. 无标志: 仅修改了已存在的文件

  2. u 标志:新增了尚未被跟踪的文件

  3. a 标志: 需要保存一切,包括构建产物或临时文件

大多数时候,您会使用 -u。在开发中新建过文件时,它是最稳妥的选择。

部分或选择性 stash

您不必 stash 工作区中的所有内容。

比如修了两个缺陷,但只想 stash 其中一个。或者改动涉及 5 个文件,但只有 3 个与要保存的功能相关。

您可以通过 pathspec 指定文件进行 stash:

git stash push -m "New files" new_file.txt new_file_2.txt

这样只会 stash new_file.txt 和 new_file_2.txt。其他一切留在工作区。

图片 5 - 仅 stash 选定文件

您也可以使用通配符:

git stash push -m "Stash all txt files" *.txt

或者使用 --patch 进行交互式 stash:

git stash push --patch

Git 会逐条遍历改动,询问您是否要 stash。您用 y(是)、n(否)或 s(将该块拆分为更小片段)来回答。

当同一文件里混有相关与无关改动时,这很方便。您可以 stash 功能性工作,把调试代码留在本地。

交互式提示大致如下:

图片 6 - Patch 示例

列出并检查 stash

如前所示,您可以运行 git stash list 查看所有已保存的 stash:

图片 7 - 列出 stashes

最新的 stash 始终是 stash@{0}。更旧的会在索引中下移。

如果您写了好的消息,扫一眼列表就能知道每个 stash 里是什么。否则就得逐个检查。

使用 git stash show 查看摘要:

图片 8 - Stash 摘要

它显示哪些文件被更改、增加或删除了多少行。

或者使用 git stash show -p 查看完整 diff:

图片 9 - 整个 stash 差异

标志 -p 会像 git diff 一样显示实际代码更改。这能帮助您在运行 git stash pop 前确认要弹出的 stash 是否正确。

Git Stash Pop 实际做了什么

接下来聊聊 git stash pop 的实际行为以及为什么要用它。

基本行为与语法

git stash pop 做两件事:应用您存起来的更改,然后将该 stash 从栈中删除。

基本语法:

git stash pop

这会弹出最近的 stash(stash@{0})并从列表移除。

您也可以通过索引弹出指定的 stash:

git stash pop stash@{1}

这会应用 stash@{1} 并删除它,但有个细节——剩余的 stash 会上移。原先的 stash@{2} 会变成 stash@{1},以此类推。

图片 10 - 弹出指定的 stash

Git 处理 stash pop 的方式

执行 git stash pop 时,Git 会在幕后执行一次三方合并。

它比较以下三种状态:

  1. 基准提交(您创建 stash 时的提交)
  2. 您当前的 HEAD 提交
  3. 被 stash 的更改

若合并能在无冲突的情况下完成,Git 会应用更改并移除该 stash。您的工作区将与 stash 前一模一样。

一个简单的工作流示例:

# You're working on a feature
echo "new feature code" >> feature.py
git stash push -m "Half-finished feature work"

# Switch to new branch and make unrelated changes
git checkout bugfix
echo "bug fix" >> bugfix.py
git add bugfix.py
git commit -m "Fix critical bug"

# Go back to your other branch
git checkout main

# Pop your stashed work
git stash pop

如果 Git 无法干净地合并,就会产生冲突。由于 pop 未成功完成,stash 会留在栈中。您会在文件中看到冲突标记,就像常规合并冲突那样。

出现冲突时,您需要手动解决、暂存修复后的文件并提交。stash 不会自动消失,因此在全部解决后需要运行 git stash drop。

跨分支应用 stash

Stash 不绑定任何特定分支。

您可以在 bugfix 上创建一个 stash,切到 main,并在那儿弹出。Git 不关心它来自哪里——它只是尝试将改动应用到您当前所在的分支。

这带来一些实用的工作流:

  1. 在分支间移动工作: 比如您一不小心在错误的分支上开始编码。与其重置并丢失工作,不如先 stash,切到正确分支,再在那里 pop。

  2. 重新组织任务: 您一周前 stash 了些试验性代码。现在想在另一个分支上试试是否更合适。

  3. 在不同上下文中测试改动: 您有一个缺陷修复被 stash 了,想在多个分支上测试后再提交。此时用 git stash apply 而非 pop,以便保留 stash,在不同分支测试后,再在目标分支上 pop。稍后我们会详细谈 apply。

只要改动与当前分支没有冲突,stash 就能干净地应用——这就是您需要牢记的核心。

Git Stash Pop 与 Git Stash Apply 对比

开发者常常会纠结该用 git stash pop 还是 git stash apply。

关键区别:stash 的持久性

主要区别很简单:pop 在应用后删除该 stash,而 apply 会保留它在栈中。

用 pop 的意思是“我用完这个 stash 了——应用并丢弃”。用 apply 的意思是“我可能还会用到它”。

这会以两种方式影响您的工作流:

  1. 安全性: 如果在 pop 过程中出了问题需要恢复,stash 已被删除。用 apply 时,stash 仍在栈中作为备份。

  2. 清理: 使用 pop 会自动保持 stash 列表干净。使用 apply 则需要稍后手动运行 git stash drop 删除已用完的条目。

大多数开发者默认使用 pop,因为更干净。但当您不确定改动能否在当前分支顺利应用,或想在多个分支测试同一改动时,apply 更合适。

可预测性、风险与索引位移

这正是 pop 的 tricky 之处——当您从栈中间弹出时,stash 索引会发生位移。

假设您有三个 stash:

stash@{0}: Feature work
stash@{1}: Bug fix
stash@{2}: Experimental code

如果您弹出 stash@{1},剩余的会向上移动:

stash@{0}: Feature work
stash@{1}: Experimental code

如果您在脚本中操作 Git 或连续执行多个 pop,这会带来问题。您先 pop 了 stash@{1},接着想 pop stash@{2},但该索引已不存在。

使用 apply 则没有这个问题。 只有当您显式运行 git stash drop 时索引才会移动。您可以按任意顺序应用 stash,而无需担心栈在过程中发生变化。

相同的冲突处理

两者处理冲突的方式完全一致。

如果 Git 无法干净地合并您的 stash,更改文件中会出现冲突标记。区别只在于 stash 的去留:

  1. 用 pop: 由于 pop 未成功完成,stash 会保留在栈中

  2. 用 apply: stash 依然留在栈中(本来也会如此)

两种情况下,您都需要手动解决冲突、用 git add 暂存解决后的文件,并(若使用 apply)用 git stash drop 删除该 stash。

冲突解决流程完全一致——唯一的区别在于成功时 stash 是否会被自动删除。

何时选择哪一个

在以下情况下使用 git stash pop:

  1. 您只需应用一次该 stash,之后就不再需要
  2. 希望自动保持 stash 列表整洁
  3. 只在单一分支上工作且不需要在其他处使用该 stash

在以下情况下使用 git stash apply:

  1. 想在多个分支测试同一改动
  2. 不确定该 stash 是否能干净应用
  3. 在脚本中操作 Git,需要可预测的索引
  4. 需要一个兜底以防万一

在 Stash Pop 中处理冲突

当 Git 无法干净合并您 stash 的更改时,就会发生冲突。本节将向您展示如何处理。

冲突出现的时机与原因

冲突发生在您弹出 stash 时 Git 执行的三方合并过程中。

Git 会比较代码的三个版本:

  1. 创建 stash 时的基准提交
  2. 您当前的 HEAD 提交
  3. 被 stash 的更改

如果相同的代码行在当前分支与 stash 中都发生了改动,Git 不知道该保留哪一个——这就是冲突。

常见的 stash pop 冲突原因:

  1. 您在两个分支都修改了同一文件: stash 了文件的更改,切换分支后在弹出前又编辑了同一文件
  2. 别人推送了更改: 您先 stash,又从远程拉取更新,而这些更新也改到了相同代码
  3. 您做过 rebase 或 cherry-pick: Git 期望的基准提交已不存在,导致合并不匹配

总的来说,stash 放得越久,最终弹出时遇到冲突的可能性就越大。

冲突解决流程

发生冲突时,Git 会暂停 pop,并在文件中标记冲突:

您的文件现在包含冲突标记:

<<<<<<< Updated upstream 与 ======= 之间是您当前的代码;======= 与 >>>>>>> Stashed changes 之间来自 stash。

解决方法如下:

  1. 打开有冲突的文件,决定保留哪一方(或进行合并)

  2. 移除冲突标记(<<<<<<<、=======、>>>>>>>)

  3. 使用 git add 暂存已解决的文件

  4. 用 git stash drop 手动删除该 stash——别忘了它不会自动消失。

替代策略

如果不想在当前分支处理冲突,改用 git stash branch。

该命令会从您创建 stash 的提交上拉出一个新分支,并在其上应用该 stash:

git stash branch temp-feature

Git 会创建名为 temp-feature 的分支、切换过去并在其上弹出您的 stash。由于该分支从创建 stash 时的确切提交开始,因此不会有任何冲突。我将在单独一节中更深入讨论。

您也可以用 git reset --merge 来中止一次失败的 pop:

git stash pop

# Conflicts appear

git reset --merge

该操作会撤销 pop 尝试,并将工作区还原到 pop 之前的状态。stash 会留在栈中。

中止进行中的 stash 操作

如果您开始了 pop 或 apply 又想完全回退,有以下选项。

若冲突尚未开始处理,运行:

git reset --merge

这会取消合并并清理工作区。一切回到执行 stash 命令前的状态。

若冲突已部分解决,运行:

git reset --hard HEAD

这会丢弃工作区中的所有更改,包括您做过的任何修复。当改乱了只想重来时使用。

请注意该命令会销毁未提交的工作。执行前请确认您确实要全部丢弃。

中止后,您的 stash 仍在栈中(除非您使用了 pop 且其在遇到冲突前已成功)。您可以稍后再尝试,或使用 git stash branch 来获得更干净的方案。

清理 Stash

在生命周期较长的项目中,stash 会很快堆积。您为了修 bug 而暂存工作,然后把它忘了。您创建了实验性 stash,却从未弹出。六个月后,您有 20 个 stash,其中一半您都不知道里面是什么。

这会让您更难找到真正需要的那个。您最终会对每个条目都运行 git stash show -p 来搞清楚里面是什么。

这非常浪费时间,所以请记得定期清理您的 stash。

删除单个 stash

使用 git stash drop 删除指定的 stash:

git stash drop stash@{2}

这会从栈中删除 stash@{2}。剩余的条目会上移——原先的 stash@{3} 会变成 stash@{2}。

您也可以不指定索引,删除最近的 stash:

git stash drop

默认会移除 stash@{0}。

根据我多年的 Git 实践,以下是删除 stash 的主要原因:

  1. 您意识到不再需要这些改动
  2. 出现了重复的 stash(比您想的更常见)
  3. 某个 stash 太旧了,您已记不起它的用途

若拿不准是否应删除,先用 git stash show -p 检查。小心驶得万年船。

清空整个 stash 栈

您可以使用 git stash clear 一次性删除所有 stash:

git stash clear

请记住这将是永久性的。无法撤销或找回这些 stashes。

仅在完全确定不再需要任何已 stash 的工作时,才使用 git stash clear。

多数时候,逐个删除更稳妥,避免误删需要的内容。

从 Stash 创建分支

有时最干净的做法是把一个 stash 变成独立分支。这样可避免合并冲突,并给您的 stash 工作一个正经的归宿。

使用 git stash branch

git stash branch 命令会创建一个新分支并将您的 stash 应用到其上:

具体流程如下:

  1. Git 从您创建 stash 的提交处创建新分支 feature-experiment

  2. Git 切换到该新分支

  3. Git 在该分支上弹出 stash

  4. Git 将该 stash 从栈中移除(与 pop 相同)

由于新分支从与 stash 完全相同的提交开始,因此不会产生冲突。每次都能干净应用。

您也可以指定某个特定的 stash,而非最近的一个:

git stash branch new-feature stash@{2}

常见用例

从 stash 创建分支非常适合试验性功能。比如您一周前 stash 了些实验代码,现在想在不影响当前工作的情况下把它好好开发出来。

您会得到一个干净的分支来推进实验。若成功,就合并回来;若不行,就删掉分支继续前进。

它也非常适合处理耗时的 rebase。与其在 rebase 过程中应对潜在冲突,不如先把一切 stash,再由此创建分支。

git stash push -m "WIP before rebase"
git rebase main
git stash branch temp-work

现在您可以单独审查这些已 stash 的更改,并决定在 rebase 之后如何整合。

当改动庞大或杂乱时,创建分支也很有用。想象一个巨大的 stash,涉及 15 个文件,其中一半与当前分支冲突。直接创建新分支即可——无需硬着头皮硬合。

您将获得一个专用分支,能从容审查、规范提交,再以清晰的历史合回。

进阶技巧与恢复选项

至此您已熟悉 git stash 的基础用法,下面介绍一些更进阶的概念。

操作特定的 stash 条目

您可以弹出或应用栈中的任意一个 stash,而不只是最近的那一个。

通过索引引用 stash,即可精准获取所需:

git stash pop stash@{3}
git stash apply stash@{1}

这样可以在不触碰更新条目的情况下获取较旧的 stash。当您弹出中间某个 stash 时,其下方的索引会全部上移。原先的 stash@{4} 会变成 stash@{3}。如果您在脚本中操作 Git 或连续弹出多个 stash,这种索引位移会弄乱您的命令。

解决方案是在需要可预测索引时,用 apply 代替 pop:

git stash apply stash@{2}

# Drop it manually when you're done
git stash drop stash@{2}

这样您就能完全掌控栈何时变化。先应用、验证无误,再自行删除。只有当您明确要求时,索引才会移动。

恢复暂存区状态

默认情况下,git stash pop 和 git stash apply 会恢复您的改动,但不会保留当时的暂存状态。

比如您修改了三个文件,并在 stash 前将其中两个加入了暂存区。弹出该 stash 后,三个文件都会以未暂存的形式回来。Git 不再知道您原本打算提交哪些文件。

解决方案是使用 --index 标志来原样恢复暂存状态:

git stash pop --index

这会重建您在 stash 前的完整工作树与索引。已暂存的文件保持暂存,未暂存的保持未暂存。一切回到原样。

以下场景需要该标志:

  1. 您正精心准备一次提交,无法承受丢失暂存信息

  2. 您在处理复杂的暂存场景,比如用 git add -p 只暂存了文件的部分改动

  3. 您希望工作区与 stash 前完全一致,毫无差别

大多数时候,您用不上该标志。通常是先弹出,再视情况选择性暂存。

从 stash 错误中恢复

迟早您会误删一个需要的 stash,甚至不小心清空整个栈。

一旦发生,git 的 reflog 也许能救您。

reflog 会追踪仓库中所有引用的变更,包括 stashes。每次创建或删除 stash,Git 都会在 reflog 中记录。即使删除后,这些提交一段时间内仍会以不可达对象的形式存在。

您可以通过搜索不可达提交来找回丢失的 stash:

git fsck --unreachable | grep commit

搜索不可达提交

接着检查每个提交,找到您的 stash:

git show 066ded985342e585bc8e75c074add99ec1950f50

查看 diff 与提交信息以识别哪个是您丢失的 stash。找到后进行恢复:

git stash apply 066ded985342e585bc8e75c074add99ec1950f50

这样就会把丢失的 stash 应用回工作区,就像它从未被删除过一样。

更好的方法是遵循以下最佳实践,从源头避免失误:

  1. 为 stash 写清晰描述,这样在删除时心中有数。面对五个 stash,“修复登录缺陷”比“WIP”好得多。

  2. 在删除前先用 git stash show -p 确认无误。花五秒核对,胜过花五分钟恢复。

  3. 定期清理 stash 栈避免混乱。栈里只有三个相关 stash 要比 15 个陈年条目更易管理。

  4. 当您不百分之百确定要删除时,优先用 apply 而不是 pop。验证无误后,随时可以再 drop。

reflog 恢复可行,但很麻烦。看看上图就知道要手动检查多少提交——而这还是为本文特意创建的小项目。

最佳实践与工作流指南

想要用好 stash,就要遵循能避免失误、保持工作流整洁的模式。下面是我的常用方法。

推荐的工作流模式

最安全的 stash 工作流很简单:带消息地 stash,切换上下文,准备继续时再 pop。

# Work on feature-branch
git stash push -m "Feature work in progress"

git checkout main
# Do urgent work on main

# Go back
git checkout feature-branch
git stash pop

这对大多数情况都适用。您保留了工作,处理了打断,然后干净地恢复一切。

另一种常见模式是“弹出前先检查”。先列出 stashes,检查内容,再弹出正确的那个。

git stash list
git stash show -p stash@{1}
git stash pop stash@{1}

这个额外的确认步骤能防止您弹错或应用过时的工作。

有的开发者更倾向于用“临时提交”来替代 stash。他们不使用 stash,而是提交一个临时提交,如“WIP - not ready”,之后再 amend 或 reset。如果您对 stash 不太熟悉,或希望在分支历史中保留这段工作,这种做法也可以。缺点是如果忘了清理,提交历史会变得凌乱。

与开发工具的集成

大多数 Git 图形界面都能直观显示 stash,并支持一键弹出或应用。

GitKraken、Sourcetree 和 GitHub Desktop 等工具会在侧边栏列出 stash。您可以看到消息、检查 diff,并无需敲命令即可应用或删除。当有多个 stash 时,这能方便地并排对比。

VS Code 的 Git 扩展会在源代码管理面板显示 stash。您可以右键进行弹出、应用或删除,无需离开编辑器。

如果更喜欢命令行,别名能让 stash 更快捷。在 .bashrc 或 .zshrc 中添加:

alias gst='git stash'
alias gstp='git stash pop'
alias gstl='git stash list'
alias gsts='git stash show -p'

现在 gst 用于 stash 工作,gstp 用于弹出,gstl 用于列出,gsts 用于显示 diff。每次都能省下几次敲击。

stash 卫生与团队协作注意事项

Stash 仅存在于您的本机——永远不会被推送到远程仓库。

这意味着队友看不到您的 stash,您也无法在其他电脑访问。如果需要共享进行中的工作,请不要使用 stash。改用补丁或临时分支。

通过补丁共享工作的方法如下:

git stash show -p > my-work.patch
# Send the patch file to your teammate
# They apply it with: git apply my-work.patch

现在把补丁文件发给您的队友,他们将通过运行 git apply my-work.patch 来应用。

通过临时分支共享工作的方式如下:

git checkout -b temp/work-in-progress
git add .
git commit -m "WIP - authentication feature"
git push origin temp/work-in-progress

您的队友可以拉取该分支、审阅并继续。

无论您偏好哪种方式,都要保持良好的 stash 卫生。这能避免混乱,让本地栈易于管理。以下是一些宜遵循的做法:

  1. 为每个 stash 使用描述性名称。“添加用户认证逻辑”能告诉您里面是什么,“WIP on feature-branch”则毫无帮助。

  2. 每周清理一次 stash。运行 git stash list,删除一周前的条目。七天都没用到,多半以后也用不上。

  3. 不要让 stash 数量超过五个。超过五个往往意味着您把它当长期存储用了。要么弹出、要么提交、要么删除。

  4. 团队协作中若有人问“你在做的那个代码在哪儿?”,切勿回答“在我 stash 里”。Stash 是私有且临时的——不用于共享或归档重要工作。

结语

您现在已经了解 git stash pop 的工作机制及其适用时机。

本质上,stashing 很简单:保存未提交的工作、切换上下文、稍后恢复。但细节很重要。明白何时用 pop 与 apply,如何处理冲突,以及何时从 stash 创建分支,会为您省下大量时间与精力。

最重要的一点是:stash 是临时存储,而非永久备份。使用描述性消息、定期清理,并将栈控制在五个以内。若需要共享或长期保留,请改为提交到分支。

如果您喜欢这篇文章并希望进一步提升 Git 技能,接下来不妨看看我们的 Intermediate Git 与 Intermediate GitHub Concepts 课程。

Dario Radečić

作者

Dario Radečić

常驻克罗地亚的高级数据科学家。顶级科技写作者,已发表 700 多篇文章,累计获得超过 1,000 万次阅读。著有《使用 TPOT 实现机器学习自动化》。

FAQs

什么是 git stash pop?我该在什么时候使用它?

git stash pop 会将您最近一次存入的更改应用到工作区,并把该条目从栈中移除。当您为切换分支或拉取更新而临时保存了未提交的工作、现在准备恢复时,请使用它。它非常适合在不中断思路的情况下应对突发任务,而无需制造凌乱的“WIP”提交。

git stash pop 与 git stash apply 有何区别?

git stash pop 会应用 stash 并将其从栈中删除,而 git stash apply 会在应用后保留该 stash。不再需要某个 stash、想保持栈整洁时用 pop。需要在多个分支测试相同改动或想保留备份时用 apply。

使用 git stash pop 时出现合并冲突怎么办?

stash pop 期间发生冲突时,Git 会在文件中标记冲突并暂停操作。打开发生冲突的文件,手动选择保留的更改并解决冲突,然后用 git add 暂存已修复的文件。发生冲突后,stash 会继续留在栈中,完成后需要手动用 git stash drop 删除。

我能恢复误删的 stash 吗?

可以,您可以使用 Git 的 reflog 恢复被删除的 stash。运行 git fsck --unreachable | grep commit 查找不可达提交,然后对每个哈希使用 git show 来识别丢失的 stash。找到后,运行 git stash apply <commit-hash> 进行恢复。

我该用 git stash 还是做一个临时提交?

当您需要快速切换上下文并很快回到当前工作(如在其他分支修紧急缺陷)时,用 git stash。如果需要让工作记录在分支历史中,或对 stash 不熟悉,则可以做一个临时提交。请记住,stash 是本地且临时的,而提交是永久的并可推送到远程。

主题