如何将SVN转换为GIT,同时将一个巨大的存储库拆分为单独的存储库?



我想把我们的SVN存储库迁移到git.

我们当前的存储库是一个巨大的单例堆,包含了许多Visual Studio解决方案,它们都位于存储库的不同子目录中。

当将其转换为git时,我想将SVN存储库拆分为每个解决方案的单独git存储库,同时维护每个解决方案的历史。

我不希望在我们未来的所有git存储库中都包含整个SVN存储库的历史。在这些未来的git存储库中,我想要的只是特定子目录的历史记录。

这可能吗?


当前SVN存储库文件结构:

svn_base
|-- Solution1
|   |-- 1.cs
|   |-- 1.csproj
|   |-- 1.sln
|-- Solution1
|   |-- 2.cs
|   |-- 2.csproj
|   |-- 2.sln
|-- Solution3
|   |-- 3.cs
|   |-- 3.csproj
|   |-- 3.sln

期望的git责任文件结构:

Solution1
|-- .git
|-- 1.cs
|-- 1.csproj
|-- 1.sln
Solution2
|-- .git
|-- 2.cs
|-- 2.csproj
|-- 2.sln

Solution3
|-- .git
|-- 3.cs
|-- 3.csproj
|-- 3.sln

虽然@acran给出的答案确实解决了问题,但首先将SVN存储库转换为Git,然后将大的单一存储库拆分为多个较小的存储库也是可能的,有时也是有利的。

1。转换SVN到Git

如果你的SVN存储库有一个标准的布局(子目录branches,tagstrunk),你不需要任何其他的花哨的东西,这是很容易的:

$ git svn clone <url_to_subversion_repo>

这个命令有两个陷阱:

  1. git svn使用SVN登录名作为Git作者名。它还使用一些默认的邮件地址(我想是@localhost,尽管我不确定)。如果这不是您想要的,您可以使用authors文件。添加SVN用户到git用户的映射文件user_mapping.txt
    svn_user_1 = Git User 1 <user1@example.com>
    svn_user_2 = Git User 2 <user2@example.com>
    
    然后用这个文件调用git svn clone:
    $ git svn clone --authors-file=user_mapping.txt <url_to_subversion_repo>
    
  2. 由于SVN的标签可以更改,git svn将它们作为Git分支导入。如果你愿意,你可以转换它们。

git svn clone按顺序从SVN服务器检查出SVN repo的每个版本-如果您有一个大的存储库,这将需要一段时间(我的经验是,大约50,000个版本需要多个小时,我想,尽管我不确定,这是几年前的事情)。如果可能,您可能希望在SVN服务器上运行该命令,特别是在连接速度较慢的情况下。不管怎样,去喝杯咖啡(或五杯)。

2。拆分Git存储库

有多个工具可以将Git库拆分为子库。请看下面这个问题。当我几年前这样做的时候,我用的是git filter-branch,但是这个工具现在已经被弃用了——你可以仍然使用它,或者你可以使用git filer-repo,尽管我没有任何使用这个工具的经验。

对我链接的问题的最多支持的答案使用git subtree filter-我建议而不是使用这个答案,因为git subtree filter只转换一个分支,实际上是从子存储库中删除所有其他分支。

优势与通过git svn clone转换每个子存储库相比,这个答案的优点是什么?

  • 您只需要克隆SVN存储库一次。这可能比克隆每个项目的子文件夹要快(尽管我没有测试过,这只是一个有根据的猜测)。
  • 克隆具有标准布局的SVN存储库比克隆具有非标准布局的SVN存储库更好。根据我的经验,git svn并不总是做你想要的,所以一个更标准的用法可能更有可能产生你想要的结果。
  • 如果您想重写新Git存储库的历史记录(例如,删除大的二进制文件),您可以在步骤1和步骤2之间重写monorepo的历史记录。对于每一个新的子存储库,这将是一个更大的努力。

如果您的项目被整齐地划分到它们自己的子目录中,那么使用--trunk参数到git svn init/git svn clone应该是非常直接的:

git svn clone --trunk=Solution1 $SVN_URI ./Solution1

这将把Solution1子文件夹的唯一历史文件克隆到./Solution1目录下的新git存储库中。它将只包含涉及该子文件夹中的文件的提交,并且它将调整相对路径,使该子文件夹成为新git存储库的根目录。

最新更新