如何将带有历史记录的SVN仓库迁移到新的Git仓库

如何将带有历史记录的SVN仓库迁移到新的Git仓库

技术背景

在软件开发过程中,版本控制系统起着至关重要的作用。SVN(Subversion)是一种集中式版本控制系统,曾被广泛使用,但随着分布式版本控制系统的兴起,Git因其高效的分支管理和分布式特性,逐渐成为开发者的首选。因此,将现有的SVN仓库迁移到Git仓库变得十分必要,同时还需要保留历史记录,以便后续的开发和追溯。

实现步骤

1. 创建用户映射文件

创建一个 users.txt 文件,用于将SVN用户映射到Git用户:

1
2
3
user1 = First Last Name <[email protected]>
user2 = First Last Name <[email protected]>
...

可以使用以下命令从现有的SVN仓库生成模板:

1
svn log -q | awk -F '|' '/^r/ {gsub(/ /, "", $2); sub(" $", "", $2); print $2" = "$2" <"$2">"}' | sort -u > users.txt

2. 克隆SVN仓库到Git

1
git svn clone --stdlayout --no-metadata --authors-file=users.txt svn://hostname/path dest_dir-tmp
  • --stdlayout:表示SVN仓库采用常见的 “trunk/, branches/, tags/” 布局。
  • --no-metadata:不添加SVN的元数据到Git提交信息中。
  • --authors-file:指定用户映射文件。

3. 处理分支和标签

分支

1
2
git branch -r # 查看SVN分支
git checkout -b local_branch remote_branch # 创建本地分支

标签

1
2
3
4
git checkout -b tag_v1 remotes/tags/v1
git checkout master
git tag v1 tag_v1
git branch -D tag_v1

4. 克隆到干净的Git仓库

1
2
3
git clone dest_dir-tmp dest_dir
rm -rf dest_dir-tmp
cd dest_dir

5. 推送至远程Git仓库

1
2
3
git remote add origin url://your/repo.git
git config --global http.postBuffer 1073741824 # 增加HTTP缓冲区大小
git push origin --mirror # 推送所有分支和标签

核心代码

创建用户映射文件

1
svn log -q | awk -F '|' '/^r/ {gsub(/ /, "", $2); sub(" $", "", $2); print $2" = "$2" <"$2">"}' | sort -u > users.txt

克隆SVN仓库

1
git svn clone --stdlayout --no-metadata --authors-file=users.txt svn://hostname/path dest_dir-tmp

推送至远程仓库

1
2
3
git remote add origin url://your/repo.git
git config --global http.postBuffer 1073741824
git push origin --mirror

最佳实践

  • 使用工具:可以使用 svn2git 等工具简化迁移过程,避免手动处理分支和标签的繁琐操作。
  • 测试迁移:在正式迁移之前,先在测试环境中进行迁移,确保所有历史记录和分支标签都正确迁移。
  • 备份数据:在迁移之前,务必备份SVN和Git仓库的数据,以防数据丢失。

常见问题

1. 迁移过程中卡住

这是正常现象,尤其是在处理大型仓库时。Git需要逐个检出每个修订版本,可能会花费很长时间。

2. 找不到SVN用户

更新 users.txt 文件,添加缺失的用户映射,然后继续执行 git svn fetch

3. 推送失败

可能是由于网络问题或远程仓库权限问题。检查网络连接和权限设置,增加HTTP缓冲区大小可以解决部分问题。


如何将带有历史记录的SVN仓库迁移到新的Git仓库
https://119291.xyz/posts/migrate-svn-repo-with-history-to-git-repo/
作者
ww
发布于
2025年5月29日
许可协议