git內部原理淺見

2021-10-23 05:43:19 字數 3217 閱讀 5653

git物件儲存

git引用

包檔案git gc

git是版本管理工具

git是內容定址檔案系統,其核心部分是乙個簡單的鍵值對資料庫(key-value index),通過sha-1雜湊值來查詢對應的原資料

git儲存的是快照: (每次commit都會儲存整個專案的檔案資料,如果檔案沒有修改則儲存指向原檔案的指標(sha-1值),如果修改則是修改後的檔案(檔案所有內容而不是差分內容))

git儲存的是內容的差分: git會在打包的時候,將所有資料整合,生成資料檔案(pack-***x.pack)和索引檔案(pack-***.idx),在資料檔案中會以差分的形式記錄有修改的檔案,並且最新的是全部檔案內容,之前的原始檔則以差分的形式記錄。

資料物件儲存專案中的單個資料(檔案)

只是單純的記錄資料內容,類似檔案系統的資料塊

可以儲存資料,但是不知道資料是哪個檔案的,只能通過sha-1獲取資料內容,記那麼多40位的sha-1值,是不科學的。

樹物件儲存多個檔案的sha-1值,以及子樹的sha-1值

記錄資料物件的檔名,類似檔案系統的目錄

將資料物件與檔名對應,便於恢復檔案資料,知道哪個blob物件的資料對應哪個檔案了

乙個專案肯定會有各種資料夾,而資料物件不能滿足此要求。

提交物件儲存當前提交時間點專案的所有檔案對應的樹物件,以及父commit物件,提交人,提交時間,提交原因.

樹物件只是記錄專案的資料,無法記錄資料的修改者,修改時間,以及修改原因的資訊

總的來說,資料物件 -> 樹物件 -> 提交物件

資料型別+空格+資料長度+空位元組 -> 頭資訊

頭資訊+資料 -> sha-1校驗和

頭資訊+資料 -> zlib壓縮 -> 磁碟內容(sha-1頭兩位作目錄,後38位作檔名)

檢視某個物件的內容:

git cat-file -p sha-1
引用就是指向commit的標識,也就是分支

對commit進行操作,依舊需要知道該commit對應的sha-1值,而記錄sha-1值是非常麻煩的,所以通過乙個標識(名字)來指向這個sha-1值,就應用而生。

head引用是乙個符號引用(symbolic reference),像linux的軟鏈結(指向鏈結的檔名)

內容:ref: refs/heads/master 意思為當前本地分支為master分支

.git/refs/remote

其內容為某一commit的sha-1值

git儲存的是資料檔案,每次修改後都會儲存乙份新檔案(不管修改多麼小),這樣git倉庫會越來越大,所以需要在git倉庫達到一定規模的時候進行打包操作,以釋放儲存空間,提高查詢效率等。

命令:git gc

最初git向磁碟儲存物件的結構稱為鬆散物件格式,每次修改都會新增乙份完整檔案到磁碟。

打包:將鬆散的物件打包成乙個包檔案(二進位制檔案)和乙個索引檔案(記錄包檔案的偏移量)

在打包後,修改的檔案會以差分的形式儲存在包檔案中,最新的物件儲存完整的資料,以前的原始檔則以差分的形式儲存。

這是基於以下考慮

一般情況下,都會檢視最新的資料,保證查詢效率

(純屬猜測)在對檔案進行還原的時候,從最新檔案進行回退可以還原檔案,假設初始檔案記錄全部資料,每次修改記錄差分,則還原檔案的時候,則需要從初始檔案應用一系列之前的差分才能得到檔案,當乙個檔案修改履歷較長時,這無疑會進行複雜的運算。

建立分支 -> 建立乙個引用,然後內容(sha-1)指向你想切到的commit點。預設值為head的值

切換分支-> 將當前分支的內容修改為目標commit點的sha-1值。然後讀取對應commit物件中樹物件以及資料物件的內容,並替換當前工作空間的檔案。

counting objects: 23, done. :倉庫所有的物件(commit tree blob)

delta compression using up to 4 threads.(作增量的物件,原理不懂,可通過git verify-pack -v .git/objects/pack/pack-***.idx檢視)

compressing objects: 100% (11/11), done.(增量壓縮物件,沒整明白delte,所以這個算不明白)

writing objects: 100% (23/23), done. 寫入包檔案的物件

total 23 (delta 4), reused 23 (delta 4) reused是之前已經有的對

象git push 的時候會先執行git gc 然後將包檔案通過網路傳到遠端

counting objects: 3, done.

delta compression using up to 4 threads.

compressing objects: 100% (2/2), done.

writing objects: 100% (3/3), 260 bytes | 260.00 kib/s, done.

total 3 (delta 1), reused 0 (delta 0)

git clone 的時候會在遠端執行git gc 然後傳包檔案過來,如下

remote: enumerating objects: 15, done.

remote: counting objects: 100% (15/15), done.

remote: compressing objects: 100% (11/11), done.

remote: total 15 (delta 2), reused 0 (delta 0), pack-reused 0

unpacking objects: 100% (15/15), done.

remote: enumerating objects -> 遠端操作:列舉物件,本地和遠端相差的object -> frontier邊界(會找到新加commit的父commit(遠端已經存在的commit))- > 確定那些是新加的

git內部原理

從根本上來講 git 是乙個內容定址 content addressable 檔案系統,並在此之上提供了乙個版本控制系統的使用者介面。git 的核心部分是乙個簡單的鍵值對資料庫 key value data store 你可以向該資料庫插入任意型別的內容,它會返回乙個鍵值,通過該鍵值可以在任意時刻再...

AsyncTask原理淺見

asynctask的基原理是建立乙個執行緒池,通過執行緒池執行乙個runnable物件 futuretask 然後通過handler通知ui執行緒。1 執行緒池的建立。建立執行緒池,並返回乙個執行器物件 executor private static final int core pool size...

Git 內部原理之 Git 物件雜湊

git中的資料物件 樹物件和提交物件的hash方法原理是一樣的,可以描述為 header content.length 0 hash sha1 header content 上面公式表示,git在計算物件hash時,首先會在物件頭部新增乙個header。這個header由3部分組成 第一部分表示物件...