如何查看“ git stash -u”的未跟踪文件

Mat*_* J. 3 git git-stash

将内容存储在git中非常有用。存放取消跟踪的文件并像这样进行存放时

echo test > foo
git stash -u # foo is stashed
git stash show -p stash@{0}
Run Code Online (Sandbox Code Playgroud)

未跟踪的文件不会显示。我们怎么看到他们?

谢谢

tor*_*rek 9

您只需要查看第三个隐藏提交即可。但是“只是需要”稍微低估了事情,直到您知道三个隐藏提交什么,这才有意义。要明白我的意思,请继续阅读。

设置:关于隐藏的知识

当您运行git stash save或时git stash push,Git的常规操作是创建两个提交,两个提交都不在任何分支上。如果您像这样绘制“之前”的图片,则将具有以下一系列提交:

...--o--o--*   <-- branch (HEAD)
Run Code Online (Sandbox Code Playgroud)

git stash save完成,你有两个新的提交上没有的分支branch,而不是任何其他分支之一:

...--o--o--*   <-- branch (HEAD)
           |\
           i-w   <-- the stash
Run Code Online (Sandbox Code Playgroud)

w同时提交保存工作树的状态i提交保存索引。这两个提交中的每一个都非常类似于任何其他提交,并且实际上,该i提交是使用大多数常规git commit机制进行的:Git使用将当前索引写入内部对象git write-tree,然后使用来创建提交对象git commit-tree。如果您不知道这些内部对象是什么,则不必对此太担心:重点在于,这也是git commit通过编写树然后提交对象来完成其大部分工作的方式。(其余步骤git commit包括首先收集您的日志消息,然后在最后更新分支名称。)

w犯是一个有点复杂,因为它的形式(而不是意图)一的合并提交,两个父母,而不是一个。但基本上,它会保存工作树的快照,就好像您已git add在所有跟踪的文件上运行一样。

当您添加--all--include-untracked-a-u简称)时,git stash它的作用是添加了第三次提交,我们可以这样绘制:

...--o--o--*   <-- branch (HEAD)
           |\
           i-w   <-- the stash
            /
           u
Run Code Online (Sandbox Code Playgroud)

第三次提交是快照,但这是一个非常奇怪的快照。它包含未跟踪的文件-未被跟踪但未被忽略的文件(git stash save -u),或包括未跟踪和被忽略文件的未跟踪文件(git stash save -a)。它也没有提交。

隐藏“堆栈”,提交哈希ID和父对象

Git添加了动词的原因1pushgit stash push其他情况下,它基本上是同义词save-的原因是,当您创建新的存储时,Git使用存储reflog来跟踪较早的存储。当前存储stash@{0}使用reflog术语,而较早的存储变为stash@{1}

这些名称中的每一个只是Git为您提供的更为通用的东西的特定情况:您可以使用解析为正确的哈希ID的任何名称来引用任何提交。任何提交的“真实名称”是其较大的丑陋哈希ID。 gitrevisions文档全面介绍了将哈希ID拼写到Git的所有方法;使用类似branchstash这样的名称就是这样一种方式。

使用该名称可专门stash查找提交w。然后,Git使用w自身来查找commit i,如果存在的话,则要提交commit u。Git之所以可以这样做是因为每个提交都包括其父提交的哈希ID 。使之w具有合并提交形式的原因是,它至少有两个父级:i,索引提交和*,您在运行时git stash savegit stash push刚开始时所坐的提交。

我们可以stash通过添加插入符号^和数字来专门查看编号的父级,从而修改大多数修订说明符(如)。写作stash^1是命名提交的一种方式*; 写作stash^2是命名提交的一种方式i。如果u存在提交,stash^3则将其命名。请注意,在某些系统上(Windows),^可能是一个特殊字符,需要加倍或加引号,因此stash^3可能不需要stash^^3


1另一个原因是增加了使用pathspecs进行部分隐藏的能力:git stash save将任何额外的参数作为消息包含在隐藏提交中,因此他们需要一个用于-m指定消息的新动词,为pathspec参数留出空间。


查看u提交

我们可以使用查看任何提交git show。对于隐藏w提交,这会失败,因为Git认为w提交是合并,因此可以git stash show代替使用。(这一次合并,只是无法git show正确显示。)我对相关问题的较早答案要求git diffu提交上使用,因为在这种情况下,我们不想获取git show显示的标题,但是如果只想查看未跟踪的文件提交,可以git show在这里使用:

git show stash^3
Run Code Online (Sandbox Code Playgroud)

例如。这是foo上面示例的输出:

$ git show stash^3
commit 4c9bd2486706980f5a492d19c49270381db2d796
Author: Chris Torek <chris.torek gmail.com>
Date:   Sun Sep 16 12:35:03 2018 -0700

    untracked files on master: f72737e initial

diff --git a/foo b/foo
new file mode 100644
index 0000000..257cc56
--- /dev/null
+++ b/foo
@@ -0,0 +1 @@
+foo
Run Code Online (Sandbox Code Playgroud)

使用类似的名称stash@{1}标识reflog条目#1中的提交,这是“存储堆栈”中的下一个存储。(引用日志将开始从零算起,所以stashstash@{0}意味着同样的承诺。)因此,对于stash@{1}你需要stash@{1}^3或者可能stash@{1}^^3