.git的數(shù)據(jù)結(jié)構(gòu)一

本文主要探討git 的add commit 操作的數(shù)據(jù)是如何進行記錄的

1. 新建一個git倉庫

chuangchuang@chuang:~/work/temp$ cd gittest/
chuangchuang@chuang:~/work/temp/gittest$ ll
總用量 8
drwxrwxr-x 2 chuangchuang chuangchuang 4096 11月 11 18:20 ./
drwxrwxr-x 4 chuangchuang chuangchuang 4096 11月 11 18:20 ../
chuangchuang@chuang:~/work/temp/gittest$ git init
初始化空的 Git 倉庫于 /home/chuangchuang/work/temp/gittest/.git/
chuangchuang@chuang:~/work/temp/gittest$ 
chuangchuang@chuang:~/work/temp/gittest$ ll
總用量 12
drwxrwxr-x 3 chuangchuang chuangchuang 4096 11月 11 18:21 ./
drwxrwxr-x 4 chuangchuang chuangchuang 4096 11月 11 18:20 ../
drwxrwxr-x 7 chuangchuang chuangchuang 4096 11月 11 18:21 .git/

2.看一下.git的結(jié)構(gòu)

chuangchuang@chuang:~/work/temp/gittest$ tree .git/
.git/
├── branches
├── config
├── description
├── HEAD
├── hooks
│   ├── applypatch-msg.sample
│   ├── commit-msg.sample
│   ├── post-update.sample
│   ├── pre-applypatch.sample
│   ├── pre-commit.sample
│   ├── prepare-commit-msg.sample
│   ├── pre-push.sample
│   ├── pre-rebase.sample
│   └── update.sample
├── info
│   └── exclude
├── objects
│   ├── info
│   └── pack
└── refs
    ├── heads
    └── tags

9 directories, 13 files

3,添加一些東西

3.1 剛開始的時候并沒有在路徑上顯示分支门岔,即使使用git branch -a 也沒有

chuangchuang@chuang:~/work/temp/gittest$ git branch -a     
chuangchuang@chuang:~/work/temp/gittest$ 

3.2 在往里面添加過文件

chuangchuang@chuang:~/work/temp/gittest$ touch aa.txt  //1
chuangchuang@chuang:~/work/temp/gittest$ ll         //2
總用量 12
drwxrwxr-x 3 chuangchuang chuangchuang 4096 11月 11 19:00 ./
drwxrwxr-x 4 chuangchuang chuangchuang 4096 11月 11 18:20 ../
-rw-rw-r-- 1 chuangchuang chuangchuang    0 11月 11 19:00 aa.txt
drwxrwxr-x 7 chuangchuang chuangchuang 4096 11月 11 19:00 .git/

3.3 查看.git目錄(只有objects目錄有變化)

├── objects
│   ├── e6
│   │   └── 9de29bb2d1d6434b8b29ae775ad8c2e48c5391
│   ├── info
│   └── pack

這個時候發(fā)現(xiàn)在objects下面多了一個id e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
查看該文件下有什么

chuangchuang@chuang:~/work/temp/gittest[master*]$ git cat-file -p e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
chuangchuang@chuang:~/work/temp/gittest[master*]$ 
//顯示的是什么都沒有寒随,這個是add 添加到stage區(qū)的文件妻往,因為是空文件试和,所以沒有內(nèi)容

3.4 執(zhí)行了commit 操作以后就有了分支

chuangchuang@chuang:~/work/temp/gittest$ git add aa.txt   //1
chuangchuang@chuang:~/work/temp/gittest$ git commit -a -m "aa.txt tianjia"  //2
[master (根提交) a3c8eff] aa.txt tianjia
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 aa.txt
// 接下來的路徑中就顯示了master分支
chuangchuang@chuang:~/work/temp/gittest[master*]$ ll   //3
總用量 12
drwxrwxr-x 3 chuangchuang chuangchuang 4096 11月 11 19:00 ./
drwxrwxr-x 4 chuangchuang chuangchuang 4096 11月 11 18:20 ../
-rw-rw-r-- 1 chuangchuang chuangchuang    0 11月 11 19:00 aa.txt
drwxrwxr-x 8 chuangchuang chuangchuang 4096 11月 11 19:00 .git/

4阅悍,再次看看.git中都有寫什么

.git
├── branches
├── objects
│   ├── a3
│   │   └── c8effc24eeb66de97a66b073c6d62c48fbc9ed
│   ├── e6
│   │   └── 9de29bb2d1d6434b8b29ae775ad8c2e48c5391
│   ├── f1
│   │   └── 3f51556efabe074d5b255eabcdd3ec33520c55
│   ├── info
│   └── pack
└── refs
    ├── heads
    │   └── master
    └── tags

4.1 可以看到object中多了兩個目錄节视,每個目錄下多了一個文件,這個其實就是每次操作的hash值
執(zhí)行g(shù)it log 看看當前有多少提交

chuangchuang@chuang:~/work/temp/gittest[master*]$ git log -1 --pretty=raw  //注意這里的是 -1 是數(shù)字不是字母
commit a3c8effc24eeb66de97a66b073c6d62c48fbc9ed
tree f13f51556efabe074d5b255eabcdd3ec33520c55
author chuang <chuangchuang.chen@cafintech.com> 1510398041 +0800
committer chuang <chuangchuang.chen@cafintech.com> 1510398041 +0800

    aa.txt tianjia
chuangchuang@chuang:~/work/temp/gittest[master*]$ git version

可以看到有一個commit id ,是 a3c8effc24eeb66de97a66b073c6d62c48fbc9ed
還有一個是本次操作的快照id f13f51556efabe074d5b255eabcdd3ec33520c55
使用git cat-file解壓文件看一下

//可以看到這個里面存儲的就是commit 提交的時候填入的信息
chuangchuang@chuang:~/work/temp/gittest[master*]$ git cat-file -p a3c8effc24eeb66de97a66b073c6d62c48fbc9ed
tree f13f51556efabe074d5b255eabcdd3ec33520c55
author chuang <chuangchuang.chen@cafintech.com> 1510398041 +0800
committer chuang <chuangchuang.chen@cafintech.com> 1510398041 +0800

aa.txt tianjia

// 這個tree中存放的也是一個引用,指向了真正存放文件內(nèi)容 的文件
chuangchuang@chuang:~/work/temp/gittest[master*]$ git cat-file -p f13f51556efabe074d5b255eabcdd3ec33520c55
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391    aa.txt

//因為這個文件剛剛創(chuàng)建,什么都沒有
chuangchuang@chuang:~/work/temp/gittest[master*]$ git cat-file -p e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
chuangchuang@chuang:~/work/temp/gittest[master*]$ 

//查看一下倉庫中的文件記錄,就是最開始add的那個id

chuangchuang@chuang:~/work/temp/gittest[master*]$ git ls-tree -l HEAD
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391       0    aa.txt

可以看到文件記錄是e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
這個代表了倉庫中存儲的該原始文件

5 執(zhí)行g(shù)it add 操作后的結(jié)構(gòu)

chuangchuang@chuang:~/work/temp/gittest[master*]$  echo '1 di yi ci wang li tian jia nei rong' >> aa.txt 
chuangchuang@chuang:~/work/temp/gittest[master*]$ git add .
chuangchuang@chuang:~/work/temp/gittest[master*]$ git status
位于分支 master
要提交的變更:
  (使用 "git reset HEAD <文件>..." 以取消暫存)

    修改:     aa.txt

這個時候再看


chuangchuang@chuang:~/work/temp/gittest[master*]$ tree .git/
.git/
├── branches
├── objects
│   ├── a3
│   │   └── c8effc24eeb66de97a66b073c6d62c48fbc9ed
│   ├── e4
│   │   └── 626567ec9ae5a6f3abd77af37c25a85ec4e7f1
│   ├── e6
│   │   └── 9de29bb2d1d6434b8b29ae775ad8c2e48c5391
│   ├── f1
│   │   └── 3f51556efabe074d5b255eabcdd3ec33520c55
│   ├── info
│   └── pack


可以看到多了一個文件
e4626567ec9ae5a6f3abd77af37c25a85ec4e7f1
通過list-files 查看緩存區(qū)的文件

chuangchuang@chuang:~/work/temp/gittest[master*]$ git ls-files -s
100644 e4626567ec9ae5a6f3abd77af37c25a85ec4e7f1 0   aa.txt

6牙丽,再次執(zhí)行g(shù)it commit 后的結(jié)果

6.1 執(zhí)行commit

chuangchuang@chuang:~/work/temp/gittest[master*]$ git commit -a -m "di er ci ti jiao test"
[master 45776d6] di er ci ti jiao test
 1 file changed, 1 insertion(+)

6.2 查看.git 的object目錄為(截取了一部分)

              
├── objects
│   ├── 45
│   │   └── 776d6cb67571cfe31656fb1d114e520c9e0ab2
│   ├── 68
│   │   └── d98b1781c29d1df8b4ac7b6d457bccecf9756e
│   ├── a3
│   │   └── c8effc24eeb66de97a66b073c6d62c48fbc9ed
│   ├── e4
│   │   └── 626567ec9ae5a6f3abd77af37c25a85ec4e7f1
│   ├── e6
│   │   └── 9de29bb2d1d6434b8b29ae775ad8c2e48c5391
│   ├── f1
│   │   └── 3f51556efabe074d5b255eabcdd3ec33520c55
│   ├── info
│   └── pack

可以看到又多了兩條記錄
6.3 通過git log查看commit

chuangchuang@chuang:~/work/temp/gittest[master*]$ git log -2 --pretty=raw
commit 45776d6cb67571cfe31656fb1d114e520c9e0ab2  //這個是第二次提交產(chǎn)生的commit id
tree 68d98b1781c29d1df8b4ac7b6d457bccecf9756e     // 這個是第二次提交產(chǎn)生的快照
parent a3c8effc24eeb66de97a66b073c6d62c48fbc9ed
author chuang <chuangchuang.chen@cafintech.com> 1510452772 +0800
committer chuang <chuangchuang.chen@cafintech.com> 1510452772 +0800

    di er ci ti jiao test

commit a3c8effc24eeb66de97a66b073c6d62c48fbc9ed
tree f13f51556efabe074d5b255eabcdd3ec33520c55
author chuang <chuangchuang.chen@cafintech.com> 1510398041 +0800
committer chuang <chuangchuang.chen@cafintech.com> 1510398041 +0800

    aa.txt tianjia

6.3.1 git log 分析

45776d6cb67571cfe31656fb1d114e520c9e0ab2 是這次commit 產(chǎn)生的commit id
68d98b1781c29d1df8b4ac7b6d457bccecf9756e 是本次提交的快照
parent a3c8effc24eeb66de97a66b073c6d62c48fbc9ed 表明了上次提交的 commit id 是a3c8effc24eeb66de97a66b073c6d62c48fbc9ed 對應(yīng)了第一次提交的commit id

6.3.2 查看當前本地倉庫的文件

chuangchuang@chuang:~/work/temp/gittest[master*]$ git ls-tree -l HEAD
100644 blob e4626567ec9ae5a6f3abd77af37c25a85ec4e7f1      37    aa.txt

是保存id 為e4626567ec9ae5a6f3abd77af37c25a85ec4e7f1 的文件
這個對應(yīng)了5中add操作在object目錄下產(chǎn)生的id,說明這個時候已經(jīng)從暫存區(qū)(stage)進入了倉庫

6.3.3 分析這些id之間的關(guān)系

//這里可以看出拍棕,commit id中存儲的就是 commit的時候填寫進去的信息
chuangchuang@chuang:~/work/temp/gittest[master*]$ git cat-file -p 45776d6cb67571cfe31656fb1d114e520c9e0ab2
tree 68d98b1781c29d1df8b4ac7b6d457bccecf9756e
parent a3c8effc24eeb66de97a66b073c6d62c48fbc9ed
author chuang <chuangchuang.chen@cafintech.com> 1510452772 +0800
committer chuang <chuangchuang.chen@cafintech.com> 1510452772 +0800

di er ci ti jiao test

// tree中記錄的依然是一個指針勺良,指向了blob類型的  e4626567ec9ae5a6f3abd77af37c25a85ec4e7f1
chuangchuang@chuang:~/work/temp/gittest[master*]$ git cat-file -p 68d98b1781c29d1df8b4ac7b6d457bccecf9756e
100644 blob e4626567ec9ae5a6f3abd77af37c25a85ec4e7f1    aa.txt

//可以看到這個里面存儲的是真正的文件內(nèi)容尚困,也就是add操作產(chǎn)生的id
chuangchuang@chuang:~/work/temp/gittest[master*]$ git cat-file -p e4626567ec9ae5a6f3abd77af37c25a85ec4e7f1
1 di yi ci wang li tian jia nei rong

7 ,一次添加多個文件

7.1 兩次修改原來的aa.txt

//第一次操作谬泌,修改aa.txt 會產(chǎn)生一個新的index id
chuangchuang@chuang:~/work/temp/tempgit[dev*]$ echo 'another test san'>> aa.txt 
chuangchuang@chuang:~/work/temp/tempgit[dev*]$ cat aa.txt 
1 di yi ci wang li tian jia nei rong
another test san
chuangchuang@chuang:~/work/temp/tempgit[dev*]$ git add .
chuangchuang@chuang:~/work/temp/tempgit[dev*]$ git ls-files -s
100644 5c3079aa5ec819e560b4b548e0ea4efb39be239f 0   aa.txt
chuangchuang@chuang:~/work/temp/tempgit[dev*]$ git cat-file -p 5c3079aa5ec819e560b4b548e0ea4efb39be239f

//第二次操作修改 aa.txt 會產(chǎn)生新的 index id
chuangchuang@chuang:~/work/temp/tempgit[dev*]$ echo 'third test'>>aa.txt
chuangchuang@chuang:~/work/temp/tempgit[dev*]$ cat aa.txt 
1 di yi ci wang li tian jia nei rong
another test san
third test
chuangchuang@chuang:~/work/temp/tempgit[dev*]$ git add .
chuangchuang@chuang:~/work/temp/tempgit[dev*]$ git ls-files -s
100644 658bed4dcaeec2c18e04af192971e7093b3c7ab9 0   aa.txt




7.2 添加3個文件掌实,

//添加bb.txt
chuangchuang@chuang:~/work/temp/tempgit[dev*]$ touch bb.txt
chuangchuang@chuang:~/work/temp/tempgit[dev*]$ echo 'bb text'>> bb.txt 

//添加cc.txt dd.txt
chuangchuang@chuang:~/work/temp/tempgit[dev*]$ vi cc.txt
chuangchuang@chuang:~/work/temp/tempgit[dev*]$ 
chuangchuang@chuang:~/work/temp/tempgit[dev*]$ vi dd.txt

7.3 查看緩沖區(qū)index

chuangchuang@chuang:~/work/temp/tempgit[dev*]$ git ls-files -s
100644 658bed4dcaeec2c18e04af192971e7093b3c7ab9 0   aa.txt
100644 90593bc026fb525e8bf56485d3101a389dac4417 0   bb.txt
100644 9af3475341efe72b1fc0b4109055436b2700c1b9 0   cc.txt
100644 f224fbe59efc4467313afe938f836488d84ff3b3 0   dd.txt

可以看到每個文件分別有一條

7.4 執(zhí)行commit之后的git log結(jié)構(gòu)
commit

chuangchuang@chuang:~/work/temp/tempgit[dev*]$ git commit -m "一次提交了四個"
[dev d4a8da9] 一次提交了四個
 4 files changed, 5 insertions(+)
 create mode 100644 bb.txt
 create mode 100644 cc.txt
 create mode 100644 dd.txt


查看倉庫

chuangchuang@chuang:~/work/temp/tempgit[dev*]$ git ls-tree -l HEAD
100644 blob 658bed4dcaeec2c18e04af192971e7093b3c7ab9      65    aa.txt
100644 blob 90593bc026fb525e8bf56485d3101a389dac4417       8    bb.txt
100644 blob 9af3475341efe72b1fc0b4109055436b2700c1b9      12    cc.txt
100644 blob f224fbe59efc4467313afe938f836488d84ff3b3       8    dd.txt
chuangchuang@chuang:~/work/temp/tempgit[dev*]$ 

查看日志

chuangchuang@chuang:~/work/temp/tempgit[dev*]$ git log -1 --pretty=raw
commit d4a8da99076957a318aafff68fab06f81862fafc
tree bfdc957c7bb165a8f53c13b49261c683ca5c8c7f
parent 45776d6cb67571cfe31656fb1d114e520c9e0ab2
author chuang <chuangchuang.chen@cafintech.com> 1510484509 +0800
committer chuang <chuangchuang.chen@cafintech.com> 1510484509 +0800

7.5 分別看看該次commit的 log 記錄對應(yīng)結(jié)構(gòu)
查看commit

chuangchuang@chuang:~/work/temp/tempgit[dev*]$ git cat-file -p d4a8da99076957a318aafff68fab06f81862fafc
tree bfdc957c7bb165a8f53c13b49261c683ca5c8c7f
parent 45776d6cb67571cfe31656fb1d114e520c9e0ab2
author chuang <chuangchuang.chen@cafintech.com> 1510484509 +0800
committer chuang <chuangchuang.chen@cafintech.com> 1510484509 +0800

一次提交了四個

查看 commit對應(yīng)的tree,也就是當次操作的快照

chuangchuang@chuang:~/work/temp/tempgit[dev*]$ git cat-file -p bfdc957c7bb165a8f53c13b49261c683ca5c8c7f
100644 blob 658bed4dcaeec2c18e04af192971e7093b3c7ab9    aa.txt
100644 blob 90593bc026fb525e8bf56485d3101a389dac4417    bb.txt
100644 blob 9af3475341efe72b1fc0b4109055436b2700c1b9    cc.txt
100644 blob f224fbe59efc4467313afe938f836488d84ff3b3    dd.txt

可以看到滋将,這里的快照的id關(guān)聯(lián)的 index的id是剛才add操作產(chǎn)生的四個id

8 總結(jié)

git的數(shù)據(jù)信息的管理都是在.git/objects目錄下進行管理的

git的add

  1. 會在object下
    為每一個變化的文件產(chǎn)生一個壓縮文件來記錄改變后的文件(是改變后的完整文件)

commit 操作

  1. 產(chǎn)生一個commit id記錄本次commit的一些描述性信息
  2. 產(chǎn)生一個關(guān)聯(lián)commit的快照信息的文件
  3. 2中產(chǎn)生的文件內(nèi)容包含指向add產(chǎn)生的壓縮文件的指針
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末随闽,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子蛾扇,更是在濱河造成了極大的恐慌添诉,老刑警劉巖医寿,帶你破解...
    沈念sama閱讀 222,590評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件靖秩,死亡現(xiàn)場離奇詭異,居然都是意外死亡花颗,警方通過查閱死者的電腦和手機扩劝,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來聂示,“玉大人簇秒,你說我怎么就攤上這事趋观。” “怎么了编曼?”我有些...
    開封第一講書人閱讀 169,301評論 0 362
  • 文/不壞的土叔 我叫張陵灵巧,是天一觀的道長抹沪。 經(jīng)常有香客問我,道長敏弃,這世上最難降的妖魔是什么噪馏? 我笑而不...
    開封第一講書人閱讀 60,078評論 1 300
  • 正文 為了忘掉前任欠肾,我火速辦了婚禮,結(jié)果婚禮上粹淋,老公的妹妹穿的比我還像新娘。我一直安慰自己屋匕,他們只是感情好借杰,可當我...
    茶點故事閱讀 69,082評論 6 398
  • 文/花漫 我一把揭開白布蔗衡。 她就那樣靜靜地躺著,像睡著了一般廓推。 火紅的嫁衣襯著肌膚如雪翩隧。 梳的紋絲不亂的頭發(fā)上堆生,一...
    開封第一講書人閱讀 52,682評論 1 312
  • 那天,我揣著相機與錄音涝婉,去河邊找鬼蔗怠。 笑死寞射,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的引矩。 我是一名探鬼主播侵浸,決...
    沈念sama閱讀 41,155評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼掏觉,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了织盼?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,098評論 0 277
  • 序言:老撾萬榮一對情侶失蹤晚吞,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后迁沫,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體集畅,經(jīng)...
    沈念sama閱讀 46,638評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡挺智,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,701評論 3 342
  • 正文 我和宋清朗相戀三年赦颇,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片媒怯。...
    茶點故事閱讀 40,852評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡扇苞,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出脖苏,到底是詐尸還是另有隱情定踱,我是刑警寧澤,帶...
    沈念sama閱讀 36,520評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站至扰,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏敢课。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,181評論 3 335
  • 文/蒙蒙 一鞭盟、第九天 我趴在偏房一處隱蔽的房頂上張望瑰剃。 院中可真熱鬧齿诉,春花似錦、人聲如沸晌姚。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽挥唠。三九已至抵恋,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間宝磨,已是汗流浹背弧关。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留唤锉,地道東北人世囊。 一個月前我還...
    沈念sama閱讀 49,279評論 3 379
  • 正文 我出身青樓腌紧,卻偏偏與公主長得像茸习,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子壁肋,可洞房花燭夜當晚...
    茶點故事閱讀 45,851評論 2 361

推薦閱讀更多精彩內(nèi)容