[TOC] #### 1. 前言 --- 我使用的是 mac 系統(tǒng),本文用到 `tree`、`watch` 命令,mac 默認(rèn)是沒有這兩個(gè)命令的,需要先安裝下這兩個(gè)命令 ``` brew install tree && brew install watch ``` #### 2. git 是如何保存代碼的 --- **一、git 在 add 時(shí),會(huì)將文件的內(nèi)容通過Hash SHA-1算法生成一個(gè)基于Hash值的鍵值對(duì)數(shù)據(jù)庫** 參考 git 中文書籍`git對(duì)象`章節(jié): [https://www.progit.cn/#_objects](https://www.progit.cn/#_objects) 監(jiān)聽文件變化可使用命令(每隔一秒執(zhí)行 tree .git 命令): ``` watch -n -1 -d tree .git ``` 創(chuàng)建 `hello.txt` 文件,文件內(nèi)容: `hello git` ``` echo 'hello git' > hello.txt ``` 將文件添加到暫存區(qū), 此時(shí) `.git/objects` 下面會(huì)多出一個(gè)目錄,這個(gè)目錄下存放一個(gè)文件 git 會(huì)根據(jù)文件內(nèi)容通過 hash sha-1 算法得到40位的 blob對(duì)象 hash字符串文件 示例: `8d0e41234f24b6da002d962a26c2495ea16a425f`, 前兩位作為目錄名,后38位作為文件名進(jìn)行存儲(chǔ) 這個(gè)文件存儲(chǔ)的就是 hello.txt 的文件內(nèi)容: `hello git`, 下面就來驗(yàn)證這句話 ``` git add hello.txt ``` ![](https://img.itqaq.com/art/content/33d02328ed22aa83adda10be181ce06d.png) 使用 `cat` 查看 hash 串存儲(chǔ)的文件內(nèi)容,看到是一串亂碼,這個(gè)是文件經(jīng)過`zlib` 壓縮后的數(shù)據(jù) ``` cat .git/objects/xx/xxxx ``` ![](https://img.itqaq.com/art/content/aac54ae51e3f321d7ce985cb72198c8d.png) 查看文件的原始內(nèi)容,壓縮前的數(shù)據(jù): 語法格式: `git cat-file -p 索引值前七位` cat: 可以理解查看 -p: pretty 漂亮的,理解為便于查看的 ``` git cat-file -p 8d0e412 ``` ![](https://img.itqaq.com/art/content/b7e828638efe7d167719eeafd27813d3.png) 查看文件類型,執(zhí)行以下命令返回 `blob` 代表是 `blob對(duì)象` ``` git cat-file -t 8d0e412 ``` 查看文件內(nèi)容長度(例如: 10) ``` git cat-file -s 8d0e412 ``` #### 3. hash 算法 --- hash算法: 將任意長度的內(nèi)容通過算法生成固定長度的輸出,也就是加密為固定長度的字符串 git 是一個(gè)基于Hash值的鍵值對(duì)數(shù)據(jù)庫,鍵指的是`hash索引值`,值指的 `hash索引值對(duì)應(yīng)的文件內(nèi)容` 總結(jié): git 的核心一個(gè)鍵值對(duì)數(shù)據(jù)庫,里面有一種叫 `blob` 的數(shù)據(jù)對(duì)象負(fù)責(zé)存儲(chǔ)壓縮后的代碼 具體算法,使用算法生成 hash 字符串 語法格式 ``` 'blob 長度\0內(nèi)容' ``` 使用示例 + 10: 是文件的長度, 除了hello git 9個(gè)字符外, 還有一個(gè)\n, 所以長度為10 + hello git 是文件的內(nèi)容 + sha1sum: 是Linux自帶的計(jì)算Hash串的命令 ``` echo 'blob 10\0hello git' | shasum ``` ``` 注意 如果在windows下, 可能會(huì)得到不同的結(jié)果. 因?yàn)樵趙indows下, 文件的末尾添加的是 CRLF 也就是 \r\n, 而 Linux下只有 \n 因此, 可能會(huì)得出不一樣的結(jié)果 ``` #### 4. 暫存區(qū) --- 暫存區(qū)所在位置: `.git/index` 暫存區(qū)可以看做一個(gè)文件名到 blob 對(duì)象的索引表,這也是為什么暫存區(qū)叫 `index` 的原因 查看暫存區(qū)中的數(shù)據(jù) ``` git ls-files -s ```