SVN 迁移到 Git
摘要
- 本文介绍如何使用
git-svn将 SVN 中的项目迁移到 Git
Git-Svn 简介
-
git-svn 是 Git 官方提供的工具,用于把 SVN 仓库的提交历史逐条转换为 Git commit,并支持后续同步,是 SVN 迁移到 Git 的经典方案。
-
用
git-svn做 SVN → Git 迁移,本质是利用 Git 内置的“SVN 适配器”把 SVN revision 流水线转换成 Git commit。 -
它的优势主要体现在
完整保留 SVN 线性历史、迁移成本低、可控性强这三个维度。
Git-Svn 安装
Linux 安装
1 | sudo dnf install git-svn -y |
Mac 安装
1 | brew install git-svn |
查看版本与帮助信息
1 | # 查看版本 |
实战迁移
查看svn最后一次提交时的 revision
1 | # 输入密码后,凭证会被保存在 ~/.subversion/auth/ 中 |
迁移trunk(不包含branch和tags)
-
前台运行
1 | # 运行 git svn clone 时,它会自动使用缓存的凭证 |
-
后台运行
1 | # 如果上面已经缓存或密码了,可以使用如下命令 |
发布到git仓库
-
注意此时不需要执行
git add .和git commit,因为迁移过程中这些commit已经自动生成了
1 | # 设置仓库 |
小贴士
- 如果
git push时报如下错误,说明上传的bady大小超过了限制,可以改用ssh push的方式
1 | # error: RPC failed; HTTP 413 curl 22 The requested URL returned error: 413 |
- 生成 key(如果你没有)
1 | ssh-keygen -t ed25519 -C "your_email@example.com" |
- 添加 key 到 GitLab
1 | # 复制: |
同时迁移branch和tags
-
标准svn结构
1 | project/ |
1 | git svn clone \ |
-
非标准结构,例如
1 | project/ |
1 | git svn clone \ |
转换 SVN Tag 和 Branch
-
git-svn 导入后,查看git分支会看到类似如下的内容
1 | git branch -a |
-
实际的branch是:
1 | remotes/origin/sometool-Branch |
-
实际的tags是
1 | remotes/origin/tags/sometool-V1.0.0.00-b582-p0 |
-
但此时都显示为branch,所以需要将其转换为tag
1 | for tag in $(git branch -r | grep 'tags/' | sed 's|origin/tags/||'); do |
-
然后检查
1 | git tag -l |
-
转换 Branch
1 | # 这里创建需要保留的分支 |
-
添加远程仓库
1 | git remote add origin https://gitlab.test.com/android/sometool.git |
-
推送所有内容
1 | # 推送分支: |
把 SVN 用户名映射成 Git 的用户
1 | git svn clone \ |
-
authors.txt格式
1 | SVN 用户名 Git 用户 |
git-svn 优点与缺点对比表
-
一、核心能力对比
| 维度 | 优点 | 缺点 |
|---|---|---|
| SVN → Git 迁移能力 | 可将 SVN revision 逐条转换为 Git commit | 不支持现代 Git 迁移增强(如智能重写) |
| 历史保留 | 完整保留 commit 顺序、message、时间 | 复杂历史(merge / branch)可能失真 |
| 作者信息 | 可通过 --authors-file 精确映射 SVN 用户 |
不配置时作者信息可能不规范 |
| revision 映射 | 保留 SVN revision(git-svn-id) | Git commit 与 SVN 强绑定,历史较“冗余” |
-
二、分支与标签支持
| 维度 | 优点 | 缺点 |
|---|---|---|
| trunk 映射 | 自动映射为主分支 | 无明显缺点 |
| branches 支持 | 支持 SVN branches → Git branches | 转换后通常需要手动整理 |
| tags 支持 | 支持 SVN tags → Git tags | 需要额外脚本转换为真正 tag |
| 灵活性 | 可选择只迁移 trunk | 多分支结构处理较繁琐 |
-
三、迁移方式与成本
| 维度 | 优点 | 缺点 |
|---|---|---|
| 使用复杂度 | 命令简单(git svn clone) | 参数较多时容易踩坑 |
| 工具依赖 | Git 官方工具,无需第三方软件 | Windows 环境可能缺组件 |
| 学习成本 | 对 Git 用户友好 | 对 SVN 复杂仓库理解要求高 |
| 部署成本 | 无需额外服务 | 无 GUI 可视化迁移工具 |
-
四、性能与规模
| 维度 | 优点 | 缺点 |
|---|---|---|
| 中小型仓库 | 表现稳定 | — |
| 大型仓库 | 可通过 --log-window-size 优化 |
10万+ revision 性能较慢 |
| 网络依赖 | 支持断点式 fetch/rebase | 强依赖 SVN server 性能 |
| 内存使用 | 可控 | 大历史导入时较高 |
-
五、功能扩展能力
| 维度 | 优点 | 缺点 |
|---|---|---|
| 增量同步 | 支持 git svn fetch |
维护复杂 |
| 双向同步 | 支持 dcommit 回写 SVN |
实际工程中很少使用 |
| 历史可追溯性 | SVN revision 与 Git commit 可对照 | Git history 不够“现代化” |
| 生态兼容 | Git 原生工具链可用 | 不适合 Git-centric 工作流重构 |
-
六、适用场景总结
| 场景 | 是否适合 git-svn |
|---|---|
| SVN → Git 一次性迁移 | ✔ 非常适合 |
| 保留完整 SVN 历史 | ✔ 最常用方案 |
| 只迁移 trunk 简化历史 | ✔ 很适合 |
| 大规模企业 Git 重构 | ⚠ 可用但不最佳 |
| 复杂 Git 历史重写 | ❌ 不适合 |
| 长期 SVN + Git 双向开发 | ⚠ 可用但维护成本高 |