svn - 如何将具有历史记录的 SVN 存储库迁移到新的 Git 存储库?

标签 svn git version-control git-svn

我阅读了 Git 手册、常见问题解答、Git - SVN 速成类(class)等,他们都解释了这个那个,但是你找不到像这样的简单说明:

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

我不希望它这么简单,也不希望它是一条命令。但我确实希望它不会试图解释任何事情 - 只是说明在这个例子中要采取什么步骤。

最佳答案

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

user1 = First Last Name <email@address.com>
user2 = First Last Name <email@address.com>
...

您可以使用这个单行代码从您现有的 SVN 存储库构建模板:

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

如果 SVN 发现丢失的 SVN 用户,而不是在文件中,SVN 将停止。但在那之后,您可以更新文件并从中断的地方继续。

现在从存储库中 pull SVN 数据:

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

此命令将在 dest_dir-tmp 中创建一个新的 Git 存储库并开始 pull SVN 存储库。请注意,“--stdlayout”标志意味着您拥有通用的“trunk/、branches/、tags/”SVN 布局。如果您的布局不同,请熟悉 --tags , --branches , --trunk选项(通常为 git svn help )。

允许所有常见协议(protocol):svn:// , http:// , https:// .该 URL 应以基本存储库为目标,类似于 http://svn.mycompany.com/myrepo/repository . URL 字符串必须包含/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 将 check out 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 names

标签作为分支导入。您必须创建一个本地分支,创建一个标签并删除该分支才能将它们作为 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

关于svn - 如何将具有历史记录的 SVN 存储库迁移到新的 Git 存储库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/79165/

相关文章:

svn - 将转储的 SVN 存储库导入 VisualSVN Server

svn - 如何管理 SVN 标签中的修订编号?

c# - 在源代码管理中存储您不想要的密码的位置

git - 在 Synology NAS 上启用 Gitlab LFS

visual-studio-2010 - 忘记将我的代码搁置在 TFS 中。我现在有什么选择?

version-control - VCS 和 Python 项目结构 : How to setup the PYTHONPATH automatically?

SVN从提交的代码创建补丁?

windows - 无法识别 composer install "svn"的问题?

git - 在 git 的命令行中显示 merge 状态的方法

git - Go:如何向构建的二进制文件添加 git 修订版?