2016-06-13 177 views
1

在它的預提交鉤子git似乎驗證HEAD存在。如果不是,它默認使用空樹的特殊散列來比較索引。爲什麼git的pre-commit hook會驗證HEAD是否存在?

if git rev-parse --verify HEAD >/dev/null 2>&1 
then 
     against=HEAD 
else 
     # Initial commit: diff against an empty tree object 
     against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 
fi 

它默認的散列是一個特殊的散列。我讀,我也可以通過

git hash-object -t tree < /dev/null 

against得到它以後像這樣使用

# If there are whitespace errors, print the offending file names and fail. 
exec git diff-index --check --cached $against -- 

爲什麼掛鉤做到這一點?在什麼情況下我可以做一個提交但HEAD將是無效的?

回答

1

HEAD總是指向當前提交的,因爲:

  • 它包含當前的分支(例如ref: refs/heads/master)的名稱,或
  • 它直接指向實際提交ID(一個「detached HEAD」),以便它包含原始SHA-1哈希字符串。

如果HEAD包含原始散列值,然後HEAD肯定是有效的,因爲它指向一個真正的承諾。但是......在一個全新的空倉庫中會發生什麼?

你在分支master,所以HEAD讀數爲ref: refs/heads/master。但是什麼是分支master的小費?什麼提交ID存儲在master本身?

存儲庫中沒有提交。你會在哪裏製作master點?

Git解決這個問題的辦法是保持master無效。那時git rev-parse --verify HEAD失敗:HEAD表示master,但master尚不存在。

在內部,Git將此稱爲「未出生的分支」,有時也稱爲「孤兒分支」。使用git checkout --orphan newbranch將Git置入新創建的相同狀態(除非它不是真正創建的而是)分支newbranchHEAD參考現在包含ref: refs/heads/newbranch,但仍然沒有newbranch。因此,每個未出生的分支狀態都是這樣的,但每當您創建一個新的空存儲庫時,都會看到一個特定的狀態。