将svn项目迁移到git
将svn项目迁移到git
一、为什么从 SVN 迁移到 Git?
在过去很长一段时间,很多公司都使用 SVN 作为版本控制工具。随着 Git 的普及,以及 CI/CD 等现代开发工具链的兴起,越来越多团队考虑从 SVN 迁移到 Git。
本篇博客记录我实际操作的一次 SVN 到 Git 的迁移过程:我想将一个SVN老项目带走,因为SVN离开公司的中心服务器原来的提交历史等信息就会丢失,我自然就想到Git的自身就能进行版本控制的能力,然后我会出差来到一个无网络环境(局域网),此时我将进行一些开发做一些提交,最后回到公司将这些提交集成回公司的中心服务器.
Git的优势:
-
Git 分支管理灵活,支持分布式开发
-
支持离线提交、离线历史查看
-
集成更丰富的代码托管平台(GitHub、GitLab、Gitea 等)
-
配合 CI/CD、Pull Request 等现代开发流程更友好
二、环境准备
工具:
如果你不熟悉Git可以看我的这篇博客:在Unity环境中使用Git进行版本控制(入门篇)_unity git-CSDN博客
安装了Git后在一个文件夹下验证一下环境:
在任意一个目录下右键发现一个Open Git Bash 验证下面两个命令
git --version
git svn --version
三、获取 SVN 作者信息映射表(可选)
如果不关心作者信息,则建议直接省略,省略这步则会直接使用SVN中的作者信息
如果想让 svn 的历史作者正确映射成 git 格式,需要一份作者映射表。
生成作者映射文件:
svn log -q | awk -F '|' '/^r/ {sub("^ ", "", $2); sub(" $", "", $2); print $2" = "$2" <"$2"@example.com>"}' | sort -u > userinfo.txt
然后根据需要编辑 userinfo.txt
,把 SVN 用户名改成人名邮箱等 Git 风格。
四、执行 git-svn 克隆
进入一个空目录(该目录是用来存放项目的):
git svn clone https://svn服务器地址/项目路径
clone后面加上svn的地址就行了,但是也可以加一些参数,但是我对此不是很懂,所以没有使用,有需要则需要更细致的查看git的官方文档.
要注意的是大概率会弹出一个弹窗要求你信任证书
因为如果 svn 是 https 且有自签证书,会提示信任证书,选择 t
(临时) 或 p
(永久信任)。
然后要求你输入你的svn账号密码.
参数说明:
参数 | 含义 |
---|---|
--no-metadata |
不保留 git-svn 内部元数据 |
--authors-file |
使用刚才的作者映射表 |
--stdlayout |
如果 SVN 仓库有标准目录结构(trunk/branches/tags)可以加上 |
五、离线开发与本地提交
Git 的好处就是,即使没网,也可以这样:
git add .
git commit -m "第一次离线开发提交"
git commit -m "第二次离线开发提交"
不用担心 SVN 连接失败。
你可以使用GUI工具,我上面提到博客也对此有说明.
六、恢复网络后同步回 SVN
先拉取一下 SVN 最新:
git svn fetch
然后同步你的历史提交:
git rebase remotes/git-svn
git svn dcommit
这样,你所有本地 Git 提交,会逐个同步回 SVN。
这里要提一下:这个由svn迁移的git仓库内部仍保持着对原来svn服务器的联系,所以你仍然可以更新或推送代码.所以这里的需要专门的命令(如 git svn dcommit而不是git commit)
Git SVN 工作流细致讲解(git svn fetch
、git rebase remotes/git-svn
、git svn dcommit
)
这里用一个完整的场景,详细讲解 Git 与 SVN 协作中的三个核心命令的作用和顺序:
① 克隆仓库(git svn clone
)
首先,我通过以下命令克隆 SVN 仓库:
git svn clone <SVN 仓库地址>
此时:
-
SVN 服务器当前版本是 r100;
-
Git 会创建一个远程跟踪分支
remotes/git-svn
,指向 SVN 最新提交 r100; -
Git 还会基于
remotes/git-svn
创建一个本地分支master
,作为本地工作分支,也指向 r100。
② 本地开发
我在本地 master
分支上进行了三次提交,分别是:
-
提交 A
-
提交 B
-
提交 C
此时本地提交历史如下:
r100 → A → B → C(master)
而 remotes/git-svn
依然指向 r100:
remotes/git-svn → r100
③ 同事推送了新提交到 SVN
假设此时我的同事在 SVN 服务器上进行了 5 次提交,SVN 版本推进到了 r105。
④ 同步 SVN 最新提交(git svn fetch
)
我需要拉取最新的 SVN 提交,执行命令:
git svn fetch
此时:
-
remotes/git-svn
被更新到 r105; -
本地
master
分支不变,仍基于 r100。
当前状态:
remotes/git-svn → r105
master → r100 → A → B → C
⑤ 变基到最新 SVN 提交(git rebase remotes/git-svn
)
为了让我的提交基于 SVN 最新版本,我执行:
git rebase remotes/git-svn
这个命令做了三件事:
-
临时“摘取”我本地的提交 A、B、C;
-
将
master
分支指针移动到remotes/git-svn
(r105); -
依次把 A、B、C 重放到 r105 之后,形成新的提交链(过程中若有冲突需解决):
r105 → A′ → B′ → C′(master)
(注:A′、B′、C′ 是变基后的新提交对象)
⑥ 推送到 SVN(git svn dcommit
)
变基完成后,我执行:
git svn dcommit
这条命令会:
-
将 A′、B′、C′ 提交到 SVN 服务器,生成新版本 r106、r107、r108;
-
自动更新
remotes/git-svn
,指向最新的 SVN 提交 r108; -
本地
master
也指向 r108,保持同步。
最终状态:
SVN 服务器:r106 → r107 → r108
remotes/git-svn → r108
master → r108
✅ 全流程示意图:
# 初始状态
remotes/git-svn → r100
master → r100 → A → B → C
# 同事提交后
remotes/git-svn → r105
master(不变)
# 执行 git svn fetch
remotes/git-svn → r105
master(不变)
# 执行 git rebase remotes/git-svn
remotes/git-svn → r105
master → r105 → A′ → B′ → C′(变基)
# 执行 git svn dcommit
SVN 服务器 → r106 → r107 → r108
remotes/git-svn → r108
master → r108
✅ 关键总结:
-
remotes/git-svn
仅是 SVN 服务器最新提交的“镜像”,不会存储你的本地提交; -
git rebase remotes/git-svn
会把你的本地提交“重放”到 SVN 最新提交之后,让提交链保持线性; -
git svn dcommit
会按顺序把你的提交推送到 SVN,并自动更新本地remotes/git-svn
和master
。
七、推送到云端 Git 仓库
如果你还想同步备份到云 Git 仓库(比如 Gitee、GitHub、GitLab):
git remote add origin https://你云端Git地址.git
git push -u origin master
-u的意思是将名为origin的仓库设为默认推送或拉取的仓库
以后想同步:
git push
git pull
此时SVN中心服务器和Git云服务器都能和你这个仓库交互.
其实这里我还遇到一个问题:我本想使用gitee作为我的云,但是遭遇了推送失败,原因是免费版本的云服务器限制单个文件要小于100MB,很不巧我的项目的历史提交中包含这么大的文件,所以我没法使用gitee,没办法我临时搭建一个自己的git服务器,我以前使用过gitea,轻量强大
Gitea简单部署:
https://github.com/go-gitea/gitea
从发布版里面找windows的64版本,下载下来就行了(我是临时用用,建议从官方文档查看规范的部署流程).
下载下来后,放在一个专门的目录下就完成了(这个目录就是你的服务器了) ,此时启动该exe
我的理解本质就是一个大的后端项目,访问该地址(ctrl+左键)
要求数据库,我选择SQLite,这样我不需要部署数据库,公司名填一下就可以安装了
默认第一个注册用户是管理员,后续操作和Github没有太大差别.
八、日常双轨工作流建议
场景 | 命令 |
---|---|
从 SVN 拉取更新 | git svn fetch |
把本地改动同步到 SVN | git svn dcommit |
离线开发 | 用 git commit |
推送云端 Git | git push origin master |
拉取云端 Git | git pull origin master |
九、常见问题
1. SSL 证书错误怎么办?
SVN 自签证书的话,第一次拉取时会弹出信任确认,选 t
或 p
。
2. 推送到 Git 报错:remote contains work that you do not have locally?
远程仓库可能有默认 README、.gitignore,你先:
git pull origin master --rebase
然后再推:
git push
3. 有没有办法以后彻底脱离 SVN?
可以,后续可以做一次仓库“脱 SVN 清洗”,删掉 .git/config
里的 svn-remote
部分,然后强制推送纯 Git 历史。
更多推荐
所有评论(0)