2012-01-15 30 views
10

對於實驗的緣故,可以說你的git log確定了以下承諾是否僅基於樹的內容計算提交的SHA-1?

commit 16bc8486fb34cf9a6faf0f7df606ae72ad9ea438 // added 2nd file 
commit 9188f9a25b045f130b08888bc3f638099fa7f212 // initial commit 

承諾,.git/refs/heads/master點16bc8486fb34cf9a6faf0f7df606ae72ad9ea438後。

比方說,在此之後,我手動編輯.git/refs/heads/master文件指向9188f9a25b045f130b08888bc3f638099fa7f212

在這一點上,git的狀態確認,新提交的文件是需要一定的關注。這是我第二次提交之前處理的文件。

如果我不提交它.. git log現在顯示

commit b317f67686f9e6ab1eaabf47073b401d677205d5 // 2nd file committed for the 2nd time 
commit 9188f9a25b045f130b08888bc3f638099fa7f212 // initial commit 

問題1:

你會發現,SHA散列的第一次之間的不同我犯了第二個文件和現在。這是爲什麼?文件的內容沒有改變,它仍然是一樣的確切文件。

問題2

在這一點上,發生了什麼事原本第二的承諾?當我做git show 16bc8486時,它顯示這個提交。但它不會出現在git log的歷史記錄中。

+1

有趣的閱讀:http://book.git-scm.com/1_the_git_object_model.html – Mat 2012-01-15 20:42:01

回答

14

問題1:因爲生成的散列考慮了所有事情,包括提交元數據(本身包含日期和時間)。

問題2:git log顯示當前分支的日誌。提交16bc8486不是它的一部分。據我所知(我不完全確定),垃圾收集器遲早會把它拿走,如果它發現它沒有任何引用它(git gc --help)..

+0

Q2上,'git branch'只顯示了一個存在的分支 - * master。現在是舊文件的一部分? – JAM 2012-01-15 20:41:44

+0

@JAM:它不是任何分支的一部分,這就是爲什麼它是垃圾收集的候選人。您可以通過在該提交'git branch branch_name commit_hash'上顯式創建一個分支來「拯救」它。 – Mat 2012-01-15 20:43:10

+0

@Mat,如果有一段時間過去了,而且這個散列不是一成不變的,是否有可能以某種方式恢復它? – JAM 2012-01-15 20:49:32

2

SHA1計算從差異和所有來自此提交的元數據(包括作者和提交者,時間戳以及各種其他數據)。

對於第二個問題,數據提交仍然存在,但不再是任何活動分支的一部分。有時候git會運行一個垃圾收集,其中各種刪除的東西實際上將被刪除。你會注意到,一旦你使用git gc手動運行它,未提交的提交將會消失,甚至不能用git show訪問。

6

如果您擁有相同的內容(即使文件名已更改),文件Blob中每個文件的sha1值在兩種情況下都是相同的。

同樣,如果文件blob的具有相同的文件名,它們的sha1值將相同。

然而,在最高層,我們有提交其中將包含不變鏈接到以前提交,頂部樹,筆者和commiter,但KingCrunch說,作者和commiter日期將是不同 ,所以提交sha1的sha1將會不同。

如果您使用環境變量故意設置作者和提交者日期以使它們保持不變,那麼可以使它們相同。

+0

額外的推論;如果確實使它們相同,那麼就對象庫和分支圖而言,它們將是相同的。這就好像初始的但是完全相同的分割從未發生 - 它們是無法區分的!快樂狩獵。 – 2014-06-09 19:37:46