git 修改文件名称_Git版本存储原理

论坛 期权论坛 编程之家     
选择匿名的用户   2021-6-2 20:52   1513   0

Git的过人之处

Git为什么是现在互联网最流行的版本控制工具,在我看来Git有其与众不同的地方,也就是过人之处:

  • 首先它是分布式版本工具,每台电脑都有一个完整的版本库,我们可以随时在本地提交我们的代码,集中式版本工具,都要将代码提交到代码库的服务器中,如果没有网络,你想先把本地代码提交了,再进行下一个版本的开发就会变得非常不方便。

  • C语言的指针在Git内部实现中运用得淋漓尽致,无论是分支创建,分支的合并本质上都是对指针的调整,所以Git非常推荐我们使用分支,哪怕是修复一个小小的bug,都可以创建一个分支进行修复,因为Git分支创建和销毁的代价都是非常小的,仅仅是删除和移动指针而已。而在SVN等工具中想要创建和销毁分支的代价是非常大的,显得非常笨重不方便。

  • Git是保存的是快照流,而SVN保存的是版本之间的差异。这也是为什么Git进行版本回溯比其他工具要快。

简述了下Git的过人之处,那么就来看看其内部的实现原理。

快照和差异比较的区别

SVN的存储方式如下图:

58f8e0a08d2488591e61153f9af6c3ed.png

其实就是保存每个文件不同版本之间的差异。那么回溯版本的时候是不是需要拼接或者剔除差异后,才能得到最终的内容,如果一个文件版本的迭代次数越多,版本的回溯就会越慢。

那么,Git的快照是怎么存储的呢?

e6f025938f9206b7432183f0c16ddb89.png

就是同个文件,每个版本都会保存一份快照,如果下个版本文件没有修改,就会延用原先的快照,用一个指针指向原先的快照即可。

那么Git怎么知道文件没有被修改呢?其实Git会用一种SHA-1的散列算法基于文件的内容计算出一个Hash值,Git可以通过Hash值来索引文件,文件内容一致,Hash值必然一致,这也是为什么你只修改了文件名但内容并没有修改,Git却能感知到该文件已经换了一个文件名,而不是一个新增的文件,因为它基于内容计算出的Hash值是相同的。

Git原理

假设我们在新建的一个git项目,执行git add 1.txt,就会看到文件.git/object下多了个文件夹和文件,如图:

友情提示,查看目录树的命令watch -n 1 tree .git/

ecf064d67506cd6fc5d7d076d7e046e5.png

下面我们通过Hash值便可以索引到文件内容。

7c3a48131a8431285d8383a965b01cfb.png

这个时候我们执行git commit -m 'first commit' 1.txt,发现.git/object下又产生几个新的文件夹,很显然黄色框部分就是新产生的。

dd3608b1ea9e1756076baacdac49b879.png

再来看下其中里面存储的是什么内容

ea2dfc931c7b4c4f1a3f8f54ab296fab.png

看到这里,你是不是明白了什么,原来6dc2这个Hash对应的文本里面包含了1.txt文件的Hash值文件名称


再往下看,你是不是明白了彻底懂了,原来这个98de这个Hash对应的文本里面包含了6dc2提交注释和作者信息

f9923f4f017857e00fd7371276d5b30f.png

查看git log发现,原来98de就是commitID

539b4a2658ff1197c8b8516dd197d393.png

也就是我们通过98de这个commitID找到6dc2对应的tree,再通过tree里面保存的5711这个Hash值就可以索引到文本快照。

如果再提交一个新的文件呢?就会生成新的commitID,我们查看最新的commitID,就会看到多了一个parent节点,很显然它指向上次提交的commitID

e2613a32c39a99bd8c4f4038eb348c49.png

再看下master分支,保存也是这个最新的commitID,这样我们就知道,分支不过就是存储一个指针,指针的表现形式就是Hash值。

031158d78f5b08411d6178261903b023.png

通过下面的图我们可以直观的感受下,他们之间的关联关系:

1add2ea6025763356b08c909a14f9bfd.png

820c090a3491d62b0bc6fe5d2a9afe92.png

Git回溯版本直接就通过版本对应的CommitID,层层索引下去就能将当前版本下的所有文件给找出来,因为每个文件版本都有一个快照,并不像SVN一样需要对比文件差异,所以速度是非常快的。

最后

理解Git原理对于我们使用Git本身也会有非常大的好处,当然,笔者没有讲分支的合并,其实你懂了这篇文章,你去看Git分支合并原理相关的文章,你也会更加理解git merge的几种合并方式以及git mergegit rebase本质上有什么不同,以及他们各自的实现原理。

最近一段时间都在看Netty源码,核心的逻辑过了下,有些地方设计得确实比较巧妙,不知道有没有机会给读者来一篇,不过很建议大家去把TCP/IP深入了解下,这样对于整个网络编程的理解也会更加深刻,因为分布式系统之间的通信都逃不过网络协议,这样对于你理解各种中间件应相关的协议,比如Redis,MQ的上层协议也会非常快。

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP