Git内部原理解析

1. GIT存储信息的过程。

首先我们创建一个空目录,使用命令初始化为一个本地仓。

git init

 执行完毕会生成一个.git/的目录,如下是.git/的目录结构。其中我们需要关注objects目录。

[root@python .git]# tree
.
├── 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

首先我们创建两个文件:a.txt和b.txt,并添加到缓存区。

echo '111' > a.txt
echo '222' > b.txt
git add .

此时我们再看下objects目录,会多出两个文件夹58c2,这两个文件夹下都有以哈希值为命令的文件。

[root@python workspace]# tree .git/objects/
.git/objects/
├── 58
│   └── c9bdf9d017fcd178dc8c073cbfcbb7ff240d6c
├── c2
│   └── 00906efd24ec5e783bee7f23b5d7c941b0c12c
├── info
└── pack

若直接使用cat命令查看这两个文件,会得到Git将信息压缩成的二进制信息,想要查看该文件的内容和类型时,可以使用git 命令git cat-file-t查看类型,-p查看内容。

[root@python 58]# git cat-file -t 58c9
blob
[root@python 58]# git cat-file -p 58c9
111
[root@python 58]# cd ../c2/
[root@python c2]# git cat-file -t c200
blob
[root@python c2]# git cat-file -p c200
222

一个文件就是一个git object,可以看到58c8这个object的git类型是blob,内容是111,也就是说我们刚刚提交的a.txt文件内容保存在这个object对象中(不包含文件名等其他信息)。然后将这些信息经过SHA1哈希算法得到对应的哈希值58c9bdf9d017fcd178dc8c073cbfcbb7ff240d6c,作为这个object在Git仓库中的唯一身份证。

继续使用commit命令把暂存区的内容提交到本地仓库。

[root@python workspace]# git commit -am "test commit"
[master (root-commit) e5afac3] test commit
 2 files changed, 2 insertions(+)
 create mode 100644 a.txt
 create mode 100644 b.txt

再来查看object目录,多出了4c,e5两个object

[root@python workspace]# tree .git/objects/
.git/objects/
├── 4c
│   └── aaa1a9ae0b274fba9e3675f9ef071616e5b209
├── 58
│   └── c9bdf9d017fcd178dc8c073cbfcbb7ff240d6c
├── c2
│   └── 00906efd24ec5e783bee7f23b5d7c941b0c12c
├── e5
│   └── afac38ad1c3bacf681d15b4296b4e35d1fb14d
├── info
└── pack

6 directories, 4 files

同样使用cat-file命令查看4caa object的类型和内容

[root@python workspace]# cd .git/objects/4c/
[root@python 4c]# git cat-file -t 4caa
tree
[root@python 4c]# git cat-file -p 4caa
100644 blob 58c9bdf9d017fcd178dc8c073cbfcbb7ff240d6c    a.txt
100644 blob c200906efd24ec5e783bee7f23b5d7c941b0c12c    b.txt


可以看到4caa的git类型为tree,存储的内容:权限(100644),类型(blob),哈希值(58c9),文件名(a.txt)

[root@python e5]# git cat-file -t e5af
commit
[root@python e5]# git cat-file -p e5af
tree 4caaa1a9ae0b274fba9e3675f9ef071616e5b209
author hhs <1196454389@qq.com> 1622392476 +0800
committer hhs <1196454389@qq.com> 1622392476 +0800

test commit

 可以看到e5af的git类型是commit,存储的是一个commit提交的信息。包含tree的哈希值,提交的作者以及提交的具体时间,最后是该提交的信息。至此git的存储完毕。

小总结下:

  • git add . :把数据提交到暂存区,会在objects目录下生成blob类型、文件名是哈希值的git object对象。
  • git commit -am :会生成两个git的object对象,一个类型是tree,存储缓存区的数据(权限、类型、哈希值、文件名),另一个类型是commit,存储tree的哈希值,和作者信息,提交信息。

2. 修改文件Git的操作流程。

修改a.txt的内容为 333 ,此时objects目录下无变化

echo "333" > a.txt

执行git add 把文件添加到缓存区

git add .

 此时objects目录下多出了55bd的git对象,类型是blob,内容是333,原先的58c8还存在,其他文件内容都保持不变。

[root@python workspace]# tree .git/objects/
.git/objects/
├── 4c
│   └── aaa1a9ae0b274fba9e3675f9ef071616e5b209
├── 55
│   └── bd0ac4c42e46cd751eb7405e12a35e61425550
├── 58
│   └── c9bdf9d017fcd178dc8c073cbfcbb7ff240d6c
├── c2
│   └── 00906efd24ec5e783bee7f23b5d7c941b0c12c
├── e5
│   └── afac38ad1c3bacf681d15b4296b4e35d1fb14d
├── info
└── pack

执行git commit命令,查看ojects目录

[root@python workspace]# git commit -am "fix a.txt content"
[master 5bba618] fix a.txt content
 1 file changed, 1 insertion(+), 1 deletion(-)
[root@python workspace]# tree .git/objects/
.git/objects/
├── 0f
│   └── d247c919b0faa824e03cbef3b4b375d804e481   # 新tree
├── 4c
│   └── aaa1a9ae0b274fba9e3675f9ef071616e5b209
├── 55
│   └── bd0ac4c42e46cd751eb7405e12a35e61425550
├── 58
│   └── c9bdf9d017fcd178dc8c073cbfcbb7ff240d6c
├── 5b
│   └── ba61842ebaf5532fdab6ad319443bf52e686be   # 新commit
├── c2
│   └── 00906efd24ec5e783bee7f23b5d7c941b0c12c
├── e5
│   └── afac38ad1c3bacf681d15b4296b4e35d1fb14d
├── info
└── pack

可以看到,多出了类型为tree的0fd2和类型为commit的5bba文件。

[root@python 0f]# git cat-file -t 0fd2
tree
[root@python 0f]# git cat-file -p 0f2d
fatal: Not a valid object name 0f2d
[root@python 0f]# git cat-file -p 0fd2
100644 blob 55bd0ac4c42e46cd751eb7405e12a35e61425550    a.txt
100644 blob c200906efd24ec5e783bee7f23b5d7c941b0c12c    b.txt
[root@python 0f]# cd ../5b/
[root@python 5b]# git cat-file -t 5bba
commit
[root@python 5b]# git cat-file -p 5bba
tree 0fd247c919b0faa824e03cbef3b4b375d804e481
parent e5afac38ad1c3bacf681d15b4296b4e35d1fb14d
author hhs <1196454389@qq.com> 1622395651 +0800
committer hhs <1196454389@qq.com> 1622395651 +0800

fix a.txt content

参考:这才是真正的Git——Git内部原理揭秘!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大帅不是我

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值