我们将客户端迁移到了一个网站。我们的代码在一个单独的分支上,然后合并到master和release中。对于其他功能,Master已经多次分支。所有这些分支使得存储库比我在网络上找到的示例稍微复杂一些。
我们现在意识到客户端的原始媒体 - 主要是图像和一个大的CSV文件 - 也被检入Git。虽然它只有12MB左右,但有几个理由可以删除它(尤其是客户端的文件名具有非ASCII字符,这些字符与我们在OSX上的Vagrant box的共享文件夹一起播放。)以下是存储库的大小细分:
$ du --max-depth 1 -h
12M ./.git
13M ./modules
2.0M ./themes
27M .
虽然二进制文件显然现在存在于多个分支上,但据我所知,我应该能够执行以下操作来删除二进制文件,然后删除与它们对应的存储库对象:
$ git filter-branch --tree-filter "git rm -rf --ignore-unmatch modules/custom/mymigration/data/photos/*" # Did this with and without "HEAD" argument
[snip lots of output]
$ git reflog expire --expire=now --all
$ git gc --aggressive --prune=now
但是,我仍然有一个很大的.git子文件夹:
$ du --max-depth 1 -h
12M ./.git
1.4M ./modules
2.0M ./themes
15M .
最大的文件是.git / objects / pack / pack -.... pack。当我验证.idx文件时:
$ git verify-pack -v .git/objects/pack/pack-53c8077d0590dabcf5366589c3d6594768637f5e.idx | sort -k 3 -n | tail -n 5
我得到一长串对象。如果我将其传输到rev-list,并将grep传递给我的迁移数据目录:
$ for i in `git verify-pack -v .git/objects/pack/pack-53c8077d0590dabcf5366589c3d6594768637f5e.idx | sort -k 3 -n | tail -n 5 | awk '{print $1}'`; do
git rev-list --objects --all | \
grep $i | \
grep modules/custom/mymigration/data
done
47846536601f0bc3a31093c88768b522a5500c96 modules/custom/mymigration/data/photos/Turkey.jpg
b920e36357d855352f4fdb31c17772d21c01304d modules/custom/mymigration/data/photos/Burger_Top.JPG
然后你可以看到照片仍然在包文件中。
git clone file://path/to/old-repos new-repos
在本地克隆此存储库也具有相同的效果:更糟糕的是,我所有的原始分支都消失了(正如您可能期望的那样)所以我只有主人。我能做些什么来摆脱那些打包的物品?它们是否继续存在表明它们仍然与某些git提交对象相关联?我试过repack
和prune-packed
,但一切都没有改变。
此外,如果我只是“摆脱它们”,如果我没有正确完成第一位,是否有可能破坏?如果删除git提交仍然引用的文件对象会发生什么?
答案 0 :(得分:7)
以下工作可以重复地将存储库减少到大约2.5MB .git和5.8MB。它包括上面@jamessan提出的建议。
这将从所有分支中删除对象,并将这些删除推送到远程存储库。据我所知,那个远程存储库完全没有这些对象(存储库大小大幅下降。)
# Configure the repository to push all existing branches & tags
# when none are explicitly specified
git config --add remote.origin.push '+refs/tags/*:refs/tags/*'
git config --add remote.origin.push '+refs/heads/*:refs/heads/*'
# Make sure all local branches exist, so they get filtered
for remote_branch in `git branch --all | grep -v HEAD | sed -e 's/\*//'`; do local_branch=`echo $remote_branch | sed -e 's!remotes/origin/!!'`; git checkout $local_branch; done
# Prevent git <1.7.7.1 from complaining about dirty working directory
git update-index -q --ignore-submodules --refresh
# Do the filtering across --all branches and rewrite tags
# Note that this will necessarily remove signatures on tags
git filter-branch -f --tree-filter "git rm -rf --ignore-unmatch modules/custom/mymigration/data/photos/*" --tag-name-filter cat -- --all
# Remove the backed-up refs
git for-each-ref --format="%(refname)" refs/original/ | xargs -n 1 git update-ref -d
# Clear out the reflog and garbage-collect
git reflog expire --expire=now --all
git gc --aggressive --prune=now
# Push all changes to origin - pushes tags and branches
git push origin
答案 1 :(得分:2)
git-filter-branch手册页的底部描述了缩小存储库的两种方法。
简单的方法是再次克隆存储库
git clone file:///path/to/repo
更复杂的方法类似于你所做的(reflog expire,gc),但是你省略了第一步
删除由git-filter-branch备份的原始引用:git for-each-ref --format =“%(refname)”refs / original / | xargs -n 1 git update-ref -d