Split Git存储库,仅保留剩余文件的历史记录

问题描述 投票:0回答:2

我有一个git存储库,其中包含11个不同的独立项目(不要问我为什么****都在一个存储库中)。由于某些项目包含许多资产,因此gitlab表示,存储库的大小约为14.3 GB,这会导致巨大的签出时间(在我们的CI / CD系统上,长达20分钟)。

因为我们一次只构建一个项目,所以我想将所有项目都分离到不同的存储库中。因为项目A不需要与项目B的文件有关的提交,所以我想清除整个历史记录。

我已经尝试了不同的方法:

  1. 删除文件。这些文件已消失,但仍可通过历史记录获得。
  2. 使用简单的git filter-branch --prune-empty,但我想保留文件结构。
  3. git filter-branch --index-filter --prune-emptygit rm --cached --ignore-unmatch一起使用,但是我仍然可以恢复旧文件。
  4. 删除文件,并在--delete-folders中使用Git BFG。很好的结果,但是我只能提供一个glob / regex和一些包含其他项目名称的项目contaiting文件夹(命名错误...),这些文件夹也被删除了...

[最好的方法是像BFG那样工作的工具/命令,但允许我提供删除的路径或保留的更好的路径。

文件结构示例:

./
+- Project A/
+- Project B/
+- UI Projects/
|  +- Foo/
|  +- Bar/
+- Project E/
|  +- Foo/
|     +- Bar/
+- Build
   +- build_a/
   +- build_b/
   +- build_foo/
   +- build_bar/
   +- build_e/

我的要求是:

  • 保留的文件结构
  • 保留多个路径(例如,回购A的./Project A/./Build/build_a/
  • 已删除不再属于新存储库的文件的历史记录

有什么建议吗?

git git-filter-branch bfg-repo-cleaner
2个回答
0
投票

嗯...您在这里遗漏了更大的问题,但我会再谈一谈。根据要求解决您的问题:

您尝试过的选项中,filter-branch是应该起作用的选项。 (请注意,git有一个新工具filter-repo,建议他们优先使用filter-branch;但是我没有花时间进行切换,而且听起来您的filter-branch过程几乎可以正常工作,所以我将使用filter-branch ...)

解决问题

因此,您说在将filter-branchindex-filter结合使用后仍可以恢复已删除的文件。造成这种情况的原因可能有多种,但总的来说,git试图避免丢失数据,除非您确实确定不再需要它。因此:

  • filter-branch每当重写存储库引用时都会创建一组“备份引用”。那些“备份引用”仍然可以达到旧的历史]
  • 分支机构的引用日志提供了一种方法,可返回到这些分支机构先前指向的位置;这些历史reflog条目仍然可以达到旧历史

消除所有这些的最简单方法是从进行清理的存储库中重新克隆。如果确实要清理它,则需要(1)删除original名称空间下的引用; (2)使reflog过期或删除-我一直很难让git使它们过期,但是如果其他所有方法都失败rm -r .git/logs; (3)运行gc。对于这种类型的操作,我使用gc --force --aggressive --prune=now

现在...更大的问题是,如果将11个项目的历史合并为14.3GB,则每个项目的历史(平均)超过1GB-这仍然很可笑。您有一个更深层次的问题。国际海事组织将回购协议拆分是一个好主意(我不喜欢“ monorepo”趋势)。但您也应该尝试减少回购的总规模。

[您很可能在源代码管理下拥有大型二进制文件。很少建议这样做。如果确实需要这样做,则应使用git lfs之类的工具来保持核心存储库的规模小且易于管理。但是,如果您只是存储构建工件或依赖项或类似的东西,则最好查看工件存储库(artifactory,nexus等)。这可能需要改进的构建工具来管理依赖项版本


0
投票

以下树过滤器满足您的要求:

find . ./Build -maxdepth 1 -path . -o -path ./Build -o -path "./Project A" -o -path ./Build/build_a -o -exec rm -rf {} +

用实际项目名称替换Project Abuild_a。您可以按照./Build文件夹的示例添加其他路径。

将其传递给filter-branch的--tree-filter选项:

git filter-branch --tree-filter '...' --tag-name-filter cat --prune-empty -- --all
© www.soinside.com 2019 - 2024. All rights reserved.