使用重写的Git repo历史记录更新开发团队,删除大文件

rlk*_*024 32 git project-planning git-filter-branch git-rewrite-history

我有一个git repo,里面有一些非常大的二进制文件.我不再需要它们,我不关心是否能够检查早期提交的文件.因此,为了减少repo大小,我想从历史中删除二进制文件.

在网络搜索之后,我得出结论,我最好的(仅?)选项是使用git-filter-branch:

git filter-branch --index-filter 'git rm --cached --ignore-unmatch big_1.zip big_2.zip etc.zip' HEAD
Run Code Online (Sandbox Code Playgroud)

到目前为止,这似乎是一个好方法吗?

假设答案是肯定的,我还有另外一个问题需要解决.该git的手册中有这样的警告:

警告!重写的历史将具有所有对象的不同对象名称,并且不会与原始分支会聚.您将无法在原始分支的顶部轻松推送和分发重写的分支.如果您不知道完整的含义,请不要使用此命令,并且无论如何都要避免使用它,如果简单的单个提交就足以解决您的问题.(有关重写已发布历史记录的详细信息,请参阅git-rebase(1)中的"从上游重新恢复"部分.)

我们的服务器上有一个远程仓库.每个开发人员都会推动并从中拉出.基于上面的警告(以及我对git-filter-branch工作原理的理解),我认为我不能git-filter-branch在本地副本上运行然后推送更改.

所以,我暂时计划完成以下步骤:

  1. 告诉我的所有开发人员提交,推送和停止工作.
  2. 登录服务器并在中央存储库上运行过滤器.
  3. 让所有人删除旧副本并从服务器再次克隆.

这听起来不错吗?这是最好的解决方案吗?

cdh*_*wie 18

是的,您的解决方案将起作用.您还有另一种选择:在中央存储库上执行此操作,在克隆上运行过滤器,然后将其推回git push --force --all.这将强制服务器接受存储库中的新分支.这仅取代了第2步; 其他步骤将是相同的.

如果你的开发人员非常精通Git,那么他们可能不必删除他们的旧副本; 例如,他们可以根据需要获取新的遥控器并重新设置其主题分支.


Rob*_*ley 9

你的计划很好(虽然最好是在你的存储库的裸克隆上进行过滤,而不是在中央服务器上),但是git-filter-branch你应该使用我的BFG Repo-Cleaner,这是一种更快,更简单的git-filter-branch设计方案.专门用于从Git repos中删除大文件.

下载Java jar(需要Java 6或更高版本)并运行以下命令:

$ java -jar bfg.jar  --strip-blobs-bigger-than 1MB  my-repo.git
Run Code Online (Sandbox Code Playgroud)

任何大小超过1MB的blob(不在最近的提交中)都将从存储库的历史记录中完全删除.然后,您可以使用git gc清除死数据:

$ git gc --prune=now --aggressive
Run Code Online (Sandbox Code Playgroud)

BFG通常比运行速度快10-50倍,git-filter-branch并且这些选项围绕这两种常见用例进行了定制:

  • 删除疯狂的大文件
  • 删除密码,凭据和其他私人数据


Ben*_*son 5

如果你不让你的开发人员重新克隆它,他们可能会设法将大文件拖回来.例如,如果他们仔细地拼接到新的历史记录,你将创建,然后碰巧git merge来自当地的项目分支如果没有重新定位,合并提交的父母将包括项目分支,该分支最终指向您删除的整个历史记录git filter-branch.