git保存数据模式

Git 和其它版本控制系统(包括 Subversion 和近似工具)的主要差别在于 Git 对待数据的方式。 从概念上来说,其它大部分系统以文件变更列表的方式存储信息,这类系统(CVS、Subversion、Perforce、Bazaar 等等) 将它们存储的信息看作是一组基本文件和每个文件随时间逐步累积的差异 (它们通常称作 基于差异(delta-based) 的版本控制)。
Git 不按照以上方式对待或保存数据。反之,Git 更像是把数据看作是对小型文件系统的一系列快照。 在 Git 中,每当你提交更新或保存项目状态时,它基本上就会对当时的全部文件创建一个快照并保存这个快照的索引。 为了效率,如果文件没有修改,Git 不再重新存储该文件,而是只保留一个链接指向之前存储的文件。 Git 对待数据更像是一个 快照流。

从以上信息可知,git保存的是快照而不是差异,那么随着git提交次数增加,git版本库的体积会越来越大,好在git提供了一些命令可以解决这种问题。

打包对象

git数据大多保存在.git/objiects,我们每次保存数据都会增加新的快照,即使少量的改动,也会生成相应新的快照,虽然保存快照进行了压缩,但还是没有实现增量存储。
克隆远程版本库时,使用了“智能”的通讯协议,远程Git服务器将对象打包后传输给本地,形成本地版本库的对象库中的一个包含所有对象的包以及索引文件。无疑这样的传输方式——按需传输、打包传输,效率最高。
Git的对象(commit、blob、tree、tag)在对象库中的存储。对象库中只有两个文件,本应该一个一个独立保存的对象都不见了。
所有的对象文件都被打包到这两个文件中了,其中以:file:.pack结尾的文件是打包文件,以:file:.idx结尾的是索引文件。打包文件和对应的索引文件只是扩展名不同,保存于:file:.git/objects/pack/目录下。
在这里插入图片描述
git gc对分散在.git/refs下的文件进行打包,打包到文件.git/packed-refs中。
![在这里插入图片描述](https://img-blog.csdnimg.cn/a93f2b5a686a465aa26d65b34a216169.png
git verify-pack -v .git/objects/pack/pack-acccb266f218c2d6d642eee70acda5c952f6e88e.pack查看打包内容
在这里插入图片描述

git gc

会对版本库进行一系列的优化动作

  • 对分散在:file:.git/refs下的文件进行打包,打包到文件:file:.git/packed-refs中。
    如果没有将配置:file:gc.packrefs关闭,就会执行命令::command:git pack-refs --all --prune实现对引用的打包。

  • 丢弃90天前的reflog记录。
    会运行使reflog过期命令::command:git reflog expire --all。因为采用了缺省参数调用,因此只会清空reflog中90天前的记录。

  • 对松散对象进行打包。
    运行:command:git repack命令,凡是有引用关联的对象都被打在包里,未被关联的对象仍旧以松散对象形式保存。

  • 清除未被关联的对象。缺省只清除2周以前的未被关联的对象。
    可以向:command:git gc提供–prune=参数,其中的时间参数传递给:command:git prune --expire <date>,实现对指定日期之前的未被关联的松散对象进行清理。

  • 其他清理。
    如运行:command:git rerere gc对合并冲突的历史记录进行过期操作。

git gc完成了相当多的优化和清理工作,并且最大限度照顾了安全性的需要。例如像暂存区操作引入的没有关联的临时对象会最少保留2个星期,而因为重置而丢弃的提交和文件则会保留最少3个月。

清理未关联的对象

一次提交中,可能使用了多次git add,只需把保存最后一次提交的文件即可,过程文件可以作为垃圾对象被清理掉。
git fsck查看未关联的垃圾对象
git prune -n查看执行git prune会删除的对象
git prune 删除未关联的对象
git reset回退的、已删除分支的对象不会被认为是未关联的对象,所以不会被清理,以下命令通过配置禁用宽限日期和reflog等配置参数可直接删除未关联的对象

git -c gc.reflogExpire=0 -c gc.reflogExpireUnreachable=0
-c gc.rerereresolved=0 -c gc.rerereunresolved=0
-c gc.pruneExpire=now gc “$@”

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐