.git的数据结构一

本文主要探讨git 的add commit 操作的数据是如何进行记录的

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的结构

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

这个时候发现在objects下面多了一个id e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
查看该文件下有什么

chuangchuang@chuang:~/work/temp/gittest[master*]$ git cat-file -p e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
chuangchuang@chuang:~/work/temp/gittest[master*]$ 
//显示的是什么都没有,这个是add 添加到stage区的文件,因为是空文件,所以没有内容

3.4 执行了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值
执行git log 看看当前有多少提交

chuangchuang@chuang:~/work/temp/gittest[master*]$ git log -1 --pretty=raw  //注意这里的是 -1 是数字不是字母
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中存放的也是一个引用,指向了真正存放文件内容 的文件
chuangchuang@chuang:~/work/temp/gittest[master*]$ git cat-file -p f13f51556efabe074d5b255eabcdd3ec33520c55
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391    aa.txt

//因为这个文件刚刚创建,什么都没有
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 执行git add 操作后的结构

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 查看缓存区的文件

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

6,再次执行git commit 后的结果

6.1 执行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  //这个是第二次提交产生的commit id
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

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 产生的commit id
68d98b1781c29d1df8b4ac7b6d457bccecf9756e 是本次提交的快照
parent a3c8effc24eeb66de97a66b073c6d62c48fbc9ed 表明了上次提交的 commit id 是a3c8effc24eeb66de97a66b073c6d62c48fbc9ed 对应了第一次提交的commit id

6.3.2 查看当前本地仓库的文件

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

是保存id 为e4626567ec9ae5a6f3abd77af37c25a85ec4e7f1 的文件
这个对应了5中add操作在object目录下产生的id,说明这个时候已经从暂存区(stage)进入了仓库

6.3.3 分析这些id之间的关系

//这里可以看出,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

//可以看到这个里面存储的是真正的文件内容,也就是add操作产生的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 会产生一个新的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 会产生新的 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 查看缓冲区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 执行commit之后的git log结构
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 记录对应结构
查看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对应的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关联的 index的id是刚才add操作产生的四个id

8 总结

git的数据信息的管理都是在.git/objects目录下进行管理的

git的add

  1. 会在object下
    为每一个变化的文件产生一个压缩文件来记录改变后的文件(是改变后的完整文件)

commit 操作

  1. 产生一个commit id记录本次commit的一些描述性信息
  2. 产生一个关联commit的快照信息的文件
  3. 2中产生的文件内容包含指向add产生的压缩文件的指针
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,724评论 6 479
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,104评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,142评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,086评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,076评论 5 370
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,914评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,220评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,871评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,318评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,834评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,951评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,574评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,162评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,162评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,383评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,349评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,652评论 2 343

推荐阅读更多精彩内容