2017-10-13 266 views
0

我正在玩弄git中的stash,并遇到了一些看似奇怪的行为。`git stash show -p @ {0}`显示的不正确语法是什么(而不是使用正确的`stash @ {0}`)

创建了一些窗口后,我想看看里面有什么。我跑了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}在此上下文中提到并且差异来自哪里?

回答

1

要扩大kostix's answer了一下,git stash代码使用以下原则:

  • “的” 藏匿(默认一个)名称为refs/stash,因此[email protected]{number}是此引用的reflog条目。
  • 每个存储实际上由两个(或者有时是三个)提交组成,如Is this a valid visualization of the "git stash" operation?图中所示stash引用指向工作目录或工作树提交,其中有两个(如果是第三个提交存在)父提交。这意味着如果将工作树提交视为由常规Git命令进行的常规提交,那么它将仅仅是一个合并提交。 (其实把它当作一个普通的合并能产生奇特的效果,所以最好使用git stash命令与它合作。)

这第二点,这是一个实现细节,仍然影响git stash代码相当强烈。特别是,git stash会认为任何承诺一个有效的存储当且仅当它是一个合并提交。它实际上并不要求通过refs/stash或其中一个相应的reflog条目来命名提交。

如果你写[email protected]{1},规则为gitrevisions概述通常会发现refs/stash并提取了1个引用日志条目(即,第一个,不计算[email protected]{0}项,这在技术上是不是引用日志条目都:Git只是检索引用本身的值,而不是来自reflog的条目)。

假设[email protected]{1}存在,这将命名您的存储工作树提交之一,这将是一个合并提交。 git stash代码验证您提交的提交是“隐藏”,即具有规定的形式。

但是,这也意味着,如果运行一些git stash子命令(如showapply)使用散列ID,或分支的名称,或任何其他名称可以接受的版本解析代码 - 包括@{0}这样的普通类似reflog的引用,意思是“从HEAD中提取的值” - 存储代码将尝试用该提交完成它的事情。

如果该提交通过了“隐藏式”测试,则存储代码会将其视为,就像它是存储一样。由于“隐藏”测试基本上是“合并提交”,因此git stash show @{0}git stash show HEAD会发生什么情况,即如果当前提交是合并,则git stash show倾向于显示其中的一部分(从技术上讲,它只是区分而不是HEAD) 。如果它不一个合并提交,git stash show应该抱怨和退出:混帐的

'HEAD' is not a stash-like commit 

但旧版本并不总是那么聪明。如果你的Git真的是古老的,它可能试图展示一些现有的藏匿处,将额外的论据传递给git diff,这将会抱怨他们。

1

gitrevisions(7) manual page (可以运行git help revisions):

@{<n>} , e.g. @{1}

You can use the @ construct with an empty ref part to get at a reflog entry of the current branch.For example, if you are on branch blabla then @{1} means the same as [email protected]{1} .

+0

'@ {0}'在这种情况下无效。 – ElpieKay

+0

@ElpieKay这就是OP的问题所在,不是吗? – kostix