SVN 迁移到 Git 仓库如何保留历史提交记录

文章导读
使用 git svn 工具是保留 SVN 历史提交记录迁移到 Git 仓库的标准方案,适用于需要完整追溯代码变更场景,主要风险在于作者映射缺失导致提交人信息混乱。
📋 目录
  1. Ⅰ 命令速用版
  2. Ⅱ 为什么会这样
  3. Ⅲ 分步处理
  4. Ⅳ 怎么验证是否生效
  5. Ⅴ 常见坑
  6. Ⅵ 常见问题
  7. Ⅶ 参考来源
A A

使用 git svn 工具是保留 SVN 历史提交记录迁移到 Git 仓库的标准方案,适用于需要完整追溯代码变更场景,主要风险在于作者映射缺失导致提交人信息混乱。

先说结论:迁移过程必须建立 SVN 用户名到 Git 邮箱的映射文件,否则提交记录作者将显示为本地主机名。

  • 适合:需要保留完整 commit 历史、作者信息且后续不再回写 SVN 的项目。
  • 先看:确认 SVN 仓库结构是否为标准的 trunk/branches/tags 布局。
  • 建议:迁移前先在小范围分支测试映射文件是否正确生成。

命令速用版

以下命令用于将标准结构的 SVN 仓库克隆为本地 Git 仓库并保留历史:

git svn clone `--stdlayout` `--authors-file`=users.txt http://svn.example.com/repo/project-name project-git

完成后关联远程 Git 仓库并推送:

cd project-git
git remote add origin git@gitlab.com:group/projectname.git
git push -u origin master

为什么会这样

SVN 是集中式版本控制,提交者信息仅记录为用户名,而 Git 是分布式系统,要求提交者包含姓名和邮箱。

git svn 工具在迁移过程中充当桥梁,将 SVN 的 revision 转换为 Git 的 commit,但默认无法自动获取 SVN 用户名对应的邮箱,必须通过 authors-file 参数手动映射,否则 Git 日志中的作者信息将不可用。

分步处理

1. 环境准备

确保本地已安装 Git 且支持 git-svn 模块,Windows 用户推荐使用 Git for Windows,Linux 用户可通过包管理器安装 git-svn 和 subversion。

2. 创建用户映射文件

新建 users.txt 文件,格式为 svn 用户名 = Git 姓名 <Git 邮箱>。可通过 svn log 命令导出所有作者列表后手动补充邮箱信息。

3. 克隆 SVN 仓库

执行 git svn clone 命令,添加 `--no-metadata` 参数可去除 SVN 附加信息,添加 `--authors-file` 指定映射文件。若 SVN 结构非标准,需显式指定 `--trunk`、`--branches` 路径。

SVN 迁移到 Git 仓库如何保留历史提交记录

4. 关联远程仓库

在 GitLab 或 GitHub 创建空仓库,使用 git remote add origin 命令添加远程地址。

5. 推送代码

执行 git push -u origin master 将本地历史推送到远程,首次推送可能需要输入 Git 账号密码。

怎么验证是否生效

在本地项目目录执行 git log 命令,检查提交历史是否完整,确认作者姓名和邮箱是否已正确替换为 users.txt 中的内容,而非 username@localhost 格式。

常见坑

作者信息丢失:未提供 authors-file 会导致所有提交者显示为同一本地用户,后期无法修正。

迁移时间过长:历史悠久的 SVN 仓库克隆可能需要数小时,期间需保持网络稳定,中断后需重新 fetch。

目录结构不匹配:若 SVN 没有 trunk 目录,直接使用 `--stdlayout` 会失败,需手动指定路径参数。

常见问题

如何快速生成 users.txt 映射文件?

在 SVN 项目根目录执行 svn log 命令提取所有作者名,然后手动编辑文件补充邮箱,确保覆盖所有提交者。

SVN 仓库没有 trunk 目录怎么办?

不使用 `--stdlayout` 参数,改为通过 `--trunk`=/ 或具体路径指定主干位置,确保 git svn 能识别代码根目录。

参考来源

  • svn 迁移到 git 仓库并保留 commit 历史记录
  • 将 SVN 项目迁移到 Git,保留提交记录
  • 如何将现有的 SVN 仓库完整迁移到 Git 并保留提交历史?
  • 代码管理:svn 项目迁移至 gitlab 流程 (保留提交记录)