git学习笔记(十二)--git的库管理
1. 关于松散对象和打包的概念
在对.git版本库内容的学习中,知道其中的refs目录是存放引用的,其下的tags存放里程碑,head存放分支引用,remote存放远程版本库在本地的映射
.git----------------版本库
--refs---------引用
--tags----里程碑
--head----分支引用
引用打包命令: git pack-refs --all
查看引用打包文件: head .git/packed-refs
通过对refs引用的打包,在版本库的传输上可以达到按需传输的高效率。
松散对象:Git对以SHA1哈希值为目录名和文件名保存的对象成为松散对象。
对松散文件打包后可以提高访问效率,对差异度很小的文件之间可以通过增量存储节省磁盘。
松散文件打包后,在.git/objects目录下只有两个文件,一个是.idx索引文件,一个是.pack打包文件
2. 清除暂存区中引入的临时对象
在文件的反复修改和添加过程中,可能会在暂存区中引入大量不必要的文件,这些文件即使被撤出暂存区,在一定时间范围内不会被版本库自动丢弃,如果长时间不清理,会影响整体的运行效率。如下:
(1)复制一个大文件进入工作区
(2)添加 git add .
(3)撤销添加 git reset
(4)这时文件撤出暂存区,但对象库中已经产生了松散对象
(5)du -sh .git/ 查看版本库大小,发现还包含着大文件
(6)git fsck 这个命令用来查看版本库中是否有松散对象
(7)dangling blob ID 凡是以dangling开头的都是松散对象
(8)git prune 清除松散对象
(9)git fsck 会发现大文件已经被清除出版本库
3. 清除提交后撤销的对象
如果文件没有提交,只是假如暂存区,那么按照上述方法,git prune即可。
但如果文件已经提交,再撤销提交的话,git prune就无法清除了。
解决方法如下,结合一个例子:
(1)添加两个文件到工作区

(2)提交,撤销

(3)撤消后文件仍在对象库中

(4)git prune后,仍然是6.8M,没有清理

(5)原因是在reflog中,还为最后的恢复保留着记录,git认为撤销的提交和大文件还能被追踪到,因此并未把其设为松散对象。因此prune无法清理。
解决办法就是,直接使reflog中的对象过期,即变成了松散对象,可以清理了。

4. git管家:git gc
git gc命令会对git版本库做一系列的优化,也可以清理版本库,而且有自己独特的设置。通常直接prune的情况还是比较少,更多的时候使用git gc比较好。
优化动作:
(1)对分散在.git/refs下的引用打包。
(2)默认条件下,运行reflog过期命令,清空reflog中90天前的记录。
(3)对objects中的松散对象进行打包
(4)默认条件下,清除2周以前暂存区中未关联的文件。
(5)其他清理。
可以发现,git gc把之前3部可能遇到的问题全部处理了。
默认情况下:
暂存区未关联临时文件保存2个星期
因为重置丢弃的文件和提交,保存3个月
git gc的使用例子:
(1)添加两个相同文件进入工作区,其中一个稍作改动,以测试git gc打包的增量存储机制,并且提交

(2)撤销提交,查看空间6.3M,运行git gc后,查看空间2.9M,说明采用了增量存储,占用空间减少了一半(其他优化也可能造成空间释放,因此2.9不是6.3的一半是正常的)

(3)使reflog全部过期,这样就查到了dangling未关联的对象,运行git gc,可以看到未被关联的对象从打包中移除,成为松散对象。没有了增量存储,因此版本库大小又变大了。

(4)git gc --prune=now 不等2个礼拜了,直接清除,版本库变成280K

(5)查看.git/objects目录,发现对象确实被打包了,因此压缩了很多空间

浙公网安备 33010602011771号