如何在不克隆大型仓库的情况下将大型Git存储库拆分为多个小型独立存储库

时间:2018-02-15 11:48:22

标签: git github

我有一个巨大的git repo,它有多个活动功能分支,里面包含很多文件夹 .Below是我Git的结构。

BigRepo/
    .git
     F1
     F2
     F3

我想将上述每个文件夹F1 / F2 / F3拆分为一个单独的git repos,保留与它们和历史相关的所有实时分支。以下是我的期望:

F1/
  .git
F2/
  .git
F3/
  .git

我已经查看了以下链接:

[Detach (move) subdirectory into separate Git repository

我不想克隆大回购。此外,当创建新的repo时,我想查看所有实时分支和提交历史记录

有没有办法可以通过移动/复制文件夹并动态创建回购来实现这一目标?

感谢帮助。

2 个答案:

答案 0 :(得分:3)

首先要做的事情:

  

有没有办法可以通过移动/复制文件夹并动态创建回购来实现这一目标?

没有。 git不是cvsgit的结构从根本上不支持你所要求的。提交 - 跟踪历史记录的对象 - 由整个项目的快照组成。没有任何对象或对象集合代表“恰好是f1子目录的历史”。 足够的信息,您可以生成这样的对象,但要这样做,您需要克隆(或直接访问原点)。

当你说明不克隆的原因时,请注意评论:

  

我不想克隆有两个原因:1。它只为一个分支创建一个repo。我们有很多巨大的回购,我想摆脱克隆开销

原因1不正确。克隆时,默认情况下复制所有分支。即使您已经设置了一个不默认复制所有内容的配置,您仍然可以复制所有内容。

原因2是一个很好的想法,但是你无法进行将回购(包括历史)与任何小于回购的完整副本的东西分开所需的操作级别。因此,如果您可以登录服务器并且可以在文件系统上访问存储库,那么您可以在那里进行工作;但除此之外,你必须克隆它。做一次,拆开回购,你再也不用了。

最后

  

此外,当创建新的repo时,我想查看所有实时分支和提交历史记录

在正确克隆回购后,您可以使用git filter-branch --subdirectory-filter f1 -- all重写历史记录并生成您的第一个“新”回购。

然后你克隆它。

然后使用originals/*

下存储的备份引用返回并将所有分支恢复到之前的状态

然后,您要为要突破的其他目录重复。

答案 1 :(得分:0)

这很容易有效地完成。您正在做的是将新的提交引用添加到现有历史的部分内容中。

安全地进行主要refname手术的基线是共享对象克隆,它通过引用使用基础repo的对象db。使用heavyyduty filter-branch最适合在tmpfs:

$ProductSubCategory

克隆基本上是免费的:

git clone -s --mirror . ${scratch=`mktemp -d`}
cd $scratch

因此,您现在可以完全自由地进行任何想要的refname手术,并将结果推送到任何您想要的地方。

$ time git clone -s --mirror . ${scratch=`mktemp -d`}
Cloning into bare repository '/tmp/jthill/tmp.MmqbLpe038'...
done.

real    0m0.073s
user    0m0.049s
sys     0m0.029s
$ du -sh $scratch
240K    /tmp/jthill/tmp.MmqbLpe038
$ git -C $scratch remote -v
origin  /home/jthill/src/linux/. (fetch)
origin  /home/jthill/src/linux/. (push)
$ git for-each-ref |wc
   2296    6888  148695
$ git -C $scratch for-each-ref |wc
   2296    6888  148695

在我的小盒子上提取并提升34337(835327)$ cd $scratch $ git filter-branch --subdirectory-filter Documentation --tag-name-filter cat -- --all -- Documentation 提交约15分钟。

编辑:重写标签没有得到优化,它正在研究每个标签的完整历史记录,有数千个标签和数十年的历史记录,每个标签需要几秒钟: - (