git的文件系統(tǒng)與底層原理

由于工作中使用git作為版本管理,之前對(duì)git的了解不多,特別是底層方面的原理方面的知識(shí)。為了能更好的使用git,有必要學(xué)習(xí)并梳理下相關(guān)知識(shí)。

步入正題:

git的文件結(jié)構(gòu)

執(zhí)行g(shù)it init 初始化后,會(huì)在.git文件夾下會(huì)創(chuàng)建多個(gè)目錄,每個(gè)文件夾功能劃分的很清晰。


git目錄結(jié)構(gòu).png

git的存儲(chǔ)方式

Git 是一套內(nèi)容尋址文件系統(tǒng).通過(guò)鍵值對(duì)的方式存儲(chǔ)和查找。

下面操作一遍,直觀的看到整個(gè)過(guò)程,以便理解。

  • 首先,創(chuàng)建一個(gè)內(nèi)容對(duì)象
$ echo "小明的文件" | git hash-object -w --stdin
5c98f8a9221e5336f68c7575cd238b48875137c6
命令/參數(shù) 說(shuō)明
echo 將字符串輸出到終端
git hash-object 創(chuàng)建一個(gè)blob(二進(jìn)制大對(duì)象),
可指定其他類型,不一定是blob。
--stdin 從標(biāo)準(zhǔn)終端中讀取輸入,代替從文件讀取,
這里讀取的是由echo命令輸出到終端的字符串。
-w 把blob對(duì)象寫入數(shù)據(jù)庫(kù)

參考:https://git-scm.com/docs/git-hash-object

  • 查看剛才存儲(chǔ)的數(shù)據(jù)
$ find .git/objects -type f
.git/objects/5c/98f8a9221e5336f68c7575cd238b48875137c6
命令/參數(shù) 說(shuō)明
find 查找目錄下文件
-type f 指定查類型為普通文件

參考:http://man.linuxde.net/find

可以見(jiàn)到文件名稱為數(shù)字和字母組成的字符串。這個(gè)是根據(jù)文件內(nèi)容和頭信息(Header),通過(guò)SHA-1算法計(jì)算得出的40位十六進(jìn)制校驗(yàn)和。

校驗(yàn)和 5c98f8a9221e5336f68c7575cd238b48875137c6
存儲(chǔ)路徑 5c/98f8a9221e5336f68c7575cd238b48875137c6
以校驗(yàn)和前兩位作為子路徑創(chuàng)建文件夾,
以校驗(yàn)和后38位作為文件名生成文件。

SHA-1是一種加密哈希函數(shù)(cryptographic hash function)。SHA-1將文件中的內(nèi)容通過(guò)其hash算法生成一個(gè)160bit的報(bào)文摘要,即40個(gè)十六進(jìn)制數(shù)字(每個(gè)十六進(jìn)制數(shù)字占4位)。它幾乎可以保證,如果兩個(gè)文件的SHA-1值是相同的,那么它們確是完全相同的內(nèi)容(類似于生活中的指紋識(shí)別);SHA-1主要有兩種用途,一個(gè)是加密,一個(gè)是數(shù)據(jù)完整性校驗(yàn)。Linux kernel開(kāi)創(chuàng)者和Git的開(kāi)發(fā)者——Linus說(shuō),Git使用了SHA-1并非是為了安全性,而是為了數(shù)據(jù)的完整性。理論上SHA-1會(huì)在2^51攻擊下實(shí)現(xiàn)哈希碰撞,所以也不是完全的安全。

  • 通過(guò)校驗(yàn)和作為鍵值 解讀文件
$ git cat-file -p 5c98f8a9221e5336f68c7575cd238b48875137c6
小明的文件
命令/參數(shù) 說(shuō)明
git cat-file 讀取對(duì)象信息
-p 根據(jù)對(duì)象的類型打印其信息

參考:https://git-scm.com/docs/git-cat-file

模擬bolb對(duì)象存儲(chǔ)流程


bolb存儲(chǔ)流程圖.png

以上,說(shuō)明了git的數(shù)據(jù)存儲(chǔ)的基本方式。主要步驟:

  1. 使用SHA-1算法根據(jù)其原始內(nèi)容和頭信息(頭信息格式"blob #{content.length}\0")生成唯一的40位校驗(yàn)和。
  2. 以校驗(yàn)和前兩位創(chuàng)建文件夾、校驗(yàn)和后38位作為文件名。
  3. 對(duì)拼接后的內(nèi)容壓縮后存儲(chǔ)。

下面是創(chuàng)建文件,修改文件,恢復(fù)文件的相關(guān)過(guò)程。

  • 重新創(chuàng)建一個(gè)倉(cāng)庫(kù)并創(chuàng)建一個(gè)文件
$ echo '小明該吃午飯了' > test.txt
$ git hash-object -w test.txt
efbd70f46da0d1852de88c58aebc86616beecdaf
  • 修改文件再保存
$ echo "小明打算去吃個(gè)泡面" > test.txt
$ git hash-object -w test.txt
26aab56c7d1f9bd962b28f78ce61f021b221d317
  • 查看已保存的內(nèi)容
$ find .git/objects -type f
.git/objects/26/aab56c7d1f9bd962b28f78ce61f021b221d317
.git/objects/ef/bd70f46da0d1852de88c58aebc86616beecdaf
  • 恢復(fù)到第一個(gè)版本
$ git cat-file -p efbd70f46da0d1852de88c58aebc86616beecdaf > .git/test.txt
$ cat .git/test.txt
小明該吃午飯了

git會(huì)記錄每個(gè)版本的修改,根據(jù)校驗(yàn)和可恢復(fù)到相應(yīng)的版本。


小結(jié):這個(gè)過(guò)程中包括文件創(chuàng)建、文件修改、文件恢復(fù),跟我們平時(shí)工作中使用的高級(jí)命令功能很相似。git會(huì)把整個(gè)過(guò)程轉(zhuǎn)化為底層操作,同時(shí)對(duì)用戶透明。

相關(guān)引用參考:
http://smilejay.com/2012/08/git-commit-sha-1/
https://git-scm.com/book/zh/v1/Git-%E5%86%85%E9%83%A8%E5%8E%9F%E7%90%86-Git-%E5%AF%B9%E8%B1%A1

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Git 基礎(chǔ) 基本原理 客戶端并不是只提取最新版本的文件快照,而是把代碼倉(cāng)庫(kù)完整的鏡像下來(lái)。這樣一來(lái),任何一處協(xié)同...
    __silhouette閱讀 16,199評(píng)論 5 147
  • Git 命令行學(xué)習(xí)筆記 Git 基礎(chǔ) 基本原理 客戶端并不是只提取最新版本的文件快照,而是把代碼倉(cāng)庫(kù)完整的鏡像下來(lái)...
    sunnyghx閱讀 4,154評(píng)論 0 11
  • 一、電腦本地初始化一個(gè)倉(cāng)庫(kù) 1. git init: 初始化一個(gè)電腦上本地倉(cāng)庫(kù) 終端進(jìn)入項(xiàng)目目錄,輸入: 該命令將...
    dragon_li閱讀 3,130評(píng)論 1 4
  • 【2016.09.15】 今天中秋節(jié)了。 我在大學(xué)的最后一個(gè)中秋,還是沒(méi)有回家過(guò)。 雖然還是一個(gè)人,今年的中秋還不...
    真的以為閱讀 312評(píng)論 0 0
  • 人與人之間形成差距的最大原因是什么? 出生不好? 專業(yè)不好? 運(yùn)氣不好? 社會(huì)不公平? 太窮了? 我的答案是:求精...
    人隨心動(dòng)2017閱讀 545評(píng)論 0 3

友情鏈接更多精彩內(nèi)容