清理git服务器上的大文件

时间:2015-08-11 03:09:28

标签: git gitlab

有人意外地将一些大型(多GB)二进制文件提交给我自己托管的gitlab存储库,现在每当有人试图从存储库中取出时,服务器就会受到严重打击。

我尝试通过强制推送删除对文件的任何引用,但它似乎仍然影响服务器。有没有办法强制gitlab服务器摆脱它?

我读了一些像filter-branch这样的东西,但我不确定那会对裸仓库做什么,或者我甚至在提交时使用它我不再有引用。

更新:作为参考,这些类型的消息出现在gitlab VM的控制台上:

[ 5099.922896] Out of memory: kill process 6200 (git-upload-pack) score 1053982 or a child
[ 5099.922908] Killed process 6202 (git)
[ 5099.930796] Out of memory: kill process 6200 (git-upload-pack) score 360394 or a child
[ 5099.930807] Killed process 6203 (git)
[ 5099.938875] Out of memory: kill process 6200 (git-upload-pack) score 360394 or a child
[ 5099.938886] Killed process 6203 (git)
[ 5099.951163] Out of memory: kill process 6139 (git-upload-pack) score 324327 or a child
[ 5099.951174] Killed process 6151 (git)

3 个答案:

答案 0 :(得分:8)

OP Karl确认in the comments时,在服务器端(直接在裸仓库中)运行BFG repo cleaner足以删除大型二进制文件。

如果您遵循(如“Git - Delete a Blob”中所述):

rm -rf .git/refs/original/
git reflog expire --expire=now --all
git gc --prune=now
git gc --aggressive --prune=now

但也(“git gc --aggressive vs git repack”):

git gc
git repack -Ad      # kills in-pack garbage
git prune           # kills loose garbage

你应该得到一个更纤薄,更小的裸露回购。

答案 1 :(得分:2)

为此,您将打破从此提交推送的任何存储库的历史记录。你必须告诉他们。

您需要的是重新绑定远程存储库并删除此提交。

首先,在您的存储库中进行rebase。

.tag {
    top: 0px;
    right: 0px;
    min-height: 0px;
}

.tag {
    font-size:14px;
    font-family:'Droid Serif';
    text-align:center;
    color:#FFF;
    margin-left:15px;
    padding:6px;
    background-color:red;
    float:right;
    z-index:3;
    display:block;
    position:absolute;
}

.box {
    width: 400px;
    padding: 40px;
    background-color:blue;
}

.title {
    color:green;
    background-color:white;
    font-style:40px;
    font-weight:bold;
}

这将打开您的默认编辑器。删除commit problematicCommit的提交行。保存文件并关闭它。

删除远程存储库中的分支。

git rebase -i problematicCommit~1

查看分支名称前面的点。

最后,再次创建遥控器中的分支。

git push origin :nameOfTheBranch

这会在没有冲突提交的情况下重新生成远程分支,新克隆将再次快速。

现在,如果您仍然注意到您的存储库运行缓慢。您可以删除它所拥有的未跟踪对象(例如具有此大文件的对象)。

首先,删除所有可能指向旧提交的标签,分支。这很重要,因为为了能够删除旧的提交,它们必须是未跟踪的。

然后,按照VonC评论stackoverflow.com/a/28720432/6309 - 在存储库和远程中执行:

git push origin nameOfTheBranch

答案 2 :(得分:1)

遇到相同的问题,解决该问题的过程相当复杂。

我们在 Docker 容器中运行由社区维护的sameersbn/gitlab 11.4.5 。我不想在那里安装bfg,但选择在本地执行更改。

# Install the bfg tool, ex. on MacOS via homebrew
brew install bfg

# Clone repo locally
cd ~/Development
git clone --mirror ssh://git@server.com:22/some/dir/myrepo.git

# Clean the repo
bfg --delete-files \*.pdf myrepo.git
cd myrepo.git
rm -rf .git/refs/original/
git reflog expire --expire=now --all
git gc --prune=now
git gc --aggressive --prune=now

# Upload to container-host, e.g. via FileZilla

# Connect to the container-host via ssh

# Rename the original directory in the container, to have a backup
docker exec -it gitlab /bin/bash
mv /home/git/data/repositories/some/dir/myrepo.git /home/git/data/repositories/some/dir/myrepo.git.mybackup
exit

# Copy from container-host into container
docker cp /root/Documents/myrepo.git gitlab:/home/git/data/repositories/some/dir/myrepo.git

# Fix permissions in container
docker exec -it gitlab /bin/bash
cd /home/git/data/repositories/some/dir/myrepo.git
find . -type f -print0 | xargs -0 chown git:git
chown -R git:git /home/git/data/repositories/some/dir/myrepo.git
chmod 770 /home/git/data/repositories/some/dir/myrepo.git

# Re-create the "hooks" subdir with some symlinks in the repo
cd /home/git/gitlab/bin
./rake gitlab:shell:create_hooks

# Clear Redis cache (unclear if needed)
./rake cache:clear
exit

# Clone the changed repo locally again, also tell everyone who got a copy to clone again (history is broken now)

# Then do a commit to the repo, to hit the hook and trigger a size recheck