如何在不丢失提交历史的情况下将代码从 SVN 迁移到 GIT?

我想知道将我们的代码从 SVN 存储库转移到 GIT 存储库的推荐方法,这样我们就可以转移我们的开发团队并开始使用 GIT。

我们可以做转换并保持所有提交在 SVN 存储库中完成吗?

另外,我们的团队目前对 SVN 很满意,但是,他们不知道 GIT 中的分支比 SVN 要容易得多,我在哪里可以找到一个实际的例子来证明 GIT 在分支中的强大功能?

62497 次浏览

我不久前将我们的 CVS 存储库迁移到了 git,首先转换为 subversion,然后转换为 git。当使用正确的工具时,这种方法工作得很好。

参见 将包含 Eclipse 项目的 CVS 存储库转换为 git 的最健壮的方法是什么?

此外,完成后,严格测试。

关于 git 分支,这不是最聪明的部分。当您需要 合并分支时,优势就出现了。

既然已经有很多人在使用 Git-svn,我想说这是非常有可能的。下面的命令是众所周知的:

git svn clone -s http://svn/repo

根据 手动操作(本地验证) ,这将保持“主干,标签和分支”。

回购可以完全转换,包括标签和所有分支使用 git svn clone

有一些必要的调整来获得正确的标签,请参阅 这个链接了解更多信息。

这个主题以前至少在南方联盟讨论过一次:
如何将 svn 分支和标记导入 git-svn?

Eric Raymond (esr)创建了 再造人,“一个命令解释器,用于对版本控制历史执行复杂的编辑操作。”该工具包含用于各种目的的脚本,包括清理 VCS 转换的结果。从 https://gitlab.com/esr/reposurgeon看看。

从2.0版本开始,它支持读取 SVN 转储文件,以完成对 Git、 Mercurial、 等等。的惯用翻译; 有关详细信息,请参阅 http://esr.ibiblio.org/?p=4071。Reposurgeon 已被用于将几个大型项目转换为 Git,包括 Emacs,ESR 说,Emacs 的存储库“很大,分支结构复杂,已经足够成熟,可以作为 CVS 回购开始使用。最后一部分很重要,因为在 Subversion 项目的过去历史中,一些最丑陋的翻译问题是由 cvs2svn 生成的奇怪的 Subversion 操作序列(包括分支复制操作的组合)。”

(Git 附带的 Git-svn 工具将处理许多 Subversion 存储库,包括分支。它非常常用,特别是对于正在进行转换的团队,因为它允许 Git 作为 Subversion 客户端运行。但是请参阅 ESR 的 不要使用 git-svn 进行 svn 到 git 的存储库转换,其中他讨论了 git-svn 作为转换工具的缺点。)

关于你的第二个问题,它不是 Git 的强大功能对哪些分支如此有帮助(尽管 Git 在这方面至少和 Subversion 一样强大) ; 而是当涉及到 融合时,Git 的亮点在哪些分支上。通读 Git 社区手册,特别是第3章中标题为“ 基本分支和合并”的部分和第7章中标题为“ 高级合并”的部分。

安全顺利地从 Svn 迁移到 Git 的方法是使用 SubGit服务器端 Git/Svn 同步工具。可以将 SubGit 安装到 Subversion 存储库中,并且只要迁移过程持续,就可以同时使用 Subversion 和 Git。

免责声明: 我是一个喜欢使用 SubGit 半年的 SubGit 开发人员。

2014年4月最新情况

有一个称为 Svn2Git的工具,它可以很好地使这个过程变得简单一些。Github 项目的文档非常好。(需要 Ruby)

值得注意的是,git-svn 默认只从您指定的路径进行提取,而不是从分支、标记和主干进行提取。Svn2git 恰恰相反。它将默认在路径下查找主干、分支和标记,您应该使用 --nobranches--notags告诉它不要搜索这些(尽管这可能会抵消 svn2git 的优势)。


一旦您转移到 Git,我建议您转移所有人并继续使用 Git。虽然比较复杂,但过渡是值得的。Github.com 支持使用 Subversion 客户端访问回购(但是您可能会失去 Git 分支的能力) ,这可能是一个很好的权宜之计。

我可以保留我的 Subversion 回购吗?

当您使用以下方法移动时,所有当前提交将保留在 Subversion 回购中。你也许能够做一个单向同步从 Subversion 回购到 Git 回购,但去其他方式变得非常复杂,非常快。我不建议试图同步任何一种方式,只是移动每个人一次。

Git 有什么强大的地方?

Git 分支非常强大,但它并不是 Git 的全部。在本地拥有完整的历史记录意味着您可以使用 Subversion 做任何事情,而不必联系服务器。回顾和搜索历史、撤消更改、在本地提交、在本地分支都变得非常快。Git 还压缩它的数据,所以 Subversion 签出(只包括最新的版本)的大小最终与 Git 签出(包括完整的历史记录)相同。此外,由于数据在传输时是压缩的,所以推和拉也要快得多。不要只是推送 Git 分支,把所有关于 Git 的内容都放进去。

如何使用 git svn方法移动回购协议。

首先,克隆 Subversion 回购,这可能需要一段时间。

git svn clone http://www.example.com/svn-repo/projectA/trunk/

其中 http://www.example.com/svn-repo/是 Subversion 回购的 URL,而 projectA/trunk/是您想要复制到 Git 的路径。

如果您有一个标准的布局,比如 projectA/trunkprojectA/branches/projectA/tags/,那么您可以添加 --stdlayout并像这样从一个目录中克隆

git svn clone --stdlayout http://www.example.com/svn-repo/projectA/  projectA.git-svn

而且,如果您有一个主干,分支和标签文件夹命名不同,然后上面,您给每个 git svn clone自定义名称。

git svn clone --trunk my-trunk --branches my-branches --tags my-tags http://www.example.com/svn-repo/projectA/  projectA.git-svn

一旦完成,所有您必须做的是推到远程 git 回购与 --mirror

cd projectA.git-svn
git push --mirror git@github.com:Account/projectA.git

在这一点上,您应该使您的 Subversion 回购只读,以防止人们试图提交到一个过时的位置。

John Albin 写了一些很好的脚本 给你给你,它们将为您完成整个转换(包括作者转换)。这些脚本并不完美(我在使用多个分支时遇到了一些问题,特别是在使用 svn 外部服务器时)。

Atlassian 实际上在 svn 上编写了一个 向导来实现 git 迁移(他们在这些页面上也有很好的教程)。

Git 非常强大,但有一点需要注意: 到目前为止,git 还没有像 svn 那样简单的东西。还有其他选择(git 子树和 git 子模块) ,但是它们的工作方式从来不像 svn 外部程序那样直观(但这是另一个问题: 看看堆栈溢出,你会发现许多与这个主题相关的问题)