根據檔案,兩個命令應該做同樣的事情,但結果不同,我不明白為什么也不明白差異的含義。
第一條命令
git worktree add -d "c:\temp\junk\blah" 209134fc8f
結果:
c:\temp\junk\blah>git status
Not currently on any branch.
nothing to commit, working tree clean
第二條命令
git worktree add -d "c:\temp\junk\blah"
cd "c:\temp\junk\blah"
git checkout 209134fc8f
結果:
c:\temp\junk\blah>git status
HEAD detached at 209134fc8f
nothing to commit, working tree clean
我希望這兩個命令給出相同的狀態結果。他們不。所以我的問題:
為什么這兩個命令的狀態結果不一樣?不在任何分支上與 HEAD 在提交時分離之間是否存在有意義的區別?對于以后的命令,兩者似乎都一樣。我專門使用“-d”是因為我不想為這個臨時作業樹創建一個新分支。
uj5u.com熱心網友回復:
為什么這兩個命令的狀態結果不一樣?
因為git status太聰明了,對自己好——或者對你好。??
不在任何分支上與 HEAD 在提交時分離之間是否存在有意義的區別?
這取決于你認為什么是“有意義的”。
理解這個答案有兩三個關鍵:
- Git 有(可選的)參考日志(在您的情況下默認啟用)。
- 每個添加的作業樹都有自己的 HEAD。
- 如前所述,
git status很聰明,也許太聰明了。
我們必須擴展其中的每一個才能到達我們要去的地方。
Reflogs
要理解 Git 中的 reflog,我們必須從“ref”或“reference”的概念開始。這些“refs”是分支名稱、標簽名稱、遠程跟蹤名稱和各種其他名稱的通用術語。幾乎所有這些 refs——或所有這些 refs,取決于在任何給定時刻你相信哪個 Git 檔案的部分——都用以 . 開頭的全名拼寫refs/。例如,分支名稱main實際上只是refs/heads/main. 這heads部分是使它成為分支名稱的原因:如果是refs/tags/main,它將是標簽名稱main。
(這意味著您可以擁有相同的分支和標簽名稱,一旦去掉它們refs/heads/和refs/tags/前綴。不要那樣做。Git 不會混淆它們,但你會,特別是因為名稱優先的規則取決于您使用哪個命令。)
有一個非常特殊的名稱,Git 的一部分稱為pseudo-ref,那就是HEAD(全部用大寫寫成這樣:小寫有時在某些系統上有效,但不要使用它:這是一個陷阱)。這不是唯一的偽參考,因為還有類似CHERRY_PICK_HEADandMERGE_HEAD和ORIG_HEAD更多的名稱,但與其他偽參考不同,HEAD它可以有一個 reflog。
每個參考或偽參考存盤一 (1) 個哈希 ID。(這使得在其中存盤FETCH_HEAD更多東西的.當時是特設的,現在 Git 永遠被困在這種情況下,或者至少直到 Git 3.0 或其他東西。)FETCH_HEAD
根據定義,存盤在分支名稱中的一個哈希 ID 是該分支的最后一次提交“in”或“on”。兩個或多個名稱可以標識同一個提交;在這種情況下,兩個分支都包含完全相同的提交集,因為任何一個分支的“in”或“on”提交集是通過讀取分支名稱以找到提示 commit來確定的,然后通過提交本身向后作業。 一旦提交,任何提交的任何部分都無法更改,因此如果名稱 X 和 Y 都選擇 hash ,并且我們從該提交向后作業,我們將始終找到相同的提交。(我們可以添加新的提交maina123456...到存盤庫,但我們不能更改或洗掉現有的提交。我們可以隨時更改存盤在任何分支名稱中的哈希 ID ,但同樣,我們無法更改或洗掉現有提交。)
到目前為止,這只是說明情況,所以現在讓我們了解 reflog 的目的。 每當我們以某個現有名稱存盤新的哈希 ID 時,最好將舊的哈希 ID 保存在某處,這樣我們就可以看到某個分支在昨天、上周或其他任何地方將哪個提交作為其提示提交。 這就是分支名稱 reflog 的作用。
鑒于 refs 通常出現在refs/*名稱下,Git 只是為每個這樣的 ref 存盤一個 reflog(當前在檔案中, in .git/logs/refs/,但這是一個實作細節:這些條目實際上是資料庫條目,將它們存盤在一個真正的資料庫,總有一天。)這些reflog 條目帶有日期和時間戳和哈希 ID,加上一條訊息和各種輔助資料位;git reflog并且您可以使用or轉儲任何特定 ref 日志的內容git log -g(這些在內部是相同的,只是它們具有不同--format的 default )。
因此,Reflog 條目會告訴您在某個較早的時間點某個 ref 中的哈希 ID是什么。這是如何作業的:Git 檢查 reflog 以查看24 小時main@{yesterday}或2 小時前存盤的值。這些條目最終確實會過期,至少現在,如果您洗掉一個名稱,它的 reflog 條目也會消失,盡管有模糊的計劃保留 reflog 條目以便能夠“取消洗掉”該名稱。main@{2.hours.ago}main
除了分支名稱、遠程跟蹤名稱甚至標記名稱的 reflog 條目(盡管理想情況下標記名稱的哈希 ID 永遠不會改變)之外,Git 還具有HEAD. 每當 Git 更新時,這些都會更新HEAD,包括切換分支時。不帶引數運行git reflog會轉儲HEADreflog。雖然洗掉分支名稱會洗掉分支的 reflog,但如果附加到該分支,則HEADreflog 可能會保留該分支中的哈希 ID 。HEAD
添加了作業樹,以及什么是共享的和不共享的
當您添加帶有 的作業樹時git worktree add,您選擇 Git 應該檢查的分支名稱或提交哈希 ID,如您的示例中所示。如果您使用或創建分支名稱,則添加的作業樹使用與原始作業樹相同的名稱。 refs/heads/這就是導致“必須是未在任何其他作業樹中簽出的名稱”限制的原因,盡管為了正確描述這一點,我必須更詳細地了解索引。
一旦您考慮一下,一件不共享的事情就很明顯:因為HEAD字面上包含分支名稱- 即,一個普通檔案,如果主作業樹是“on”分支,則.git/HEAD保存文字文本(加上換行符) - 每個添加的作業樹需要擁有自己的,以便它可以位于不同的分支上。這就是這里發生的事情:每個添加的作業樹都使用不同的偽參考(仍然拼寫但未存盤在 中),而不是 using 。ref: refs/heads/mastermaster HEAD.git/HEADHEAD.git/HEAD
這就是為什么即使在 Windows 和 macOS 系統上您也必須使用全大寫的原因HEAD:在添加的作業樹中,如果您輸入head小寫,Git 不會認為與HEAD(大寫) 匹配,因此不使用HEAD存盤在其他地方的每個作業樹。相反,Git 會嘗試打開檔案.git/head,因為檔案系統不區分大小寫,而是會打開該檔案,.git/HEAD并且 Git 認為您的意思是主作業樹中的任何提交,而不是添加的作業樹中的任何提交。因此,如果您不喜歡HEAD全部大寫,請考慮使用@,這是一個可以正常作業的單字符同義詞,即使在添加的作業樹中也是如此。
現在,考慮到所有這些,請記住我們的 reflogs。有一個 reflog HEAD,因此要使添加的作業樹正常作業,每個添加的作業樹都必須有一個單獨HEAD的 reflog 。事實上有。
(正如上面提到的,每個添加的作業樹還有一個單獨的索引或暫存區域。某些偽參考,例如二等分的偽參考,以同樣的方式擴展。基本上每個作業樹“應該是”的所有東西都是-worktree。當它沒有像這樣一致地處理時,這就是一個錯誤。在早期版本中有很多這樣的錯誤git worktree,首先在 Git 2.5 中引入。一個特別糟糕的錯誤在 2.15 中修復,在 2.17 中修復了更多。 )
我們終于準備好解決您最初的問題了。
git status和分離的頭
來自的第一條輸出線git status通常是,至少當您在某個分支上時。但是當你在某個特定的提交上而不是在某個分支上時,你可以處于“分離的 HEAD”模式。在早期版本的 Git 中,當您處于detached-HEAD 模式時,只會告訴您您不在任何分支上。同樣,會說。On branch branchgit statusgit branchHEAD detached at hash
在某個時候(Git-2.4 之前的版本),git status被教導了一些額外的聰明才智,稍微挖掘一下 reflogs 并嘗試弄清楚你是否仍然“在”某個較早的分支名稱選擇的提交,然后說:
HEAD detached at <hash>
或者,如果您HEAD從那時起通過檢查一些較早的提交或使用git reset或其他方式移動:
HEAD detached from <hash>
在 Git 2.4 中,git branch學到了同樣的技巧。 除了許多細微的調整之外,這或多或少就是今天的情況。
當您看到“當前不在任何分支上”時,這意味著:
HEAD是分離的,并且- reflog中沒有任何內容
HEAD表明較早的提交或分支,因此無法選擇atvsfrom。
當你看到atorfrom時,reflog 中有一些東西HEAD,如果有合適的分支名稱,你會得到這個名字,否則你會得到哈希 ID。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/526288.html
標籤:混帐
下一篇:如何為我的網站正確設定回應
