是否有可能在GitHub上清除一个提交错误的远程repo文件?

时间:2018-04-17 03:12:51

标签: git github jenkins-plugins github-enterprise .git-folder

背景:我已经为我们公司使用的GitHub企业版上远程托管的其中一个存储库出现了嵌套问题。

我认为处理它的最简单的方法是给出repo的年龄,以某种方式删除那些本来就不应该提交的旧的硬提交文件,这些文件可能直接或通过引用存储在某处。它的诀窍是,如果可以帮助我,我不想弄乱历史,而且我不太了解更高级的git功能,所以很难甚至知道什么是正确的问题。

问题:通过GitSCM插件,通过Jenkins拉取/取出回购时间太长了。大约10分钟后它会超时。这个repo有成千上万的提交和几十个标记来跟踪,所以我不能任意设置一个特定的提交作为开始和截断其余部分的好点。

我的发现:尝试做GitSCM插件似乎正在做的事情几乎不会导致问题或时间要求。也就是说,它仍然非常慢,只是不是10 + - 分钟 - 慢,所以我们应该清理它,即使插件引入了加剧的性能问题。

可能的优化:我发现有几个提交主要是DLL的添加。这些DLL已经通过新提交删除。但是,repo的大小仍然是数百兆字节,而实际使用的是本地文件系统。现在,主分支在.git文件夹外大约4MB,大约300 MB。

目标:尽可能多地消除300 MB的MB而不会因丢失历史记录/标签而惹恼人们

我已经从可能相关的问题中尝试了许多解决方案,但是我还没有能够将远程托管仓库缩小到更接近文件系统使用的实际大小的位置。其中一些问题是,

Reduce git repository size
How to remove unused objects from a git repository?
Why won’t git further reduce the repository size?

在尝试了这些问题的解决方案之后,我最终只增加了回购的大小,而不是减少它,这是公平的,我在其中一个问题中被警告过。答案。

鉴于此问题的背景,问题详细信息以及之前引用的问题可以实现我尝试在远程托管的回购中执行的操作,如果是,我应该具体运行或询问什么如果我个人无法进行更新,我们的GHE管理员可以运行吗?

最终导致它增长:

git reflog expire --all --expire=now
git gc --prune=now --aggressive
git filter-branch --index-filter "git rm --cached --ignore-unmatch *.dll" --prune-empty -- --all
git push origin master

然而,在运行前两个命令后,我只看到.git文件夹的大小减少了40 MB;远远不是我所希望的,这就是为什么我尝试了序列中的下一个命令,当远程推动时导致repo增长而不是缩小。对象数从大约45k增加到60k。

2 个答案:

答案 0 :(得分:1)

  

这就是它的诀窍,如果可以帮助我,我不想弄乱历史,

但是你会:git filter-branch或(更容易使用)BFG repo cleaner将重写该repo提交的历史记录(SHA1s),迫使你git push --force返回最终结果到远程仓库 考虑到回购陈旧(即不再积极维护),这不是什么大问题,但仍需要考虑。

  

通过GitSCM插件,通过Jenkins拉回/取出回购时间太长了。

詹金斯不应该参与其中:您可以在本地克隆回购,清理它并将其推回。
另外,可以提高Jenkins的超时时间。

  

最终导致它增长:

那些reflog / gc命令应该在过滤器分支或BFG后使用,而不是之前。

答案 1 :(得分:1)

我不会接受我自己的答案。 VonC做了一个令人钦佩的任务,试图在评论中按摩答案,以满足我非常具体的要求,这可能不会让其他人回到类似问题 - 此外,VonC确实提到使用BFG,这最终解除了我的阻碍。只使用git来实现这一点本来不错,但由于BFG完全免费(并且速度比git filter-branch快),我不能忽视它作为处理git问题的替代方法。

要通过减少.git文件夹中的repo-size来解锁我们的远程构建,我使用了免费工具BFG Repo Cleaner并完全按照其说明进行操作。它将.git文件夹的大小从原始的300MB大小缩小到80MB。考虑到这个repo有超过7k的提交,我不会抱怨.git文件夹仍然很大。这个操作肯定加快了能够克隆回购的过程。

操作方法

完全披露:其中一些步骤直接从BFG Repo Cleaner的文档中复制,该文档链接到步骤#2。它还假设您使用的是Windows,因此请根据需要更新shell语法。

  1. 如果您还没有Java,请安装Java
  2. 从他们的网站here抓取免费工具BFG Repo Cleaner,这也是他们的文档页面
  3. 如果您不想删除.DLL的所有文件类型,请执行与我完全相同的操作,请查看BFG的简要文档以了解其他可用文件
  4. 打开命令控制台并使用--mirror为您的回购执行浅层克隆,如下所示:
    git clone --mirror https://github.com/some-big-repo.git
  5. 如果您的路径中没有java.exe,请暂时将该目录添加到PATH Set PATH=%PATH%;C:\PathToJavaBin,或直接调用,并确保更新此命令JAR文件的名称,因此下面的命令与文件系统中的命令相匹配,如下所示:
    C:\PathToJavaBin\java.exe -jar C:\PathToBFGJar\bfg.jar --delete-files *.dll some-big-repo.git
  6. 运行cd some-big-repo.git
  7. 运行git reflog expire --expire=now --all
  8. 运行git gc --prune=now --aggressive
  9. 运行git push
  10. 就是这样:)