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目录,会多出两个文件夹58,c2,这两个文件夹下都有以哈希值为命令的文件。
[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