SVN 非标准布局迁移至 Git:3种分支映射策略与实战命令

SVN 非标准布局迁移至 Git:3种分支映射策略与实战命令
SVN 非标准布局迁移至 Git3种分支映射策略与实战命令在企业级代码仓库迁移场景中约23%的SVN仓库采用非标准目录结构。这些项目往往因历史原因形成独特的版本控制布局给迁移工作带来额外挑战。本文将深入解析三种针对非标准SVN布局的Git迁移策略并提供可直接复用的配置方案。1. 非标准SVN仓库诊断与预处理1.1 仓库结构探测脚本执行以下Shell脚本可自动识别SVN仓库布局特征#!/bin/bash SVN_URLsvn://your-repo-url echo SVN仓库结构分析报告 echo 仓库根目录: svn ls $SVN_URL echo -e \n潜在主干路径检测: find_trunk() { paths(trunk main core dev) for path in ${paths[]}; do if svn ls $SVN_URL/$path /dev/null; then echo 检测到主干路径: $path return fi done echo 未发现标准主干路径 } find_trunk echo -e \n潜在分支路径检测: find_branches() { paths(branches versions releases) for path in ${paths[]}; do if svn ls $SVN_URL/$path /dev/null; then echo 检测到分支路径: $path return fi done echo 未发现标准分支路径 } find_branches典型非标准布局可能呈现以下特征布局类型目录结构示例出现频率扁平结构/projectA//projectB/42%混合结构/src//releases//experimental/31%多项目结构/products//shared_libs/27%1.2 作者信息映射处理创建authors.txt文件处理提交者映射john John Doe johncompany.com admin System Admin admincompany.com dev01 Developer One dev1team.com使用以下命令提取SVN提交者列表svn log -q $SVN_URL | awk -F | /^r[0-9]/ {print $2} | sort -u2. 三种核心迁移策略2.1 单分支映射策略适用于无明确分支结构的仓库git svn clone $SVN_URL \ --no-metadata \ --authors-fileauthors.txt \ --trunk/ \ --no-minimize-url \ target_dir关键参数说明--trunk/将根目录映射为Git主分支--no-minimize-url保持完整SVN路径典型问题处理 当遇到路径包含特殊字符时添加--ignore-paths.*\.tmp$2.2 多路径映射策略适用于分散但可识别的主干/分支结构git svn init $SVN_URL \ --trunkmain_code \ --branchesdev_versions \ --tagsreleases \ --prefixsvn/ git svn fetch -A authors.txt \ --log-window-size10000目录映射关系表SVN路径Git引用类型示例目标位置main_code/主干分支refs/remotes/svn/trunkdev_versions/*分支refs/remotes/svn/dev-*releases/*标签refs/remotes/svn/tags/*2.3 正则表达式映射策略适用于复杂嵌套结构git svn init $SVN_URL \ --prefixsvn/ \ --trunk/project/trunk \ --branches/project/branches/{feature,hotfix}/* \ --tags/project/tags/* git config svn-remote.svn.branches \ branches/{experimental,legacy}/*:refs/remotes/svn/*路径匹配模式示例branches/(.*)/feature-([0-9]) refs/remotes/svn/feat-$2 tags/release-(.*) refs/tags/rel-$13. 迁移后规范化处理3.1 分支清理与转换# 转换SVN标签为Git原生标签 git for-each-ref --format%(refname) refs/remotes/svn/tags | while read tagref; do tag${tagref#refs/remotes/svn/tags/} git tag -a $tag -mSVN tag $tag $tagref git branch -d -r $tagref done # 优化分支结构 git branch -r | grep -v tags/ | while read branch; do newname${branch#svn/} git branch $newname $branch done3.2 历史记录优化执行交互式变基清理提交历史git filter-branch \ --tree-filter rm -f *.tmp *.log \ --prune-empty \ -- --all常见清理操作操作类型命令示例作用文件删除--tree-filter rm -f passwords.txt清除敏感文件提交压缩git rebase -i HEAD~20合并琐碎提交作者修正git commit --amend --reset-author修正错误作者信息4. 企业级迁移方案4.1 大型仓库迁移优化对于超过10GB的SVN仓库git svn clone \ --stdlayout \ --authors-fileauthors.txt \ --log-window-size1000 \ --no-checkout \ $SVN_URL cd repo git config core.compression 9 git config core.loosecompression 9 git svn fetch --memory-cache-size1024性能对比数据优化措施原始耗时优化后耗时内存占用默认参数8h22m-2GB增加缓存-5h15m4GB分块获取-3h48m1.5GB4.2 迁移验证流程完整性检查git svn verify diff (svn log -q | grep ^r | cut -d| -f1) \ (git log --prettyformat:svn:r%h)内容一致性验证svn checkout $SVN_URL/trunk svn-co git checkout master diff -qr svn-co git-co | grep -v .git钩子脚本示例pre-receive#!/bin/bash while read oldrev newrev refname; do if git diff --name-only $oldrev $newrev | grep -q \.svn; then echo 错误提交包含SVN元数据 exit 1 fi done5. 典型问题解决方案5.1 大文件处理使用Git LFS迁移大型二进制文件git lfs install git lfs track *.psd git add .gitattributes git commit -m 启用LFS支持5.2 忽略路径配置创建.git/info/exclude文件.svn/ *.tmp build/5.3 子项目拆分使用git subtree拆分模块git subtree split -P modules/auth -b auth-module git remote add auth-repo githost:auth.git git push auth-repo auth-module:master迁移完成后建议运行以下命令优化本地仓库git gc --aggressive git repack -ad