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

AxD*_*AxD 2 git git-svn

我想将我们的 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
Run Code Online (Sandbox Code Playgroud)

所需的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
Run Code Online (Sandbox Code Playgroud)

sk_*_*ant 6

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

\n

1.将SVN转换为Git

\n

如果您的 SVN 存储库具有标准布局(子目录branchestagstrunk)并且您不需要任何其他附加功能,那么这非常简单:

\n
$ git svn clone <url_to_subversion_repo>\n
Run Code Online (Sandbox Code Playgroud)\n

该命令有两个问题:

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

git svn clone从 SVN 服务器 \xe2\x80\x93 按顺序检查 SVN 存储库的每个修订版 如果您有一个大存储库,这将需要一段时间(我认为,我的经验是大约 50,000 个修订版需要多个小时,尽管我不是当然,这是几年前的事了)。如果可能,您可能希望在 SVN 服务器上运行此命令,特别是如果您的连接速度较慢。不管怎样,去喝杯咖啡(或五杯)。

\n

2. 拆分Git存储库

\n

有多种工具可以将 Git 存储库拆分为子存储库。例如,参见这个问题。当我几年前这样做时,我使用了git filter-branch,但是这个工具现在已被弃用 \xe2\x80\x93 你可能仍然使用它,或者你可以使用git filer-repo,尽管我没有任何使用这个工具的经验。

\n

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

\n

优点

\n

与通过转换每个子存储库相比,此答案有哪些优点git svn clone

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