DEBUG.WIKI
京东云;让 AI 进入真实业务;零售 · 物流 · 客服 · 硬件;查看方案 →
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国
Evoxt;最高 6.0GHz CPU;高频云服务器 · 免费每周备份;查看配置 →

git stash -u 后,stash show 看不到未跟踪文件

git stash -u 保存后,stash show 默认可能看不到未跟踪文件。Git 2.32 起可用 include-untracked 或 only-untracked 查看;旧版读取第三父提交,并在恢复前确认条目、路径和保存范围。

执行 git stash -u 保存了新建文件,工作目录里的文件也消失了,但再看 git stash show 'stash@{0}',列表中只有原来已经跟踪的文件,甚至完全没有输出。这不能直接说明新文件没有保存。stash 的保存范围与查看范围不同。

Git 2.32 起,查看 stash 时可以显式包含未跟踪文件。先列出条目,确定要看的那一条,再查看其文件列表:

git stash list
git stash show --include-untracked --name-only 'stash@{0}'

stash@{0} 是当前最新条目,stash@{1} 是再前一条。下面都以最新条目为例;如果期间又创建或删除了 stash,应重新核对编号,避免查看或恢复错对象。示例适用于普通 Git 工作仓库,命令中的引号用于保护带花括号、插入符等字符的引用表达式。

保存时的 -u 不会自动变成查看时的 -u

git stash push --include-untracked 中的 --include-untracked 决定把未跟踪文件也保存进去,并从工作目录清理相应文件。git stash show --include-untracked 中的同名选项,只决定展示已有 stash 时是否包含这一部分,不会重新保存文件,也不会把文件还原到当前目录。

默认配置下,git stash show 展示保存时的已跟踪工作区内容相对于当时基础提交的差异,通常输出统计摘要。未跟踪文件保存在 stash 的另一部分;没有请求显示它们时,看不到它们属于显示范围问题。

可以按需要选择三种查看方式:

# 已跟踪修改和未跟踪文件都列出名称
git stash show --include-untracked --name-only 'stash@{0}'

# 只列出未跟踪文件的名称
git stash show --only-untracked --name-only 'stash@{0}'

# 只查看未跟踪文件的补丁内容
git stash show --only-untracked -p 'stash@{0}'

前两条适合确认文件是否在里面;第三条适合检查文本内容。对于二进制文件,补丁输出不一定展开可读内容,不能因为没有文本差异就判断文件不存在。

这里要使用 git stash show,不要漏掉中间的 stash。git show 是查看 Git 对象的另一条命令;其中 -u 可以表示生成补丁,不能拿来当作 stash 的“包括未跟踪文件”开关。

显式包含以后仍找不到文件

先区分是哪种情况,不要立即执行 pop 来试:

  • 选错条目:结合 git stash list 的分支名、说明和顺序重新定位。如果不确定,逐条用只读查看命令核对。
  • 文件当时已经暂存:执行过 git add 的新文件属于索引中的内容,未必出现在 --only-untracked 的结果里。改看 --include-untracked 的完整范围。
  • 创建 stash 时没有包括它:普通 stash 默认不收进未跟踪文件;即使后来给 show 加选项,也无法补存当时遗漏的内容。
  • 文件被忽略规则排除:保存时的 -u 不包含被忽略文件。保存时使用 --all 才会把忽略文件也纳入,但它还会清理工作目录中的这些文件,不能为验证旧 stash 而盲目运行。

创建时如果还使用了路径范围,也要确认目标文件是否在保存范围内。只读查看能回答“这个条目里有没有它”,不能证明一个不存在的文件从未被保存到其他条目或其他位置。

不要为了让旧文件显示出来,先在当前目录执行 git add . 再建一个 stash。这会改变当前暂存状态,并创建另一个条目,无法修复已经存在的条目,反而容易混淆当前工作与待查内容。

Git 低于 2.32 时查看第三父提交

如果 git stash show --include-untracked 报不认识选项,先用 git --version 确认版本。旧版可以通过 stash 的第三父提交查看保存的未跟踪文件。以下命令只读取对象:

git ls-tree -r --full-tree --name-only 'stash@{0}^3'

^3 表示第三个父提交,不是倒数第三条 stash。-r 递归列出目录中的文件,--full-tree 避免从仓库子目录运行时只看到局部范围。

找到路径后,可以直接查看其中一个文本文件。把 path/to/new-file.txt 换成列表里的实际路径,使用仓库根目录下的路径形式:

git show 'stash@{0}^3:path/to/new-file.txt'

这会将保存的文件内容输出到终端,不会覆盖工作目录中的同名文件。敏感配置或令牌文件不应把输出粘贴到公开日志;二进制文件也不适合直接打印到终端。

若提示 unknown revision 或 ambiguous argument,不能据此认定 Git 损坏了。先确认 stash 条目本身存在,再确认它确实保存过未跟踪部分。没有第三父提交的条目无法用这个表达式查看。不要把命令改成 git stash show 'stash@{0}^3':第三父提交本身不是完整的 stash 条目,应由普通的 git show 或 git ls-tree 查看。

确认内容前保留 stash

本次问题通常只需要调整查看命令。上面的 list、stash show、ls-tree 和用于读取文件对象的 show 都不要求恢复工作目录;查完无需回滚,也无需删除 stash。

如果检查后确实要恢复整条记录,先确认目标分支,保存当前工作及需要保留的未跟踪文件,并检查同名路径是否已经被新的文件占用。希望保留 stash 作为后续核对依据时,可以选择:

git stash apply 'stash@{0}'

apply 会尝试把内容应用到当前工作区,但不会从 stash 列表删除原条目;它不是只读查看。应用可能冲突,失败后也应先检查当前文件状态,不要连续重试,更不要接着清理未跟踪文件。需要撤回应用时,以操作前保留的工作区副本为依据,确认哪些修改属于本次应用,避免用整目录硬重置丢掉原有工作。

只有确认文件内容、恢复结果及其他需要保留的内容后,才考虑清理原条目。不要用 stash drop、stash clear 或 git clean 解决“列表里看不到文件”:它们不能扩大显示范围,却可能减少恢复余地。