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