定位问题步骤一: 通过文件大小查看
下载的代码--查看各个文件的大小
du -h -d 1./
首先查看包对象的
git count-objects -vH
计算解包的对象数量及其磁盘消耗量
显示所有的分支
git branch -r | awk '{print $1}'
###awk求和、平均值、最大小值
求和 cat data|awk '{sum+=$1} END {print "Sum = ", sum}'
查看各个分支的大小 branch size stats
for name in `git branch -r | awk '{print $1}'`; do echo -n $name" - "; git ls-tree -rl $name | awk '{sum+=$4}END{print sum / 1000000 "MB"}'; done | sort -k3g
定位问题步骤二:通过大文件查看
1.列出blob
找出要清理的大文件
####找出排名前 5 的 pack 记录:
git verify-pack -v .git/objects/pack/pack-*.idx | sort -k 3 -g | tail -5
35d21063a704dd90d241ae609af3f3f2ef14b321 blob 117450646 20768943 2317375723
2.blob的名称和hash
列出提交包含的文件--大文件对应的hash和名称
###第一行的字母其实相当于文件的id,用以下命令可以找出id对应的文件名
-- 根据上面提交id看文件
--- 找出大文件所在的位置 git rev-list --objects --all|grep 35d21063a704dd90d241ae609af3f3f2ef14b321
git rev-list --objects --all | grep 35d21063a704dd90d241ae609af3f3f2ef14b321
blob的内容和hash
git cat-file 命令显示版本库对象的内容、类型及大小信息
git cat-file -p 35d21063a704dd90d241ae609af3f3f2ef14b321
git cat-file -p 对象 hash 值 查看对象的内容
3.blob对应的commit
Which commit has this blob?
控制显示的记录格式,常用的格式占位符写法及其代表的意义如下
示例
obj_name="35d21063a704dd90d241ae609af3f3f2ef14b321"
git log --all --pretty=tformat:'%T %h %s' \
| while read tree commit subject ; do
if git ls-tree -r $tree | grep -q "$obj_name" ; then
echo "$obj_name" $commit "$subject"
fi
done
##中文意思为,安静模式,不打印任何标准输出。如果有匹配的内容则立即返回状态值0。
'%H': commit hash
4.commit相关的分支
git branch --contains 553095e --all
5. 查看log
git log --follow src/plng_nod237.txt
解决方式
方式一: 没合并到主分支的情况下,删除相应分支和使用到该commit 的分支
方式二: 使用filter-branch抹掉错误提交的大文件提交记录,彻底清理.git目录
####处理大文件 filter-branch 改写了commit历史
git filter-branch --index-filter 'git rm --cached --ignore-unmatch crawel.pdf '
# git stash
git filter-branch --force --prune-empty --index-filter 'git rm -rf --cached --ignore-unmatch crawel.pdf' --tag-name-filter cat -- --all
–prune-empty 选项告诉git,如果因为重写导致某些commit变成了空(比如修改的文件全部被删除),那么忽略掉这个commit。
–index-filter 选 项指定重写的时候应该执行什么命令,要执行的命令紧跟在它的后面,在这里就是git rm --cached --ignore-unmatch
–tag-name-filter 表示对每一个tag如何重命名,重命名的命令紧跟在后面,当前的tag名会从标注输入送给后面的命令,用cat就表示保持tag名不变。
紧跟着的-- 表示分割符,
最后的 -–all 表示对所有的文件都考虑在内
说明
维护着一个微型的文件系统,其中的文件也被称作数据对象。所有的数据对象均存储于项目下面的 .git/objects
Git维护两个主要的数据结构:
对象库(object store)和索引(index)
:块(blob)、目录树(tree)、提交(commit)和标签(tag)
blob, 就是单个的文件; blob对应的commit的哈希值
tree, 就是一个文件夹 tree对象解决文件名的问题
原理说明:
使用filter-branch抹掉错误提交的大文件提交记录,彻底清理.git目录
1.出现原因:
大文件放到了项目下,提交的时候又push到远程仓库去了,虽然后来把文件删掉了重新提交,
但Git保存了每个文件的前生后世 防止哪天又要找回你删除过的文件,
导致项目下的.git子目录依然存在这些大文件的提交记录,占用大量空间
git版本保存导致大文件仍会被记录用于之后回滚需要
.pack 是包文件,这个文件包含了从文件系统中移除的所有对象的内容
.idx是索引文件,这个文件包含了包文件的偏移信息
2.解决方式
用filter-branch,这个命令就可以修改历史提交记录,从而达到清理错误提交记录。
需要提交就再执行
git add 都会生成一个Git对象,称为blob 对象,存放在objects目录下
将Blob对象合并成一个包文件,同时会生成一个索引文件,索引文件中包含了每个Blob对象在包文件中的偏移信息,Git在打包的过程中使用了增量编码方案
删除pack中无用的大文件缓存
查看提交记录
参考
https://stackoverflow.com/questions/223678/which-commit-has-this-blob/223890#223890