$ git fsck 查看版本库中包含的没有被任何引用关联的松散对象
$ git prune 清理版本库(实际操作中很少用到)
若撤销的操作仍然记录在reflog中,则Git认为撤销的提交和大文件都可以被追踪到,还在使用着,所以无法用git prune命令删除。如果确认真的要丢弃不想要的对象,需要对版本库的reflog做过期操作,相当于将.git/logs/下的文件清空。reflog的过期操作默认只会让90天前的数据过期。需要为git reflog命令提供--expire=<date>参数,强制让<date>之前的记录全部过期。使用now作为时间参数,让reflog的全部记录都过期。$ git reflog expire --expire=now all
$ git pack-refs --all --prune 若未将配置gc.packrefs关闭,则对分散在.git/refs下的文件进行打包,打包到文件.git/packed-refs中
$ git reflog expire --all 清空reflog中90天前的记录。
$ git repack 对松散对象进行打包,凡是有引用关联的对象都被打在包里,未被关联的对象仍旧以松散对象的形式保存。
可以向git gc提供--prune=<date>参数,其中的时间参数传递给git prune --expire=<date>,实现对指定日期之前的未被关联的松散对象进行清理。
$ git rerere gc 对合并冲突的历史记录进行过期操作
对于1.6.6及以后版本的Git基本上不需要手动执行git gc命令了,部分Git命令会自动执行git gc --auto命令,如下:
执行git merge进行合并操作后;执行git receive-pack,即版本库接受其他版本库PUSH来的提交后;执行git rebase -i进行交互式变基操作后;执行git am对mbox邮箱中通过邮件提交的补丁在版本库中进行应用的操作后。
综上所述,对于提供共享式“写操作”的Git版本库,可以免维护。所谓的共享式写操作,就是版本库作为一个裸版本库放在服务器上,团队成员可以通过PUSH操作将提交推送到共享的裸版本中。每一次推送操作都会触发git gc --auto命令,对版本库进行按需整理。
对于非独立工作的本地工作区,也可以免维护。因为和他人协同工作的本地工作区会经常执行git pull操作从他人版本库或从共享的版本库拉回新提交,执行git pull操作会触发git merge操作,因此也会对本地版本库进行按需整理。
整理的太勤则没有必要,还会增加系统负担;疏于整理则会导致积累太多的松散文件,当真正开始版本库整理的时候会占用过多的系统资源,影响用户体验。因此实际操作中只有在特定的条件下才会触发真正的版本库整理。主要的触发条件是:松散对象只有超过一定的数量时才会执行。可以通过设置配置变量gc.auto的值调整频率,不过不能设置为0,否则git gc --auto命令永远不会触发版本库的整理。