GIT中数据的存储与组织

GIT中数据的存储与组织

我们经常使用一些Git的命令,例如checkoutcommit等命令,这些都是高级命令,有一些比较底层的命令,对我们查看数据很有帮助

命令说明
git hash-object存储数据对象
find .git/objects -type f查看objects目录下的文件
git cat-file -p [hashcode]显示存储的内容

GIT的数据目录

### 初始化Git仓库
$ git init

$ cd .git

$ ll
total 24
-rw-r--r--   1 sparrow  staff    23B 12 24 16:01 HEAD
drwxr-xr-x   2 sparrow  staff    64B 12 24 16:01 branches
-rw-r--r--   1 sparrow  staff   137B 12 24 16:01 config
-rw-r--r--   1 sparrow  staff    73B 12 24 16:01 description
drwxr-xr-x  13 sparrow  staff   416B 12 24 16:01 hooks
drwxr-xr-x   3 sparrow  staff    96B 12 24 16:01 info
drwxr-xr-x   4 sparrow  staff   128B 12 24 16:01 objects
drwxr-xr-x   4 sparrow  staff   128B 12 24 16:01 refs

重要的目录列表:

目录名目录作用
HEAD指向目前被检出的分支
index文件保存暂存区的信息
objects存储所有数据内容
refs目录存储指向数据(分支)的提交对象的指针

GIT数据的存储

如何存储文件
# sparrow @ localhost in ~/Documents/learning/test on git:master o [16:07:34] C:1
$ find .git/objects -type f

# sparrow @ localhost in ~/Documents/learning/test on git:master o [16:07:47]
$ echo '测试内容' | git hash-object -w --stdin
a936e260776b0c97788d90fb9e87e133c6401364

# sparrow @ localhost in ~/Documents/learning/test on git:master o [16:09:16]
$ find .git/objects -type f
.git/objects/a9/36e260776b0c97788d90fb9e87e133c6401364

# sparrow @ localhost in ~/Documents/learning/test on git:master o [16:09:21]
$ git cat-file -p a936e260776b0c97788d90fb9e87e133c6401364
测试内容

我们可以看到数据的存储方式:一个文件对应一条内容,以该内容加上特定头部信息一起的 SHA-1 校验和为文件命名。校验和的前两个字符用于命名子目录,余下的 38 个字符则用作文件名。

如何存储变更的文件
# sparrow @ localhost in ~/Documents/learning/test on git:master o [17:26:43]
$ echo '1111' > 1.txt

# sparrow @ localhost in ~/Documents/learning/test on git:master x [17:29:38]
$ git hash-object -w 1.txt
5f2f16bfff90e6620509c0cf442e7a3586dad8fb

# sparrow @ localhost in ~/Documents/learning/test on git:master x [17:29:45]
$ find .git/objects -type f
.git/objects/5f/2f16bfff90e6620509c0cf442e7a3586dad8fb
.git/objects/a9/36e260776b0c97788d90fb9e87e133c6401364

# sparrow @ localhost in ~/Documents/learning/test on git:master x [17:30:21]
$ echo '2222' > 1.txt

# sparrow @ localhost in ~/Documents/learning/test on git:master x [17:31:14]
$ git hash-object -w 1.txt
c7dc989f8044a4fcf16361414998e14694e1ac7e

# sparrow @ localhost in ~/Documents/learning/test on git:master x [17:31:23]
$ find .git/objects -type f
.git/objects/5f/2f16bfff90e6620509c0cf442e7a3586dad8fb
.git/objects/c7/dc989f8044a4fcf16361414998e14694e1ac7e
.git/objects/a9/36e260776b0c97788d90fb9e87e133c6401364

上面的命令,是存储了一个txt文件,之后修改这个文件,再次存储,可以看到文件变更后又存储了一个新的文件。但是有个明显的问题就是,我们始终没有看到存储的文件名称

GIT的文件种类

文件类型描述存储的信息
commit提交组建每次提交之后产生,会把所有文件信息创建一个tree文件,以及提交信息,用户信息
tree文件树存储这个tree下有哪些文件,有文件类型,文件hash值,文件名称
blob文件文件的具体内容(会被压缩)
GIT:Commit && Tree
### 新增一个1.txt文件,并且提交:


$ git commit -m'第一次提交'
[master (root-commit) f2e5a15] 第一次提交
 1 file changed, 1 insertion(+)
 create mode 100644 1.txt

$ git cat-file -p master^{tree}
100644 blob c7dc989f8044a4fcf16361414998e14694e1ac7e	1.txt

$ find .git/objects -type f
.git/objects/66/58043fa729b52ab982f5fd48aa35a3992dbca0
.git/objects/f2/e5a15e35c55cd773496dd6092953a2deeaaf29
.git/objects/c7/dc989f8044a4fcf16361414998e14694e1ac7e

$ git cat-file -p 66580
100644 blob c7dc989f8044a4fcf16361414998e14694e1ac7e	1.txt

$ git cat-file -t f2e5a
commit

$ git cat-file -p f2e5a
tree 6658043fa729b52ab982f5fd48aa35a3992dbca0
author sparrow <chwangyanan@foxmail.com> 1545645214 +0800
committer sparrow <chwangyanan@foxmail.com> 1545645214 +0800

第一次提交

从上面可以看出,如果我们进行了新的提交,就会出现一个新的commit文件,然后这个文件中包含一个tree文件的 hash值,而这个tree文件的内容则包含文件名,当然也可以是tree的名称(相当于目录的概念)

提交记录Commit
### 新增一个文件 */dir1/2.txt*

$ find .git/objects -type f
.git/objects/66/58043fa729b52ab982f5fd48aa35a3992dbca0
.git/objects/e5/cbfdee257934ed2cf026ce17ca868f3a4b1705
.git/objects/c7/dc989f8044a4fcf16361414998e14694e1ac7e
.git/objects/ee/4cc7e06ea6b72d9d92534e37cc0ee5fe8622cf
.git/objects/f2/e5a15e35c55cd773496dd6092953a2deeaaf29
.git/objects/e4/8f67e7f3128750710269e1baccadd83ac151ad
.git/objects/8a/666e85a8ec9b8d4a2bad19c976892ac1bc948d

$ git cat-file -p e5cbf
tree ee4cc7e06ea6b72d9d92534e37cc0ee5fe8622cf
parent f2e5a15e35c55cd773496dd6092953a2deeaaf29
author sparrow <chwangyanan@foxmail.com> 1545645896 +0800
committer sparrow <chwangyanan@foxmail.com> 1545645896 +0800

带目录的提交

$ git cat-file -p e48f6
dir1->111

$ git cat-file -p 8a666
100644 blob e48f67e7f3128750710269e1baccadd83ac151ad	2.txt

$ git cat-file -p ee4cc
100644 blob c7dc989f8044a4fcf16361414998e14694e1ac7e	1.txt
040000 tree 8a666e85a8ec9b8d4a2bad19c976892ac1bc948d	dir1

可以发现:

  1. 目录被储存为一个tree文件。
  2. 提交记录里面多了parent一行,指向前一次提交的hash。
  3. 1.txt的记录会被再次存储
HEAD指向
$ cat .git/HEAD
ref: refs/heads/master

看下HEAD,发现指向ref中的文件

$ cat .git/refs/heads/master
e5cbfdee257934ed2cf026ce17ca868f3a4b1705

会发现有一个hash值,这个值就是第二次提交后生成的commit文件的hash值。

分支的信息
### 新建dev分支

$ git branch dev

$ git branch
* master
dev

### 进入.git/refs/heads目录,查看分支信息
$ cd .git/refs/heads

$ ll
total 16
-rw-r--r--  1 sparrow  staff    41B 12 24 18:28 dev
-rw-r--r--  1 sparrow  staff    41B 12 24 18:04 master

$ cat dev
e5cbfdee257934ed2cf026ce17ca868f3a4b1705

$ cat master
e5cbfdee257934ed2cf026ce17ca868f3a4b1705

可以看到,dev 和 master 指向同一个CommitHEAD指向这里的master

### 通过拷贝文件的方式创建一个新的分支
$ cp dev dev2

$ git branch
* master
dev
dev2
### 这个时候可以去看下,HEAD文件已经指向dev2

我的个人博客,有空来坐坐

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值