当前位置:   article > 正文

可视化学习Git基础知识及commit规范_commit feat(*)可视化

commit feat(*)可视化

Git存储结构

git add

首先我们创建两个文件交给git管理

git init
echo 'aaa'>a.txt
echo 'bbb'>b.txt
git add  *.txt
  • 1
  • 2
  • 3
  • 4

执行完上述几条命令后,git会将整个数据库储存在.git/目录下,此时我们可以查看.git/objects目录,会发现多了两个object。
查看.git/objects
可能有人就会好奇这两个文件是什么,不要着急,我们一一查看。
我们先来通过cat命令查看,结果如下:
cat查看
我们可以看出存储的是一堆被压缩的二进制文件,如果大家还记得什么类型的文件适合存储二进制文件,那大家应该可以想到,这个文件大概是blob类型的。
git也很贴心的给了我们查看文件的api工具:

git cat-file [-t] [-p] 文件id
//-t:查看object的类型
//-p:查看object内容
  • 1
  • 2
  • 3

我们通过上面的命令查看一下,结果如下
cat-file
我们可以看到,该object是一个blob类型的节点,内容为aaa。这个object只存储a.txt的内容,并没有存储文件名/权限等信息,那么这些信息存储在哪里呢,为什么不存储在这里呢?看完就知道啦!!!
此时我们可以明确看到Git仓库就是下图的样子:
git init后仓库样子

git commit

我们将刚才add的文件,进行commit提交。

git commit -m 'init'
  • 1

git commit
上图就是进行commit操作打印的一些信息,可以有个简单的了解,commit之后让我们继续查看.git/objects目录如下:
git commit后结构
我们发现 commit 完之后,仓库又多出来了两个object文件,我们分别查看两个文件
86ca
如上图,86ca文件类型为commit,存储的是 commit 信息
65B7
如上图,65b7文件类型为tree,从存储的内容来看,它存储的是一个目录结构,以及每一个文件的权限,类型,SHA1值,文件名。
到这里,我们可以发现这四个objec的关系,我们可以通过查看 commit 信息 > tree信息 > 具体文件。
现在关系基本明朗,我们可以先查看一下分支信息。
分支信息
在git中,HEAD,分支,tag等信息都类似于一个指针,只想我们的commit信息。
看到这里,相信大家都明白了 Git 的本质其实就是一个key-value的数据库加上树结构的有向无环图
git存储结构

Git分区工作

Git的三个分区(工作目录、Index索引区、Git库)。
工作目录:
操作系统上的文件,所有代码开发编辑都在这上面完成。
Index索引区
一个暂存区域,这里面的代码会在下一次 commit 时被提交到Git仓库。
Git仓库
由 Git object 记录着每一次的快照,以及链式结构记录的提交变更历史。
接着第一部分的例子,我们此时的各分区如下图:
git各分区
我们想查看工作空间的变化,最简便的可以按如下进行操作:
修改 a.txt 内容》执行 add 》执行 commit

  1. 修改 a.txt 文件内容为ccc

    echo 'ccc'>a.txt
    
    • 1

    在修改完 a.txt 文件后,此时的各分区情况如下,索引区和Git仓库均没有变化。
    修改a.txt后

  2. 执行 add 操作

    git add a.txt
    
    • 1

    执行完 add 操作后,将 a.txt 添加到索引区域,此时 git 在仓库里面新建了一个 blob object 用于存储新的文件内容,并且更新了索引,将 a.txt 指向了新建的object。此时各分区如下图:
    git add后空间变化

  3. 执行 commit 操作

    git commit -m 'update ccc'
    
    • 1

    执行完 commit 操作后会发生一下三个操作:
    1) Git首先会根据当前索引生成一个 tree object,充当新提交的一个快照;
    2) 创建一个新的 commit object ,将这次 commit 信息储存起来,并且 parent 指向上一个 commit 组成一条链记录变更历史。
    3) 将 master 分支的指针移到新的 commit 节点。
    此时各分区情况如下图:
    最终git分区结构

好了,至此关于git的基本可视化应该就能在我们脑海中出现了吧。看到这里,不知道还记不记得上面提到的几个问题呢?

git commit message 规范

commit message格式: <type>(<scope>): <subject>

  1. type(必须) :用于说明git commit的类别,只允许使用下面的标识。
    feat: 新功能(feature)
    fix: 修补 bug
    docs: 文档(documentation)
    style: 格式(不影响代码运行的变动)
    refactor:重构(即不是新增功能,也不是修改 bug 的代码变动)
    test:增加测试
    chore:构建过程或辅助工具的变动
    revert:回滚到上一个版本
    merge:代码合并
    sync:同步主线或分支的Bug
  2. scope(可选):用于说明 commit 影响的范围
  3. subject(必须):用于说明 commit 变动的简短描述

例子:
feat(Controller): 用户拥有权限查询
fix(*): 用户权限查询异常调整

问题

  1. 为什么要把文件的权限和文件名等信息储存在 tree object 里面而不是 blob object 呢?
    关于一个修改文件名的操作,如果我们把文件名保存在 blob 中会发生什么呢?那Git只能多复制一份原始内容形成一个新的 blob object 。而Git的实现方法只需要创建一个新的 tree object 将对应的文件名更改成新的即可,原本的 blob object 可以复用,节约了空间。
  2. 每次 commit ,Git 储存的是全新的文件快照还是储存文件的变更部分?
    由上面的例子我们可以看到,Git 储存的是全新的文件快照,而不是文件的变更记录。就算你只是在文件中添加一行,Git 也会新建一个全新的 blob object。
    可能有人会说,那这样做岂不是很浪费空间,如果只保存变更的部分多好呀。
    这其实是Git在空间和时间上的一个平衡,想象一下你要 checkout 一个 commit ,或对比两个 commit 之间的差异。如果 Git 储存的是问卷的变更部分,那么为了拿到一个 commit 的内容,Git 都只能从第一个 commit 开始,然后一直计算变更,直到目标 commit ,这会花费很长时间。而相反,Git 采用的储存全新文件快照的方法能使这个操作变得很快,直接从快照里面拿取内容就行了。
    可有又有人会说,那重复文档一直增多岂不是体量超大,关于这个Git 会有垃圾回收机制 gc ,不仅会清除无用的 object ,还会把已有的相似object打包压缩。
  3. Git怎么保证历史记录不可篡改?
    通过 SHA1 哈希算法和哈系树来保证。假设你偷偷修改了历史变更记录上一个文件的内容,那么这个问卷的 blob object 的SHA1哈希值就变了,与之相关的 tree object 的SHA1也需要改变,commit 的SHA1也要变,这个 commit 之后的所有 commit SHA1 值也要跟着改变。又由于Git是分布式系统,即所有人都有一份完整历史的Git仓库,所以所有人都能很轻松的发现存在问题。

彩蛋

寓教于乐,如果关于git的基本命令还是不太清楚的,或者不能实现git可视化的,可以登录下面这个关于 Git 小游戏的链接,一层层闯关,一路打怪升级。
Git 游戏链接:https://learngitbranching.js.org/?demo=&locale=zh_CN

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/455629
推荐阅读
相关标签
  

闽ICP备14008679号