
Git是一個開源的分布式版本控制系統,是目前主流的版本控制系統,很多軟體專案都會用它做源代碼管理,Git的常用操作想必很多人都會,但是可能了解Git內部原理的人并不多,了解一些底層的東西,可以更好的幫你理清思路,遇到問題的時候也可以更好的去解決,
準備作業
在介紹Git如何存盤資料之前,我們先做一些準備作業,
首先新建一個目錄git-test,然后在這個目錄右鍵,打開Git Bash,

然后,在Git Bash,分別執行以下命令,
$ git init
$ echo 'a' > a.txt
$ echo 'b' > b.txt
$ git add .
至此,準備作業完成,我們可以看到,git-test目錄下現在有一個.git目錄,以及兩個txt檔案(a.txt、b.txt),

Git如何存盤資料
.git目錄是git init后在當前目錄生成的一個管理git倉庫的目錄,這里包含所有git操作所需要的東西,其中objects目錄下存放所有的git物件,經過上面的操作后,objects目錄是這樣的,

其中info和pack目錄是執行git init以后就已經有的,而78和61目錄分別對應著a.txt和b.txt檔案,這兩個目錄是創建了a.txt和b.txt,并執行git add .命令后才生成的,
78目錄下有一個檔案,查看一下這個檔案的內容,執行以下命令,
$ cat .git/objects/78/981922613b2afb6025042ff6bd878ac1994e85

我們看到檔案的內容是一串亂碼,這是因為Git將資訊壓縮成二進制,Git提供了一個能夠幫助探索objects的命令:git cat-file [-t] [-p], -t可以查看object的型別,-p可以查看object存盤的具體內容,分別執行以下命令,
$ git cat-file -t 7898
$ git cat-file -p 7898

blob型別的object
7898就是目錄名加上檔案名的前兩位,可以看到,這個object是一個blob型別的object,而這個object存盤的內容,就是我們寫入到a.txt的文本,因此,上面的亂碼其實就是a.txt的內容,也就是說,這個object存盤著a.txt檔案的內容,
blob型別的object存盤的是一個檔案的內容,然后,Git根據這個檔案的內容經過SHA1哈希演算法得到對應的哈希值(981922613b2afb6025042ff6bd878ac1994e85),作為這個object在Git倉庫中的唯一id,現在的Git倉庫是這樣子的,如圖:

tree型別的object
接著執行下一個命令,
$ git commit -m '第一次提交'
執行git commit命令后,objects目錄下又多出了兩個object,如圖:

首先,用git cat-file -t命令查看f4目錄下object的型別,如圖:

可以看到,這個object的型別是tree,利用git cat-file -p命令查看這個object的內容,如圖:

可以看到,tree型別的object存盤了一個目錄結構的快照,從左到右分別顯示了每個檔案的權限、型別、object的id(SHA1值)、以及檔案名,現在的Git倉庫是這樣子的,如圖:

commit型別的object
用同樣的方法,查看3c目錄下的檔案,如圖:

這是一個commit型別的object,而這個object存盤了一個tree型別的object的id,以及提交的一些資訊,現在的Git倉庫是這樣子的,如圖:

分支
實際做專案都會有很多分支,Git的分支資訊就存盤在/.git/refs/heads目錄下,如圖:

因為現在只有一個master分支,所以只有一個master檔案,直接打開master這個檔案,可以看到這個檔案存盤了3c0acd6df4df30074678a2b97967a82efd9c8acf這樣一串字串,這正是上面的commit型別object的id,現在的Git倉庫是這樣子的,如圖:

HEAD
在/.git/HEAD這個檔案下,記錄內容如下:
ref: refs/heads/master
這個內容告訴Git當前修改的內容是基于哪個分支上的,我們可以理解為這是一個指標,現在的Git倉庫是這樣子的,如圖:

至此,一個完整的Git存盤結構就出來了,
Git的三個磁區
Git有3個磁區,分別是作業區、暫存區和版本庫,
作業區: 就是專案所在目錄(除去.git目錄),所有代碼編輯都在這上面完成,
暫存區: 英文叫 stage 或 index,一般存放在 .git 目錄下的 index 檔案(.git/index)中,所以我們把暫存區有時也叫作索引(index),
Git倉庫: 由Git object記錄著每一次提交的快照,以及鏈式結構記錄的提交變更歷史,
有了3個磁區,整個結構如下圖:

Git的內部運作
現在,我們嘗試修改a.txt檔案,如圖:

這時候,除了作業目錄下的a.txt檔案內容有變化,暫存區和Git倉庫都是沒有變化的,接著,執行git add a.txt命令,這時/.git/objects目錄下又多了一個物件,如圖:

這個新增的object也是blob型別,對應著新修改的a.txt檔案,這時,整個結構如下圖:

最后,我們執行git commit -m '修改a.txt'命令,不出意外,/.git/objects目錄會生成兩個object,根據上面的介紹,這兩個object分別是tree和commit型別,如圖:

這時,整個結構如下圖:

從上圖可以看到,master分支已經指向新的commit object,并且新的commit object記錄著它的parent object,也就是舊的那個commit object,這使得我們可以查看Git的提交歷史,
本文來自博客園,作者:Yi00,轉載請注明原文鏈接:https://www.cnblogs.com/ayic/p/16678252.html
聊聊技術,聊聊人生,歡迎關注我的公眾號!^_^
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/539161.html
標籤:其他
上一篇:OpenCV3影像處理筆記
