Git原理初探
大体结构回顾
下图是一张经典的 git 的常规提交流程,展示了他从本地工作空间到本地的数据库,再到远端的整个过程,可以看到其主要由工作空间、暂存区以及本地仓库组成,通过不同的git命令来推动文件在git中的状态转换
简单的工作流程
一般工作流程如下:
- 克隆 Git 资源作为工作目录。
git clone -b <分支名称> <远程仓库地址>
- 在克隆的资源上添加或修改文件。
git add .
git commit -m "feat: 代码修改描述"
- 如果其他人修改了,你可以更新资源。
git pull
- 在提交前查看修改。
git status
- 提交修改。
git push
- 在修改完成后,如果发现错误,可以撤回提交并再次修改并提交。
git reset --soft HEAD^
具体的命令,你可以查阅相关文档
git的存储目录结构
git的目录结构如下
git的对象
git 主要有四个对象
分别是 Blob,Tree, Commit, Tag 他们都用 SHA-1 进行命名。
你可以用 git cat-file -t 查看每个 SHA-1 的类型,用 git cat-file -p 查看每个对象的内容和简单的数据结构。git cat-file 是 git 的瑞士军刀,是底层核心命令。
- Blob 对象
只用于存储单个文件内容,一般都是二进制的数据文件,不包含任何其他文件信息,比如不包含文件名和其他元数据。 - Tree 对象
对应文件系统的目录结构,里面主要有:子目录 (tree),文件列表 (blob),文件类型以及一些数据文件权限模型等。Tree对象的存储结构如下图
3. Commit 对象
是一次修改的集合,当前所有修改的文件的一个集合,可以类比一批操作的“事务”。是修改过的文件集的一个快照,随着一次 commit 操作,修改过的文件将会被提交到 local repository 中。通过 commit 对象,在版本化中可以检索出每次修改内容,是版本化的基石。
一个commit对象的存储结构如下图
4. Tag 对象
tag 是一个"固化的分支",一旦打上 tag 之后,这个 tag 代表的内容将永远不可变,因为 tag 只会关联当时版本库中最后一个 commit 对象。
分支的话,随着不断的提交,内容会不断的改变,因为分支指向的最后一个 commit 不断改变。所以一般应用或者软件版本的发布一般用 tag。
一个TAG对象的存储结构如下图
所有对象模型之间的关系大致如下
拓展内容
存储模型
概念
git 区别与其他 vcs 系统的一个最主要原因之一是:git 对文件版本管理和其他 vcs 系统对文件版本的实现理念完成不一样。这也就是 git 版本管理为什么如此强大的最核心的地方。
Svn 等其他的 VCS 对文件版本的理念是以文件为水平维度,记录每个文件在每个版本下的 delta 改变。
Git 对文件版本的管理理念却是以每次提交为一次快照,提交时对所有文件做一次全量快照,然后存储快照引用。
Git 在存储层,如果文件数据没有改变的文件,Git 只是存储指向源文件的一个引用,并不会直接多次存储文件,这一点可以在 pack 文件中看见。
如下图所示:
其具体的存储模型、检索算法可以去参考资料中查阅