在git中存储内容非常有用。当存储未跟踪文件并通过这样的存储时
echo test > foo
git stash -u # foo is stashed
git stash show -p stash@{0}
未显示未跟踪的文件。我们怎么能看到它们?
谢谢
您只需要查看第三个存储提交。但是“只需要”稍微低估一下这些内容,直到你知道三个存储提交是什么时才会有意义。要明白我的意思,请继续阅读。
当你运行git stash save
或git stash push
时,Git的正常动作是创建两个提交,这两个提交都不在任何分支上。如果您像这样绘制“之前”图片,您将获得以下一系列提交:
...--o--o--* <-- branch (HEAD)
在git stash save
完成之后,你有两个新的提交不在分支branch
而不在任何其他分支上:
...--o--o--* <-- branch (HEAD)
|\
i-w <-- the stash
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
第三个提交是快照,但这是一个非常奇怪的快照。它仅包含未跟踪的文件 - 未跟踪但未被忽略的文件(git stash save -u
),或未跟踪文件,包括未跟踪和忽略的文件(git stash save -a
)。它也没有父提交。
一个原因是Git添加了push
动词,如git stash push
- 否则它基本上是save
的同义词 - 是当你创建一个新藏匿时,Git使用隐藏的reflog来跟踪先前的stashes。目前的存储是refz术语中的stash@{0}
,而早期的存储变为stash@{1}
。
这些名称中的每一个都只是Git为您提供的更一般的特定情况:您可以通过解析为正确哈希ID的任何名称来引用任何提交。任何提交的“真实名称”都是其丑陋的哈希ID。 The gitrevisions documentation有关于将哈希ID拼写为Git的所有方法的完整描述;使用像branch
或stash
这样的名字就是这样的一种方式。
使用名称stash
专门定位提交w
。然后Git使用w
本身来查找提交i
,如果存在,则提交u
。 Git可以这样做,因为每次提交都包含其父提交的哈希ID。是什么让w
具有合并提交的形式是它至少有两个父母:i
,索引提交,和*
,你在第一时间运行git stash save
或git stash push
时所提交的提交。
我们可以通过添加插入符号stash
字符和数字来修改大多数修订说明符(如^
),以专门查看编号的父级。编写stash^1
是一种命名提交*
的方法;写stash^2
是一种命名提交i
的方式。如果存在提交u
,写stash^3
命名它。请注意,在某些系统(Windows)上,^
可能是需要加倍或引用的特殊字符,因此您可能需要使用stash^3
而不是stash^^3
。
1另一个原因是添加使用pathspecs进行部分存储的能力:git stash save
将任何额外的参数作为要包含在存储提交中的消息,因此他们需要一个使用-m
来指定消息的新动词,为pathspec参数留出空间。
u
commit我们可以使用git show
查看任何提交。对于藏匿w
提交这个失败因为Git认为w
提交是一个合并,所以我们可以使用git stash show
代替。 (这是一个合并,只是没有一个git show
可以正确显示。)我的earlier answer to a related question要求在git diff
提交中使用u
,因为在这种特殊情况下,我们不想得到git show
显示的标题,但如果我们只是想要查看未跟踪的文件提交,可以在这里使用git show
:
git show stash^3
例如。以下是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
使用类似stash@{1}
的名称标识reflog条目#1中的提交,这是“存储堆栈”中的下一个存储。 (reflog从零开始计数,所以stash
和stash@{0}
意味着同样的提交。)因此,对于stash@{1}
,你需要stash@{1}^3
或者stash@{1}^^3
。