2017-10-13 268 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