繁体   English   中英

从git中删除大型提交

[英]Remove large commits from git

我们正在运行一个中央git存储库(gforge),每个人都会从中推出并推送。 不幸的是,一些无能的同事已经决定将几个10-100Mb jar文件推入回购中是一个好主意。 因此,我们使用的服务器已经耗尽了磁盘空间。

我们才意识到这一点,为时已晚,大多数人已经撤回了新的大型回购。 如果没有推出问题,那么我们可以做一个rebase来剪掉那些巨大的提交并修复它,但是现在每个人都已经从中撤出了,删除该提交的最佳方法是什么(或者做一个rebase to just删除大文件)当每个人都想从/向回购/推送/推送时,这不会导致混乱?

它应该是脚本的小型回购,但现在大小约为700M :-(

避免混乱的最简单方法是为服务器提供更多磁盘。

这是困难的一个。 删除文件也需要从历史记录中删除它们,这只能通过git filter-branch 例如,此命令将从历史记录中删除<file>

git filter-branch --index-filter 'git rm --cached --ignore-unmatch <file>' \
--prune-empty --tag-name-filter cat -- --all

问题是这会重写SHA1哈希值,这意味着团队中的每个人都需要重置为新的分支版本,否则会有一些严重的问题。 如果没有人正在进行中并且你们都使用主题分支,这一切都很好。 如果你更集中,你的团队很大,或者他们中的许多人在工作时保持脏工作目录,没有一点混乱和不和谐就没有办法做到这一点。 你可以花很长时间让每个人的本地工作正常。 那个写的, git filter-branch可能是最好的解决方案。 只要确保你有一个计划,你的团队了解它,并确保他们备份他们的本地存储库,以防一些正在进行的重要工作丢失或被摧毁。

一个可能的计划是:

  1. 让团队生成正在进行的工作的补丁,例如git diff > ~/my_wip
  2. 让团队为他们承诺但未共享的工作生成补丁: git format-patch <branch>
  3. 运行git filter-branch 确保团队知道在发生这种情况时不要拉扯。
  4. 让团队发出git fetch && git reset --hard origin/<branch>或让他们重新克隆存储库。
  5. 使用git am <patch>应用他们以前提交的工作。
  6. 使用git apply应用他们正在进行的工作,例如git apply ~/my_wip

看看这个https://help.github.com/articles/remove-sensitive-data 在这里,他们写了关于从Git存储库中删除敏感数据的文章,但您可以很好地使用它从提交中删除大文件。

除了其他答案之外,您可能还需要考虑在回购中以预先接收挂钩的形式为未来的巨型jar文件添加一些先发制人的保护,禁止用户(或至少是“非管理员用户”)从推送非常大的文件,或名为*.jar文件,或任何看起来最好的文件。

我们之前已经做过这样的事情,包括禁止特定的提交ID,因为某些用户无法理解“将你的工作保存在临时分支上,重置和拉动,重新应用你的工作,减去巨型文件“。

请注意,预接收挂钩运行在一个相当有趣的上下文中:文件实际上已经上传,只是引用(通常是分支头)尚未实际更改。 您可以阻止分支头更改,但您仍将使用(临时,直到gc'ed)磁盘空间和网络带宽。

使用filter-branch!

git filter-branch --tree-filter 'find . -name "*.jar" -exec rm {} \;'

然后只需清除所有没有任何文件的提交:

git filter-branch -f --prune-empty -- --all

GForge家伙在这里。 即使认为这主要是一个git问题,我想提供两件事:

  1. 从GForge 6.3开始 ,站点管理员可以识别使用过多磁盘的项目,以及旧的和孤立的项目。 这可以帮助您避免全盘情况,特别是如果您有许多单独的团队和项目。
  2. 在GForge中轻松实现git钩子(一般的SCM钩子)。 站点管理员可以配置任意数量的挂钩命令,然后项目级别的人员可以选择他们想要的项目挂钩。 添加一个阻止某些类型(或大小?)文件的钩子将非常适合此功能。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM