在 git 中,有没有一种方法可以显示未被跟踪的隐藏文件,而不需要应用隐藏文件?

如果我运行 git stash -u,我可以隐藏未追踪的文件。然而,说未跟踪的文件根本不显示与 git stash show stash@{0}。有没有办法在不使用隐藏文件的情况下显示未追踪的隐藏文件?

18807 次浏览

未跟踪的文件存储在存储提交的第三个父文件中。(这实际上并没有文档记录,但是从 引入 -u 特性的提交,787513..。git-stash的其余文档短语的方式来看是很明显的... 或者只是通过做 git log --graph 'stash@{0}')

你可以通过以下方式查看“未追踪”的藏匿部分:

git show 'stash@{0}^3'

或者,仅仅是“未被追踪的”树本身,通过:

git show 'stash@{0}^3:'

或者,树中一个特定的“未跟踪”文件,通过:

git show 'stash@{0}^3:<path/to/file>'

不幸的是,没有很好的方法来总结所有分阶段 + 未分阶段 + 未跟踪状态与“当前”状态之间的差异。即: git show 'stash@{0}'不能包含未跟踪的文件。这是因为隐藏对象的树对象(称为 stash@{0}:)本身并不包含来自第三个“非暂存”父对象的任何更改。

这是由于重新应用存储的方式: 被跟踪的文件可以很容易地作为补丁应用,而未被跟踪的文件只能在理论上作为“整个文件”应用。

您可以使用以下命令列出所有提交的存储:

git rev-list -g stash

由于存储被表示为 HEAD 的3路合并提交、索引和未跟踪文件的无父级“ root”提交,所以可以通过将上述输出通过管道传送到以下位置来列出未跟踪文件存储:

git rev-list -g stash | git rev-list --stdin --max-parents=0

上述的有用应用:

只显示未被跟踪的、隐藏的文件

git rev-list -g stash | git rev-list --stdin --max-parents=0 | xargs git show --stat

当然,删除 --stat以查看文件的内容。

找到一个特定的文件

git rev-list -g stash | xargs -n1 git ls-tree -r | sort -u | grep <pattern>

搜索未追踪的文件

git rev-list -g stash | git rev-list --stdin --max-parents=0 | xargs git grep <pattern>

列出所有存货的所有内容

git rev-list -g stash | git rev-list --stdin | xargs git show --stat

要列出隐藏的未追踪文件:

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

要显示所有未跟踪文件的完整差异(包括内容) :

git show stash@{0}^3

这些命令读取最后(最近)的存储。对于早期的存储,增加“ stash@”后面的数字,例如 stash@{2}作为上一个存储的第二个。

这样做的原因是,git stash为每个存储创建一个合并提交,可以引用为 stash@{0}stash@{1}等。此提交的第一个父级是存储时的 HEAD,第二个父级包含对被跟踪文件的更改,第三个(可能不存在)包含对未跟踪文件的更改。

这在 「讨论」项下的中得到了部分解释。

为了查看隐藏文件中的所有文件(包括跟踪的和未跟踪的) ,我将这个别名添加到我的配置中:

showstash = "!if test -z $1; then set -- 0; fi; git show --stat stash@{$1} && git show --stat stash@{$1}^3 2>/dev/null || echo No untracked files -"

它需要一个单一的 争论,其中存储您想要查看。注意,它仍然会在两个背靠背的列表中显示它。

如果没有通过,则 if...fi部分 更改 bash 参数 $1 to 0。

一个变通方法: 在存储文件之前先对它们进行分阶段处理,这将使 git stash show -p按预期工作。

git add .
git stash save

注: 这种方式也增加了交互部分的功能,这就是方法
注意: 确保你之前没有分阶段的工作,否则你将无法区分它。
这个可能有用。

然而,说未跟踪的文件根本不显示与 git stash show stash@{0}

注意: 从 Git 2.11开始(2016年第四季度,4年后,这个 OP) ,你可以参考存货与它的索引只

git stash show 0

由于 git stash在 C,固定在 Git 2.22中(2019年第二季度)中被重写,最近出现了一个 bug

有没有办法在不使用隐藏文件的情况下显示未追踪的隐藏文件?

没错,Git 2.32(2021年第二季度,OP 发布后9年)的确存在。

git stash show(< a href = “ https://git-scm.com/docs/git-stash # Document/git-stash.txt-show-u% 7C-include-untrack% 7C-only-untrackedltdiff-optionsgtltstashgt”rel = “ noReferrer”> man )学会了选择性地显示未被追踪的部分存货。

犯罪提交 d3c7bf7(2021年3月3日) by 刘(Denton-L)
(由 朱尼奥 · C · 哈马诺 gitster提交 f5c73f6合并,2021年3月22日)

教授 --include-untracked--only-untracked

签名: Denton Liu

可以通过 git stash push --include-untracked(< a href = “ https://git-scm.com/docs/git-stash # Document/git-stash.txt-- include-untrack”rel = “ norefrer”> man )使用未跟踪的文件进行存储条目。

但是,由于未跟踪的文件存储在存储条目的第三个父级中,而不是存储条目本身,因此运行 git stash show(< a href = “ https://git-scm.com/docs/git-stash # Document/git-stash.txt-show-u% 7C-include-untrack% 7C-only-untrackedltdiff-optionsgtltstashgt”rel = “ noReferrer”> man )时不会将未跟踪的文件作为 diff 的一部分包含在内。

使用 --include-untracked,除了在存储库基础和存储库中的工作树之间进行修改的路径之外,还会显示未跟踪的路径(如果存在,则记录在第三个父节点中)。

有可能手工制作一个畸形的存储条目,其中重复的未跟踪文件在存储条目将掩盖跟踪文件。
在这种情况下,我们通过定制的 unpack_trees()回调函数 stash_worktree_untracked_merge()检测并发生错误。

另外,教隐藏 --only-untracked选项,它只显示隐藏条目的未被跟踪的文件。
这类似于 git show stash^3(http://git-scm.com/docs/git-show),但是为它提供一个方便的抽象是很好的,这样用户就不必考虑底层的实现。

git stash现在在其 手册中包括:

'git stash' show [-u|--include-untracked|--only-untracked] [<diff-options>] [<stash>]

git stash现在在其 手册中包括:

--no-include-untracked

当与 pushsave命令一起使用时, 所有未被追踪的文件也被藏起来,然后用 git clean.

show命令一起使用时,显示隐藏中未跟踪的文件 作为差异的一部分进入。

--only-untracked

此选项仅对 show命令有效。
作为 diff 的一部分,只显示隐藏条目中未跟踪的文件。


你有一个配置去配合这些新的选项:

学习 stash.showIncludeUntracked

签名: Denton Liu

前面的提交指导 git stash show --include-untracked(< a href = “ https://git-scm.com/docs/git-stash # Document/git-stash.txt-- include-untrack”rel = “ norefrer”> man )
对于用户来说,始终启用 --include-untracked行为是可取的。
教授 stash.showIncludeUntracked配置选项,该选项允许用户以类似于 stash.showPatch的方式进行配置。

git config现在在其 手册中包括:

stash.showIncludeUntracked

如果将此值设置为 true,则不使用 选项将显示隐藏条目的未跟踪文件。

默认为 false。

git stash现在在其 手册中包括:

您可以使用 stash.showIncludeUntrackedstash.showStatstash.showPatch配置变量来更改默认行为。


随着 Git 2.32(Q22021) ,处理选项的代码最近添加到“ git stash show(< a href = “ https://git-scm.com/docs/git-stash # Document/git-stash.txt-show-u% 7C-include-untrack% 7C-only-untrackedltdiff-optionsgtltstashgt”rel = “ noReferrer”> man )周围未跟踪的部分存储 被切断了当这些选项被用于一个存储条目,不记录未跟踪的部分。

提交1ff595d犯罪(2021年5月12日) by 刘(Denton-L)
(由 朱尼奥 · C · 哈马诺 gitster于2021年5月16日在 提交 A8A2491合并)

stash show : 用 --{include,only}-untracked修复 Segfault

签名: Denton Liu

git stash show --include-untracked(< a href = “ https://git-scm.com/docs/git-stash # Document/git-stash.txt-- include-untrack”rel = “ norefrer”> man )git stash show --only-untracked(< a href = “ https://git-scm.com/docs/git-stash # Documents/git-stash.txt--only-untrack”rel = “ norefrer”> man )在不包含未跟踪条目的存储上运行时,将发生 Segfault。

之所以会发生这种情况,是因为我们没有检查未跟踪条目是否确实存在,而只是试图盲目地取消对它的引用。

在实际尝试取消引用之前,确保存在未跟踪的条目。

还有:

承认吧(2021年5月21日) by 刘(Denton-L)
(由 朱尼奥 · C · 哈马诺 gitster于2021年5月22日在 提交378c7c6合并)

stash show : 即使在给定 diff选项时也使用 stash.showIncludeUntracked

签名: Denton Liu

如果向 git stash show(< a href = “ https://git-scm.com/docs/git-stash # Document/git-stash.txt-show-u% 7C-include-untrack% 7C-only-untrackedltdiff-optionsgtltstashgt”rel = “ noReferrer”> man )提供了关于如何显示 diff 的选项,则该命令将忽略 stash.showIncludeUntracked配置变量,默认情况下不显示任何未跟踪的文件。
这是不直观的行为,因为 diff 输出的格式和是否显示未跟踪的文件是正交的。

即使给出了差异选项,也要使用 stash.showIncludeUntracked
当然,这仍然可以通过命令行选项覆盖。

更新文档以显式说明在给定 diff 选项时将重写哪些配置变量。

git config现在在其 手册中包括:

如果设置为 true,则将显示 git stash show命令 隐藏条目的未被追踪的文件。

默认值为 false

git stash现在在其 手册中包括:

如果没有提供 <diff-option>,将给出默认行为 通过 stash.showStatstash.showPatch配置变量。

还可以使用 stash.showIncludeUntracked设置 默认情况下启用 --include-untracked

我很难找到并应用正确的存储与我的未跟踪的文件与 git 低于2.32。

我使用这个命令是为了找到那些没有被跟踪的文件和日期:

git rev-list -g stash | git rev-list --stdin --max-parents=0 | xargs git show --stat

在使用另一个命令显示带有日期的存储列表以便找到带有特定日期的正确存储位置之后:

git stash list --date=local

之后,我再次使用 git stash list,以便找到隐藏的名称并将其应用于 git stash apply

这招对我管用,我希望这招对别人管用!