git核心
分支概念
版本控制系统中,都有一个概念,叫做分支,就是同样的一份儿代码,可以拉取多个分支,每个分支的代码刚开始都是一样的,然后不同的人可以基于不同的分支去开发,然后开发完之后,再将多个分支的代码合并在一起
git里面,每次git init之后,默认初始就创建一个分支,叫做master分支,我们每次写代码,然后git commit提交,都会形成一次新的commit,然后默认就是在master分支对应的代码拷贝上,进行代码修改和提交的
.git文件夹
这个文件夹一般会在git初始化的时候创建出来,后续所有版本管理相关的数据都会存在这个文件夹里面 | 文件/文件夹 | 作用 | | —- | —- | | config | 文本文件,保存当前项目特有的配置项,通过git config —local进行配置 | | HEAD | 文本文件,指针,指向当前正在工作的分支 | | description | 文本文件,描述当前仓库的一些信息,只有GitWeb会用到该文件 | | refs | 文件夹,里面包含所有分支以及tag指向的commit信息 | | hooks | 文件夹,包含有在执行一些 Git 命令后,git 命令调用的脚本 | | info | 文件夹,存储有一些该仓库中记录的其他信息。例如,exclude 文件中要存储 需要被排除在外的文件名,类似于 .gitignore 文件,和gitignore 不同的是exclude并不会把自己也提交到git仓库中 | | objects | 文件夹,git commit建立的所有的commit和文件快照信息都会保存在这里 |
核心对象
- git有几个最核心的对象,git所谓的版本控制实际就是增删改查这几个核心的对象 | 对象名 | 作用 | | —- | —- | | blob | 存储真正的文件内容,比如我们的文本文件/图片等都会生成一个blob对象 | | tree | 存储目录结构和文件名(即blob的SHA1哈希值) | | commit | 存储提交的说明,比如提交作者/作者的邮箱/提交的时间等等,还有一个parent指针来指向上一个commit,最后还会指向一个tree构成我们的提交图谱 | | tag | 存储带注释的标签(tag) |
Object/References/Index
实体
实体就是我们上面的核心对象,仓库中的所有文件都会保存在.git/objects下面存储为实体
每一个实体以一个SHA1哈希值作为标识
引用
引用可以简单粗暴的理解为分支,不管是本地分支还是远程分支 亦是某一个tag都是一个引用
引用即字面意思 最终都会指向一个地方,git中的引用最终都会指向一个commit实体
引用是以文本文件的形式存储在.git/refs下面
索引
索引也就是我们常说的暂存区,以二进制文件的形式存储在.git/index下面
git add 的时候先会把该文件的信息存储到索引中,git commit的时候仅提交索引文件中列出的文件
三者的关系
- 三者的关系如下图所示
举例说明
初始化新的代码仓库
重新初始化一个仓库
[root@ipa ~]# git init git-test
可以看到初始化了.git目录,HEAD目前指向refs/heads/master
添加新文件
添加一个新文件,此时可以看到.git/objects文件夹里多个一个目录和文件即blob实体,并且也创建出了index文件
[root@ipa git-test]# echo "Hello Git" >> README [root@ipa git-test]# git add README
顺便说一下,objects中生成的对象的名称是以SHA1哈希值前两位做目录名 后38位做文件名,如图片所示我们在objects目录里生成了一个子目录(9f)和文件(4d96d5b00d98959ea9960f069585ce42b1349a),那么这个对象的SHA1哈希值就为9f4d96d5b00d98959ea9960f069585ce42b1349a
同时我们也可以使用命令进行类型的查看和内容的查看 ```shell
查看某个对象的类型,SHA1哈希值可以只取前几位,能够唯一标识即可
git cat-file -t 9f4d96d
查看某个对象的内容
git cat-file -p 9f4d96d

<a name="jhBEE"></a>
### 首次提交
1. 将README文件从暂存区提交至本地git仓库,可以看到创建了master引用以及多了两个实体对象
```shell
[root@ipa git-test]# git commit -m 'first commit'
- 按照前面的理论支持,我们可以猜到.git/refs/heads/master指向的是一个commit,可以看到下面输出的内容 commit对象实际上就是一个tree + 一些提交信息
```shell
查看master引用的内容是一个SHA1哈希值
[root@ipa .git]# cat refs/heads/master 994f5181ddc4fdb5ed78f96fe58af0bac99249aa
查看该SHA1哈希值的类型是一个commit
[root@ipa .git]# git cat-file -t 994f5181 commit
查看该commit对象的内容
[root@ipa .git]# git cat-file -p 994f5181 tree 53d7660eebaafbee73095cd4cef68455d47fdb21 author tianbo tianbo1@yonghui.cn 1641015725 +0800 committer tianbo tianbo1@yonghui.cn 1641015725 +0800
first commit
3. 那么commit对象里面的tree又是什么呢?其实commit 里面的tree就是指向了我们的README文件的blob对象
```shell
[root@ipa .git]# git cat-file -t 53d7660e
tree
[root@ipa .git]# git cat-file -p 53d7660e
100644 blob 9f4d96d5b00d98959ea9960f069585ce42b1349a README
修改一个文件
- 我们再把README文件修改一下,可以看到有新建了一个blob对象 并且index中也加入了这个对象 ```shell [root@ipa git-test]# echo “Hello BO.TIAN” >> README [root@ipa git-test]# git add README
查看下index文件中的内容
[root@ipa .git]# git ls-files —stage 100644 dd9178f85072dc73841d8de98167859065df25d7 0 README
查看下新加入对象的类型以及内容
[root@ipa .git]# git cat-file -t dd9178f8 blob
[root@ipa .git]# git cat-file -p dd9178f8 Hello Git Hello BO.TIAN
<br />
<a name="JDXq5"></a>
### 向子目录添加文件
1. 我们在创建一个子目录,并且在子目录中创建一个文件,此时就会更新index并且创建一个blob对象(4bf92f2)
```shell
# 创建相关文件
[root@ipa git-test]# mkdir src
[root@ipa git-test]# echo "CODEING..." >> src/code.txt
[root@ipa git-test]# git add .
# 查看下index文件中的内容
[root@ipa .git]# git ls-files --stage
100644 dd9178f85072dc73841d8de98167859065df25d7 0 README
100644 4bf92f2e900cb67b5a76ee0c02c6a9e01c706a76 0 src/code.txt
第二次提交
- 上面我们修改了README文件并且增加了一个文件夹src,在src文件夹里加入了code.txt文件,并且都加入暂存区
- 我们现在来进行第二次提交 ```shell [root@ipa git-test]# git commit -m ‘second commit’
查看master引用指向
[root@ipa .git]# cat refs/heads/master fd49b9fe6e8ec6f9ff3b8ea4d587d904c843f180
查看该实体的类型
[root@ipa .git]# git cat-file -t fd49b9 commit
查看commit实体的内容
[root@ipa .git]# git cat-file -p fd49b9
tree 97dd67d23a116a61f563096bc49c41d4b378d3cd parent 994f5181ddc4fdb5ed78f96fe58af0bac99249aa author tianbo tianbo1@yonghui.cn 1641017543 +0800 committer tianbo tianbo1@yonghui.cn 1641017543 +0800
查看该commit指向的tree
[root@ipa .git]# git cat-file -t 97dd67d tree
[root@ipa .git]# git cat-file -p 97dd67d 100644 blob dd9178f85072dc73841d8de98167859065df25d7 README 040000 tree 3f3ddf46810d1da2a635060ac0a0ace231675251 src
查看src tree
[root@ipa .git]# git cat-file -p 3f3ddf 100644 blob 4bf92f2e900cb67b5a76ee0c02c6a9e01c706a76 code.txt
```