我正在玩git中的藏匿处并遇到一些看似奇怪的行为。
创造了许多藏匿处后,我想看看它们里面有什么。我跑了git stash show -p
,它向我展示了人们所期望的最后一个藏匿的差异。然后我想确认索引0是指最近的存储,所以我(错误地)运行了git stash show -p @{0}
。这给了我以下错误:
fatal: ambiguous argument '': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
足够公平。但奇怪的是,它给我带来了一系列变化,我没有认识到这些变化,并且在我的任何一个存储中都不存在。
在这种情况下@{0}
指的是什么,差异来自何处?
答案 0 :(得分:1)
来自gitrevisions(7)
manual page
(您可以运行git help revisions
):
@{<n>}
,例如@{1}
您可以使用带有空引用部分的
@
构造来获取当前分支的reflog条目。例如,如果您在分支blabla
上,则@{1}
表示与blabla@{1}
相同。
答案 1 :(得分:1)
要在kostix's answer上展开一点,git stash
代码使用以下原则:
refs/stash
标识,因此stash@{number}
是此引用的reflog条目。stash
引用指向工作目录或工作树提交,有两个(如果存在第三个提交,则为三个)父提交。这意味着如果将工作树提交视为由常规Git命令进行的常规提交,则它只是一个合并提交。 (实际上将其视为普通合并可能会产生特殊效果,因此最好使用git stash
命令来处理它。)第二点 - 这是一个实现细节 - 但却非常强烈地影响git stash
代码。特别是,当{并且仅当它是合并提交时,git stash
将认为任何提交 是有效存储。它实际上并不要求通过refs/stash
或其中一个相应的reflog条目命名提交。
如果你写stash@{1}
,gitrevisions中列出的规则通常会找到refs/stash
并提取第1个reflog条目(即第一个,不包括{{ 1}} entry,在技术上根本不是reflog条目:Git只检索引用本身的值,而不是reflog中的条目。)
假设存在stash@{0}
,这将命名您的一个存储工作树提交,这将是一个合并提交。 stash@{1}
代码验证您所提交的提交是“类似存储”,即具有规定的格式。
但这也意味着如果您使用哈希ID或分支名称或任何其他命令运行某些git stash
子命令(例如git stash
或show
)修订解析代码可接受的名称 - 包括类似apply
的普通类似于reflog的引用,这意味着“从HEAD中提取的值” - 隐藏代码将尝试使用该代码执行其操作提交。
如果该提交通过了“类似stash”测试,则隐藏代码会将其视为,就好像它是存储一样。由于“stash-like”测试基本上是“是一个合并提交”,@{0}
或git stash show @{0}
会发生的情况是,如果当前提交是合并,git stash show HEAD
往往显示它的一部分(从技术上讲,它只是git stash show
与HEAD^1
的区别。如果它不合并提交,HEAD
应该抱怨并退出:
git stash show
但是旧版本的Git并不总是那么聪明。如果你的Git真的很古老,它可能会尝试显示一些现有的存储,将额外的参数传递给'HEAD' is not a stash-like commit
会抱怨它们。