创建用户映射
导入产生的第一个问题就是作者信息。 在 Subversion 中,每一个人提交时都需要在系统中有一个用户,它会被记录在提交信息内。 在之前章节的例子中几个地方显示了 schacon,比如 blame 输出与 git svn log。 如果想要将上面的 Subversion 用户映射到一个更好的 Git 作者数据中,你需要一个 Subversion 用户到 Git 用户的映射。 创建一个 users.txt 的文件包含像下面这种格式的映射:
1 | zhangs = 张三 <zhangs@email.address.com> |
如果上面的文件中有用户缺失,后面的 SVN 命令会输出如下错误并停止。
1 Author: xxx not defined in users.txt file不过你可以更新用户映射然后接着再来(类似断点续传)。
修改好用户后,需要进入clone的目录并使用以下命令继续拉取:
1 git fetch否则会出现如下错误信息:
1
2
3 $ git svn clone --no-metadata -A users.txt http://svn.mycompany.com/myrepo
Using existing [svn-remote "svn"]
svn-remote.svn.fetch already set to track :refs/remotes/git-svn
为了获得 SVN 使用的作者名字列表,可以运行这个:
1 | $ svn log --xml | grep author | sort -u | \ |
这会将日志输出为 XML 格式,然后保留作者信息行、去除重复、去除 XML 标记。 (很显然这只会在安装了 grep、sort 与 perl 的机器上运行。) 然后,将输出重定向到你的 users.txt 文件中,这样就可以在每一个记录后面加入对应的 Git 用户数据。
从 SVN 仓库中拉取所有数据
你可以将此文件提供给 git svn 来帮助它更加精确地映射作者数据。 也可以通过传递 --no-metadata
给 clone 与 init 命令,告诉 git svn 不要包括 Subversion 通常会导入的元数据。 这会使你的 import 命令看起来像这样:
1 | git svn clone -s --no-metadata -A users.txt http://svn.mycompany.com/myrepo |
现在在 myrepo 目录中应当有了一个更好的 Subversion 导入。 并不像是下面这样的提交:
1 | commit 37efa680e8473b615de980fa935944215428a35a |
反而它们看起来像是这样:
1 | commit 03a8785f44c8ea5cdb0e8834b7c8e6c469be2ff2 |
不仅是 Author 字段更好看了,git-svn-id 也不在了。
之后,你应当做一些导入后的清理工作。 第一步,你应当清理 git svn 设置的奇怪的引用。 首先移动标签,这样它们就是标签而不是奇怪的远程引用,然后你会移动剩余的分支这样它们就是本地的了。
为了将标签变为合适的 Git 标签,运行
1 | cp -Rf .git/refs/remotes/origin/tags/* .git/refs/tags/ |
这会使原来在 remotes/origin/tags/ 里的远程分支引用变成真正的(轻量)标签。
接下来,将 refs/remotes 下剩余的引用移动为本地分支:
1 | cp -Rf .git/refs/remotes/* .git/refs/heads/ |
现在所有的旧分支都是真正的 Git 分支,并且所有的旧标签都是真正的 Git 标签。 最后一件要做的事情是,将你的新 Git 服务器添加为远程仓库并推送到上面。 下面是一个将你的服务器添加为远程仓库的例子:
1 | git remote add origin git@my-git-server:myrepository.git |
通过以上漂亮、干净地导入操作,你的所有分支与标签都应该在新 Git 服务器上。
如果要单独 push 所有的 tag,可以像这样:
1 | git push origin --tags |
参考