這實際上是Git作者選擇通過展示的實現細節。
Git不能 - 或者更確切地說,在一個點上,可能不會將文件直接從存儲庫讀取到工作樹中。它已經(或已經)首先通過中間人傳遞它們:它必須複製它們,或者至少複製它們的重要統計數據,在其他地方。只有這樣Git才能將數據複製到工作樹文件中。 「其他地方」是索引條目。該指數也被稱爲臨時區域。
當你git checkout
整個提交,這就是你想要的。所以內部限制,首先複製到索引,然後複製到工作樹上,實際上是一個優點。所以這個機制,首先複製到索引中,然後才進入工作樹,嵌入到實現中。然後,最終,面向用戶的git checkout
前端獲得了簽出一個單獨文件或一小部分文件的能力......並且它繼續這樣做到索引。實現細節成爲記錄的功能。
請注意,有時,索引在衝突合併期間被用作輔助區域。在這種情況下,對於一些文件F,在編號的時隙1(基),2(--ours
)和3(--theirs
)中有多達三個條目,而不是正常時隙零中的一個條目。如果是這樣,您可以將三個索引時隙條目中的任何一個提取到工作樹,而不會干擾索引。但是,如果您使用git checkout
從其他提交或樹中提取文件,Git會將該文件複製到索引中,並將其寫入到零插槽。這有刪除的副作用,解決合併衝突!
的主要原因之一是散列ID。作爲ElpieKay noted in a comment,Git必須將提交哈希解析爲樹形哈希,然後搜索各種樹以找出哪個或哪些文件感興趣,以便它可以獲得blob哈希。儘管如此,索引條目本身也包含更多的數據,包括工作樹文件的stat
結構數據,以使Git走得更快。
您還可以使用這個工作流程,通過使用git read-tree
到樹複製到索引,然後使用git checkout-index
複製指數的工作樹。最初,Git由一些shell腳本組成,如git-checkout
,它們圍繞着一些基本的C編碼片段,如git-read-tree
。(這些名字都是這樣的連字號,並且沒有前端git
命令。)
在'git checkout'中,分支被解析爲一棵樹,分支的頭部提交樹。該命令首先更新給定文件的索引,然後更新工作樹中的文件以匹配索引中的版本。所以現在工作樹和索引中的文件更新爲相同的。它就像'git add '一樣。 'git checkout --help'獲取更多信息。 –
ElpieKay
可能的重複[爲什麼結帳有時會暫存文件?](https://stackoverflow.com/questions/28837246/why-does-checkout-sometimes-stage-a-file) –