如何把 SVN 仓库迁移到 Git 并保留历史

SVN 迁移 Git 用 git svn clone:准备作者映射文件(users.txt),git svn clone --stdlayout --authors-file 完整转换历史、分支、标签,再清理引用推到 Git 远程。大仓库建议通宵跑。

最佳实践
Git 提交历史与版本恢复示意

官方工具 git svn clone 可迁移 SVN 提交及配置范围内的分支/标签历史,但不保证所有合并关系、属性和已删除路径都完整转换。 关键准备是作者映射文件——SVN 用户名要映射成 Git 的"名字 <邮箱>"格式。

迁移步骤

# 1. 生成作者映射(从 SVN 日志提取所有提交者)
svn log --xml https://svn.company.com/repo > svn-log.xml
# 从 XML author 字段整理、去重并人工核对 users.txt,例如:
# alice = Alice Zhang <alice@company.com>

# 2. 克隆转换(trunk/branches/tags 标准布局)
git svn clone https://svn.company.com/repo   --stdlayout --prefix=svn/ --authors-file=users.txt my-repo

cd my-repo

--stdlayout 对应标准的 trunk/branches/tags 结构;非标准布局用 -T/-b/-t 单独指定。

转换后的清理

# 先列出并核对引用,避免把提交哈希/类型误当分支名
git for-each-ref --format='%(refname)' refs/remotes/svn/
# 根据实际清单逐项转换,以下仅为名称示例:
git branch feature-x refs/remotes/svn/feature-x
git tag v1.0 refs/remotes/svn/tags/v1.0

# 推到新远程
git remote add origin git@github.com:org/repo.git
git push --all && git push --tags

注意事项

  • 大仓库转换可能跑数小时,建议服务器上执行;
  • SVN 的 svn:ignore 转成 .gitignore(git svn show-ignore);
  • 切换前冻结 SVN 写入,完成最后一次 git svn fetch 并核对差异,再创建最终引用和推送;保留 git-svn 元数据以支持过渡期增量同步。

常见问题(FAQ)

Q:迁移后还能回 SVN 吗?

git svn 支持双向(dcommit 回推 SVN),但过渡期越长同步成本越高。建议一刀切,SVN 归档只读。

Q:SVN 的目录拷贝式分支在 Git 里什么样?

git svn 会尽量识别为真正的分支。SVN mergeinfo 不会自动成为等价 Git merge 祖先;SVN 标签可修改,Git 标签则指向固定提交。需核对删除过的分支、属性、externals 和目标目录范围,不能把转换成功视为完整保真。

Q:有没有更现代的工具?

reposurgeon、svn2git(基于 git svn 的封装,处理分支标签更自动化)。数据量大或布局怪异时值得试。

参考资料

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台