..
【翻译】给git仓库瘦身
某些特殊的原因,我们不小心把一个较大的文件加入到了 git 仓库,并且我们提交了它,git 仓库的大小会瞬间的膨胀起来,有些时候,我们甚至都不知道我们加入的是那个大文件导致,即使我们找到了这个文件,将他从 git 仓库中删除了,但是仓库并没有完全的变小,因为在 .git 这个文件中还保存着这个大文件的内容。我们处理这个问题分三个步骤:
- 找到这个大文件
- 将大文件从仓库中删除
- 修改 .git 服务器中的文件
clone仓库
如果你本地还没有仓库,那么你应该先将仓库下载到本地
git clone remote-url
现在你本地有这了这个仓库了,但是你还没有全部的分支,为了保证大文件能能够完全的干净的删除,你需要获取所有的分支,完成这个工作,你还需要一个脚本:
for branch in `git branch -a | grep remotes | grep -v HEAD | grep -v master`; do
git branch --track ${branch##*/} $branch
done
找到大文件
这里有一个脚本,帮助我们找到那个大文件
#!/bin/bash
#set -x
# Shows you the largest objects in your repo's pack file.
# Written for osx.
#
# @see http://stubbisms.wordpress.com/2009/07/10/git-script-to-show-largest-pack-objects-and-trim-your-waist-line/
# @author Antony Stubbs
# set the internal field spereator to line break, so that we can iterate easily over the verify-pack output
IFS=$'\n';
# list all objects including their size, sort by size, take top 10
objects=`git verify-pack -v .git/objects/pack/pack-*.idx | grep -v chain | sort -k3nr | head`
echo "All sizes are in kB. The pack column is the size of the object, compressed, inside the pack file."
output="size,pack,SHA,location"
for y in $objects
do
# extract the size in bytes
size=$((`echo $y | cut -f 5 -d ' '`/1024))
# extract the compressed size in bytes
compressedSize=$((`echo $y | cut -f 6 -d ' '`/1024))
# extract the SHA
sha=`echo $y | cut -f 1 -d ' '`
# find the objects location in the repository tree
other=`git rev-list --all --objects | grep $sha`
#lineBreak=`echo -e "\n"`
output="${output}\n${size},${compressedSize},${other}"
done
echo -e $output | column -t -s ', '
执行这个脚本,你将看到如下的内容:
All sizes are in kB. The pack column is the size of the object, compressed, inside the pack file.
size pack SHA location
1111686 132987 a561d25105c79aa4921fb742745de0e791483afa 08-05-2012.sql
5002 392 e501b79448b9e970ab89b048b3218c2853fdfc88 foo.sql
266 249 73fa731bb90b04dcf79eeea8fdd637ba7df4c089 app/assets/images/fw/iphone.fw.png
265 43 939b31c563bd40b1ca70e4f4a9f7d67c27c936c0 doc/models_complete.svg
247 39 03514d9e84418573f26b205bae7e4e57057c036f unprocessed_email_replies.sql
193 49 6e601c4067aaddb26991c4bd5fbddef003800e70 public/assets/jquery-ui.min-0424e108178defa1cc794ee24fc92d24.js
178 30 c014b20b6fed9f17a0b2809ac410d74f291da26e foo.sql
158 158 15f9e56bc0865f4f303deff053e21909661a716b app/assets/images/iphone.png
103 36 3135e15c5cec75a4c85a0636b154b83221020c97 public/assets/application-c65733a4a64a1a885b1c32694574b12a.js
99 85 c1c80bc4c09e692d5e2127e39c87ecacdb1e816f app/assets/images/fw/lovethis_logo_sprint.fw.png
现在,你已经看到了,最大的那个文件是一个1.1GB的SQL dump文件。
清除大文件
清理大文件会花掉相当长的一段时间,这取决你仓库的使用频率,你只需要执行如下命令即可:
git filter-branch --tag-name-filter cat --index-filter 'git rm -r --cached --ignore-unmatch filename' --prune-empty -f -- --all
这里的 filename 填写你需要删除的文件的名字或者是通配符。然后继续执行如下的命令:
rm -rf .git/refs/original/
git reflog expire --expire=now --all
git gc --prune=now
git gc --aggressive --prune=now
至此,你可以使用 du -sh 命令查看,仓库大小已经变小了很多。
发布本地仓库
现在只是本地仓库变小了,我们需要将我们的更改发布到远程仓库.
git push origin --force --all
git push origin --force --tags
现在再次 clone 仓库,发现仓库变小了很多。