协慌网

登录 贡献 社区

如何将包含历史记录的 SVN 存储库迁移到新的 Git 存储库?

我阅读了 Git 手册,常见问题解答,Git - SVN 速成课程等等,他们都解释了这个和那个,但是你无处可以找到一个简单的指令:

SVN 存储库位于: svn://myserver/path/to/svn/repos

Git 存储库位于: git://myserver/path/to/git/repos

git-do-the-magic-svn-import-with-history \
svn://myserver/path/to/svn/repos \
git://myserver/path/to/git/repos

我不希望它那么简单,我不指望它是一个单一的命令。但我确实希望它不要试图解释任何事情 - 只是说这个例子采取了哪些步骤。

答案

创建一个用户文件(即users.txt ),用于将 SVN 用户映射到 Git:

user1 = First Last Name <[email protected]>
user2 = First Last Name <[email protected]>
...

您可以使用此单行程序从现有 SVN 存储库构建模板:

svn log -q | awk -F '|' '/^r/ {sub("^ ", "", $2); sub(" $", "", $2); print $2" = "$2" <"$2">"}' | sort -u > users.txt

如果 SVN 发现缺少 SVN 用户,SVN 将停止。但之后,您可以更新文件并从中断的地方继续。

现在从存储库中提取 SVN 数据:

git svn clone --stdlayout --no-metadata --authors-file=users.txt svn://hostname/path dest_dir-tmp

此命令将在dest_dir-tmp创建一个新的 Git 存储库,并开始拉取 SVN 存储库。请注意,“- stdlayout” 标志表示您具有通用的 “trunk /,branches /,tags /”SVN 布局。如果您的布局不同,熟悉--tags--branches--trunk选项(一般git svn help )。

允许所有常用协议: svn://http://https:// 。 URL 应该以基本存储库为目标,例如http://svn.mycompany.com/myrepo/repository 。这不能包括/trunk/tag/branches

请注意,执行此命令后,通常看起来操作是 “挂起 / 冻结”,并且在初始化新存储库后可能会长时间卡住它是很正常的。最后,您将看到日志消息,表明它正在迁移。

另请注意,如果省略--no-metadata标志,Git 会将有关相应 SVN 修订的信息附加到提交消息(即git-svn-id: svn://svn.mycompany.com/myrepo/<branchname/trunk>@<RevisionNumber> <Repository UUID>

如果找不到用户名,请更新users.txt文件,然后:

cd dest_dir-tmp
git svn fetch

如果你有一个大项目,你可能需要多次重复那个最后一个命令,直到所有的 Subversion 提交都被提取:

git svn fetch

完成后,Git 会将 SVN trunk检入新分支。任何其他分支都设置为遥控器。您可以通过以下方式查看其他 SVN 分支:

git branch -r

如果要在存储库中保留其他远程分支,则需要手动为每个分支创建本地分支。 (跳过 trunk / master。)如果你不这样做,分支将不会在最后一步克隆。

git checkout -b local_branch remote_branch
# It's OK if local_branch and remote_branch are the same name

标签作为分支导入。你必须创建一个本地分支,制作一个标签并删除分支,使它们在 Git 中作为标记。要使用标记 “v1” 执行此操作:

git checkout -b tag_v1 remotes/tags/v1
git checkout master
git tag v1 tag_v1
git branch -D tag_v1

将您的 GIT-SVN 存储库克隆到干净的 Git 存储库:

git clone dest_dir-tmp dest_dir
rm -rf dest_dir-tmp
cd dest_dir

您之前从远程分支创建的本地分支将仅作为远程分支复制到新的克隆存储库中。 (跳过 trunk / master。)对于你想要保留的每个分支:

git checkout -b local_branch origin/remote_branch

最后,从干净的 Git 存储库中删除指向现在已删除的临时存储库的远程数据库:

git remote rm origin

魔法:

$ git svn clone http://svn/repo/here/trunk

Git 和 SVN 的运作方式截然不同。你需要学习 Git,如果你想跟踪 SVN 上游的变化,你需要学习git-svngit-svn手册页有一个很好的示例部分:

$ git svn --help

干净地将 Subversion 存储库迁移到 Git 存储库 。首先,你必须创建一个文件,将你的 Subversion 提交作者名称映射到 Git commiters,比如~/authors.txt

jmaddox = Jon Maddox <[email protected]>
bigpappa = Brian Biggs <[email protected]>

然后,您可以将 Subversion 数据下载到 Git 存储库中:

mkdir repo && cd repo
git svn init http://subversion/repo --no-metadata
git config svn.authorsfile ~/authors.txt
git svn fetch

如果您使用的是 Mac,可以通过安装git-core +svn从 MacPorts 获取git-svn git-core +svn

如果您的 subversion 存储库与所需的 git 存储库位于同一台机器上,那么您可以将此语法用于 init 步骤,否则完全相同:

git svn init file:///home/user/repoName --no-metadata