Git 转换:从 SVN 迁移到 Git 的一个步骤

从 SVN 迁移到 Git 的下一步是将 SVN 存储库的内容导入到新的 Git 存储库中。我们将使用大多数 Git 发行版中包含的 git svn 实用程序来完成此操作,然后使用 svn-migration-scripts.jar* 清理结果。

请注意,对于较大的存储库,即使是从本地 SVN 存储库克隆,转换流程也可能会花费大量时间。作为基准,转换一个 400MB 的存储库,在主分支上提交 33,000 次,花了大约 12 个小时才完成。

对于大小合理的存储库,应在迁移主管的本地计算机上运行以下步骤。但是,如果您有一个非常大的 SVN 存储库并且想减少转换时间,您可以在 SVN 服务器上运行 git svn clone,而不是在迁移主管的本地计算机上运行。这将避免通过网络连接进行克隆的开销。

*请注意,这些脚本是在只有 git 1.8.x 版本可用时编写的。因此,必须使用该版本的 git 才能使这些脚本正常工作。

克隆 SVN 存储库

git svn clone 命令将 SVN 存储库中的主干、分支和标记转换为新的 Git 存储库。该命令的配置方式需根据 SVN 代码存储库的结构而定。

Git 迁移:git svn clone 命令

标准的 SVN 布局

如果您的 SVN 项目使用标准的 /trunk/branches/tags 目录布局,则可以使用 --stdlayout 选项,而不必手动指定存储库的结构。在 ~/GitMigration 目录中运行以下命令:

git svn clone --stdlayout --authors-file=authors.txt
 <svn-repo>/<project> <git-repo-name>

其中 <svn-repo> 是您想要迁移的 SVN 存储库的 URI,<project> 是您想要导入的项目的名称,<git-repo-name> 是新 Git 存储库的目录名称。

例如,如果您正在迁移一个托管在 https://svn.atlassian.com 上、名为 Confluence 的项目,您可以运行以下命令:

git svn clone --stdlayout --authors-file=authors.txt https://svn.atlassian.com/Confluence ConfluenceAsGit

非标准的 SVN 布局

如果您的 SVN 存储库没有标准布局,则需要使用 --trunk--branches--tags 命令行选项提供主干、分支和标记的位置。例如,如果您的分支同时存储在 /branches 目录和 /bugfixes 目录中,则应使用以下命令:

git svn clone --trunk=/trunk --branches=/branches 
 --branches=/bugfixes --tags=/tags --authors-file=authors.txt 
 <svn-repo>/<project> <git-repo-name>

检查新的 Git 存储库

git svn clone 完成后(这可能需要一段时间),您会在 ~/GitMigration 中找到一个名为 <git-repo-name> 的新目录。这是转换后的 Git 存储库。您应该能够切换到 <git-repo-name>,并运行任何标准的 Git 命令来浏览您的项目。

分支和标记不会像您预期的那样导入到新的 Git 存储库中。您不会在 git branch 输出中找到任何 SVN 分支,也不会在 git tag 输出中找到任何 SVN 标记。但是,如果您运行 git branch -r,您会发现您的 SVN 存储库中的所有分支和标记。git svn clone 命令将您的 SVN 分支导入为远程分支,并将您的 SVN 标记导入为带有 tags/ 前缀的远程分支。

Git 迁移:克隆的 Git 代码存储库结构

这种行为使某些双向同步程序变得更容易,但是在尝试进行单向迁移 Git 时,可能会非常混乱。这就是为什么我们的下一步是将这些远程分支转换为本地分支和实际的 Git 标记。

清理新的 Git 存储库

svn-migration-scripts.jar 中包含的 clean-git 脚本将 SVN 分支转换为本地 Git 分支,将 SVN 标记转换为成熟的 Git 标记。请注意,这是一种破坏性操作,您将无法将提交从 Git 存储库移回 SVN 存储库。

如果您遵循本迁移指南,这不是问题,因为它主张从 SVN 到 Git 的单向同步(在迁移步骤完成前,Git 存储库被视为只读)。但是,如果您计划在迁移过程中提交到 Git 存储库 SVN 存储库,则不应执行以下命令。这是一项高级任务,不建议用于一般项目。

要查看可以清理的内容,请在 ~/GitMigration/<git-repo-name> 中运行以下命令:

java -Dfile.encoding=utf-8 -jar ~/svn-migration-scripts.jar clean-git

这将输出脚本想要进行的所有变更,但实际上不会进行任何变更。要执行这些变更,您需要使用 --force 选项,如下所示:

java -Dfile.encoding=utf-8 -jar ~/svn-migration-scripts.jar clean-git --force

现在,您应该在 git branch 输出中看到所有的 SVN 分支,在 git tag 输出中看到您的 SVN 标记。这意味着您已经成功地将 SVN 项目转换为 Git 存储库。

摘要

在此步骤中,您使用 git svn clone 命令将 SVN 存储库变成了新的 Git 存储库,然后使用 svn-migration-scripts.jar 清理了生成的存储库的结构。在下一步中,您将学习如何使这个新的 Git 代码存储库与 SVN 存储库的任何新提交保持同步。这将与转换流程类似,但是在此过渡期间,有一些重要的工作流程注意事项。

为您推荐

Bitbucket 博客

DevOps 学习路径

了解有关 Git 的更多信息

在此中心查找更多 Git 指南和资源。