git-svn 实战迁移:1350次提交历史完整保留,用户映射3步避坑

git-svn 实战迁移:1350次提交历史完整保留,用户映射3步避坑 Git-SVN迁移实战1350次提交历史完整保留与用户映射避坑指南1. 迁移前的战略规划当团队决定从SVN迁移到Git时往往面临两大核心挑战如何完整保留历史提交记录以及如何处理用户映射问题。我曾主导过一个包含1350次提交的中型项目迁移过程中发现前期规划的质量直接决定迁移效率。以下是关键决策点历史记录保留必要性评估若仅需最新代码简单svn export加git init即可。但需要追溯历史时必须使用git-svn工具链仓库结构分析SVN常见的三种目录布局标准布局trunk/branches/tags扁平结构单项目根目录多项目混合多个项目共享仓库# 探测SVN仓库结构示例 svn ls http://svn.example.com/repo # 典型输出 branches/ tags/ trunk/用户映射准备SVN使用系统账号Git需要邮箱格式。缺失映射会导致提交者显示为SVN账号版本范围筛选大型仓库可指定版本区间如-r 38163:HEAD减少迁移时间2. 用户映射的三步避坑法用户映射是迁移中最易出错的环节。通过三个项目实战我总结出以下标准化流程2.1 提取SVN提交者列表svn log -q | grep -E ^r[0-9] | cut -d| -f2 | sort | uniq svn_users.txt得到的svn_users.txt示例johndoe janedoe devops_robot2.2 构建映射文件创建users.txt格式为svn_user Git Name email。处理特殊情况的技巧离职员工保留历史记录但标记特殊邮箱系统账号映射到团队公共账号重名用户添加部门后缀区分# 示例映射文件 johndoe John Doe johncompany.com janedoe Jane Smith janecompany.com devops_robot CI Robot cicompany.com2.3 验证映射完整性# 检查未映射用户 git svn clone --authors-fileusers.txt --dry-run svn://repo # 出现警告时停止补充映射后继续3. 完整迁移操作流程3.1 标准布局仓库克隆git svn clone http://svn.example.com/repo \ --stdlayout \ --authors-fileusers.txt \ --no-metadata \ -r 38163:HEAD \ project_folder关键参数解析--stdlayout自动识别trunk/branches/tags--no-metadata去除SVN元数据建议新仓库使用-r指定版本范围可选3.2 非标准布局处理当遇到自定义目录结构时git svn clone http://svn.example.com/nonstd \ --trunkmain \ --branchesdev-branches \ --tagsreleases \ --authors-fileusers.txt \ project_folder3.3 大型仓库优化技巧针对超过1000次提交的仓库# 分阶段克隆 git svn init http://svn.example.com/large-repo --stdlayout git svn fetch -r 1:500 # 第一阶段 git svn fetch -r 501:1000 # 第二阶段 git svn fetch -r 1001:HEAD # 第三阶段 # 内存优化配置 git config pack.windowMemory 100m git config pack.packSizeLimit 100m4. 迁移后验证体系4.1 提交历史验证脚本#!/bin/bash # verify_svn_history.sh # 验证提交数量 EXPECTED1350 ACTUAL$(git rev-list --count HEAD) if [ $ACTUAL -ne $EXPECTED ]; then echo 提交数量不符: 预期 $EXPECTED, 实际 $ACTUAL exit 1 fi # 验证最后提交信息 LAST_SVN$(svn log -l 1 http://svn.example.com/repo | grep ^r) LAST_GIT$(git log -1 --pretty%h %s) echo SVN最后提交: $LAST_SVN echo Git最后提交: $LAST_GIT # 验证分支标签 echo 迁移后的分支: git branch -av echo 迁移后的标签: git tag -l4.2 常见问题解决方案问题现象诊断方法解决方案提交者显示SVN账号git log --pretty%an %ae检查users.txt格式重新clone分支缺失git branch -av确认--branches参数正确标签未转换git tag -l手动创建git tag -a v1.0 commit文件权限丢失ls -l对比使用git svn show-externals恢复5. 高级场景处理5.1 增量同步方案当需要保持SVN和Git并行运行一段时间# 初始克隆 git svn clone http://svn.example.com/repo --stdlayout repo # 每日同步 cd repo git svn rebase --authors-file../users.txt git push origin master5.2 二进制文件处理SVN中常见的二进制文件如Word文档需要特殊处理# 配置Git LFS git lfs install git lfs track *.docx git add .gitattributes git commit -m Track Word files with LFS5.3 忽略规则转换将SVN的忽略属性转换为Git格式git svn show-ignore .gitignore git add .gitignore git commit -m Convert svn:ignore to .gitignore6. 迁移后的Git标准化完成技术迁移后建议实施以下改进分支策略采用Git Flow或GitHub Flow代码审查配置Pull Request模板钩子脚本添加pre-commit检查# .git/hooks/pre-commit示例 #!/bin/sh if git diff --cached --name-only | grep -q \.sh$; then shellcheck $(git diff --cached --name-only -- *.sh) fi大文件清理使用BFG Repo Cleanerjava -jar bfg.jar --strip-blobs-bigger-than 10M repo.git迁移过程中最大的教训是完整测试流程比迁移速度更重要。建议先在测试仓库验证所有步骤再操作生产仓库。对于超大型项目10万提交考虑使用SubGit等专业工具会更高效。