xxxxxxxxxx
查看git库包含的引用
git show-ref
工作中的版本库:
jagent@ubuntu:~/xin1/APPHwContacts$ git show-ref
bd55831e0446a03a3cc78b1b977b15d100bec830 refs/heads/Bri_JEF_SingleOS_B201_dev
b198b4a141ca0c2894bb3964fa9b0285db4154c9 refs/heads/release_EMUI10.1.1_APK
85fde3e8d2419ca03e4d831f77752533f849641e refs/remotes/origin/APP_Store
bd55831e0446a03a3cc78b1b977b15d100bec830 refs/remotes/origin/Bri_JEF_SingleOS_B2 01_dev
583524b066501b3c88a87e897f0a77ee51305a17 refs/remotes/origin/CITU_Sydney_0611175 2_pipeline_apk
583524b066501b3c88a87e897f0a77ee51305a17 refs/remotes/origin/CITU_Sydney_0612093 0_pipeline_apk
583524b066501b3c88a87e897f0a77ee51305a17 refs/remotes/origin/CITU_Sydney_0613112 0_pipeline_apk
d833e1fd44d2aa17d3050db0d092e90d7c26ac18 refs/remotes/origin/CMCC_AE_20191113_5G _MTBF
cadd67da516ed0214960e801bb0c6a174a933582 refs/remotes/origin/CMCC_ELLE_20181115_ MTBF
...
其中的含义
refs/heads 分支
refs/remotes 版本库分支在本地的映射
refs/tags 指里程碑
按照之前的经验.git/ref目录下应该有这些引用文件
jagent@ubuntu:~/xin1/APPHwContacts$ find .git/refs/ -type f
.git/refs/heads/release_EMUI10.1.1_APK
.git/refs/heads/Bri_JEF_SingleOS_B201_dev
.git/refs/remotes/origin/Bri_JEF_SingleOS_B201_dev
jagent@ubuntu:~/xin1/APPHwContacts$ git pack-refs --all
jagent@ubuntu:~/xin1/APPHwContacts$ find .git/refs/ -type f
发现最后没了,本应该在.git/refs目录下引用文件是放在.git/packed-refs中了
jagent@ubuntu:~/xin1/APPHwContacts$ head -5 .git/packed-refs
# pack-refs with: peeled fully-peeled
bd55831e0446a03a3cc78b1b977b15d100bec830 refs/heads/Bri_JEF_SingleOS_B201_dev
b198b4a141ca0c2894bb3964fa9b0285db4154c9 refs/heads/release_EMUI10.1.1_APK
85fde3e8d2419ca03e4d831f77752533f849641e refs/remotes/origin/APP_Store
bd55831e0446a03a3cc78b1b977b15d100bec830 refs/remotes/origin/Bri_JEF_SingleOS_B201_dev
同理git对象(commit.blob.tree.tag)在对象库中的储存
jagent@ubuntu:~/xin1/APPHwContacts$ find .git/objects -type f
.git/objects/pack/pack-d79f3d0fd2b12c840332fcada0efbd1330786673.idx
.git/objects/pack/pack-d79f3d0fd2b12c840332fcada0efbd1330786673.pack
看出所有的打包文件全部都放在objects/pack打包文件里了,查看需要用一个底层命令
git show-index < .git/objects/pack/pack-*.idx | head -5
克隆远程版本库时,使用了“智能”的通信协议,远程Git服务器将对象打包后传输给本地,形成本地版本库的对象库中的一个包含所有对象的包及索引文件。
Git对于以SHA1哈希值作为目录名和文件名保存的对象有一个术语:松散对象。松散对象打包后悔提高访问效率,而且不同的对象可以通过增量存储节省磁盘空间。
xxxxxxxxxx
暂存区操作有可能在对象库中产生临时对象,例如,文件反复修改、反复地向暂存区添加,或者添加到暂存区后不提交甚至直接撤销,就会产生垃圾数据占用磁盘空间。
git fsck:查看版本库中包含的没有被任何引用关联的松散对象
git fsck --no-reflogs:查看包括reflog记录中的临时对象
git prune:清理临时对象
如果是使用重置命令引入的临时对象用git prune就不能被清除,因为这些临时对象还是可以通过reflog追踪到的,还在使用着,所以不能被git prune删除。要丢弃这些临时对象,需要把reflog做过期操作,相当于把.git/logs下的文件清空:git reflog expire -all
示例:
jagent@ubuntu:~/xin$ du -sh mytest
200K mytest
引入文件p4vinst64.exe
jagent@ubuntu:~/xin$ du -sh mytest
45M mytest(工作空间)
jagent@ubuntu:~/xin/mytest$ git add p4vinst64.exe
jagent@ubuntu:~/xin$ du -sh mytest
88M mytest
查看版本库文件,会发现多了一个松散对象
jagent@ubuntu:~/xin/mytest$ find .git/objects/ -type f
.git/objects/pack/pack-84a22ca7b95feba2ac33557dc6f83298c637fe06.idx
.git/objects/pack/pack-84a22ca7b95feba2ac33557dc6f83298c637fe06.pack
.git/objects/25/8d882a03d2f7706c8da941797271546b903adf
撤出文件
jagent@ubuntu:~/xin/mytest$ git reset HEAD p4vinst64.exe
jagent@ubuntu:~/xin$ du -sh mytest
88M mytest
撤出文件后发现大小没有变化
通过git fsck能查出版本库上没有任何引用关联的松散对象
jagent@ubuntu:~/xin/mytest$ git fsck
Checking object directories: 100% (256/256), done.
Checking objects: 100% (18/18), done.
dangling blob 258d882a03d2f7706c8da941797271546b903adf
dangling标识代表着没有被任何引用或间接关联的对象
执行git prune清理
jagent@ubuntu:~/xin/mytest$ git prune
jagent@ubuntu:~/xin/mytest$ git fsck
Checking object directories: 100% (256/256), done.
Checking objects: 100% (18/18), done.
发现没有了任何关联的松散对象
jagent@ubuntu:~/xin$ du -sh mytest
45M mytest
重置命令引入的临时文件会都一个reflog日志,过期时间为90天,松散对象为撤销的提交,目录树,以及大文件的对象 ,需要执行git fsck --no-reflogs 找到dangling对象
xGit管家 git-gc 相比git prune更常用的命令是git gc,它对版本库进行一系列的优化动作:
1)对分散在.git/refs下的文件进行打包,打包到文件.git/packed-refs中:git pack-refs --all --prune;
2)丢弃90天前的reflog记录:git reflog expire --all;
3)对松散对象进行打包:git repack:凡是有引用关联的对象都被打包,未被关联的对象仍旧以送松散对象的形式保存;
4)清除未被关联的对象。默认只清楚2周以前的未被关联的对象。
5)其他清理:对合并冲突的历史记录进行过期操作。
git gc -- prune=<date> 中时间参数是传递给git prune --expire <date>实现对指定日期之前的未被关联的松散对象进行清理。
git gc会在部分git命令下会自动执行,如git merge, git receice-pack, git rebase -i, git am 等。 共享式写操作的git版本库因为会push触发自动gc,非独立工作的本地库要pull merge触发自动gc。
git gc触发的条件:松散对象只有超过一定数量才会只写。在统计松散对象数量时,为降低在.git/objects目录下搜索松散对象对系统造成的负担,实际采取取样搜索,即只对对象库下的一个子目录.git/objects/17进行文件搜索。在默认配置下,只有该目录中对象数目超过27个才会触发版本库的整理。至于为什么只在对象库中选择一个子目录进行松散对象搜索,这是因为SHA1哈希值是完全随机的,文件有前2位哈希值组成的文件中差不多是平均分布的。gc.auto是触发版本库整理的全部松散对象树的阈值。