SVN
vscode 使用 svn 插件
步骤一

步骤二,使用 cmd 查询 svn 安装路径
TortoiseSVN
where svn

添加 .gitignore 文件
使用 svn propset 命令
- 在项目根目录下创建
.gitignore文件(文件名可以任意,但是要规范,比如.gitignore,.svnignore),并添加以下内容:
.DS_Store
node_modules
dist
npm-debug.log*
yarn-debug.log*
yarn-error.log*
tests/**/coverage/
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.local
- 绑定忽略规则到版本库 通过命令行将 .svnignore 中的规则应用到目录属性:
svn propset svn:ignore -F .gitignore .
此操作将忽略规则写入 svn:ignore 属性,并且会返回:property 'svn:ignore' set on '.' 表示写入成功。
递归将忽略规则写入 svn:ignore 属性 像vben admin 那样的项目结构,每个项目下有node_modules、dist等文件、文件夹,这时需要递归写入。
svn propset svn:ignore -R -F .gitignore .
- 查看属性内容
查看 svn:ignore 属性内容:
svn propget svn:ignore .

TIP
也可以在 TortoiseSVN 图形界面操作:在项目根目录右键选择 TortoiseSVN → 属性,看下 svn:ignore 属性是否存在或配置是否存在
查看属性列表
svn proplist . -v

提交变更
后续修改
.gitignore文件,需要再次执行svn propset svn:ignore -F .gitignore .命令绑定新的忽略规则到版本库。然后提交变更。
使用 TortoiseSVN 图形界面操作
- 右键菜单操作
在项目根目录右键选择 TortoiseSVN → 属性 → 新建(如果没有 svn:ignore 属性则新建) → 其他 → svn:ignore → 一行一个配置
- 右键-属性

- 新建-其他

- 选择 svn:ignore

- 填写配置 svn:ignore 一行一个

- 提交变更
svn 迁移到 git 标准布局
- 通过命令提取所有作者列表(在 Git Bash 中运行)
svn log -q svn://仓库地址 | grep -E "r[0-9]+ \| .+ \|" | cut -d'|' -f2 | sed 's/ //g' | sort -u > authors.txt
svn 仓库地址
svn://svn.svnbucket.com/kyan/svnbucket/
authors.txt 文件命可以任意命名,此文件用于记录所有提交者的用户名。执行命令后,会得到 svn 仓库的作者列表。内容如下:
kyan
编辑 authors.txt 文件,将用户名映射到 Git 邮箱地址,格式为:用户名 = 用户名 <邮箱地址>,如:
kyan = kyan0626 <10980059+kyan0626@user.noreply.gitee.com>
- 克隆 SVN 仓库到本地 Git
git svn clone <SVN_URL> --no-metadata --authors-file=authors.txt --stdlayout <本地目录>
git svn clone <SVN_URL> --no-metadata --authors-file=authors.txt --stdlayout my-project
- --no-metadata:省略 SVN 元数据
- --authors-file:指定作者映射文件
- --stdlayout:适用于标准布局(trunk/branches/tags)的 SVN 仓库
非标准布局需手动指定路径
git svn clone <SVN_URL> --trunk=trunk_path --branches=branches_path --tags=tags_path --authors-file=authors.txt <本地目录>
注意
- 执行命令:
git branch,master 本地分支

- 执行命令:
git branch -a,master 本地分支和远程分支

- 执行命令
git show-ref可以看到所有的引用(所有 svn 分支和标签,并且包含已删除分支和标签),可以看到有 master 这个本地分支,同时有 remote 分支

- 过滤掉 svn 中已删除的分支和标签
SVN_REPO_URL="https://svn.example.com/repo"
git svn fetch
git branch -r | grep 'origin/' | while read branch; do
svn_branch_name=${branch#origin/}
if [[ "$svn_branch_name" == tags/* ]]; then
tag_name=${svn_branch_name#tags/}
if ! svn ls "$SVN_REPO_URL/tags/$tag_name" 2>/dev/null; then
git branch -d -r "$branch"
fi
else
if ! svn ls "$SVN_REPO_URL/branches/$svn_branch_name" 2>/dev/null; then
git branch -d -r "$branch"
fi
fi
done
git fetch --prune
注释
#!/bin/bash
# 设置 SVN 仓库根目录(不含 /branches 或 /tags)
SVN_REPO_URL="https://svn.example.com/repo"
# 1. 获取最新 SVN 变更
git svn fetch
# 2. 遍历所有远程分支(包括标签)
git branch -r | grep '^origin/' | while read branch; do
# 提取分支/标签名(去掉 origin/ 前缀)
ref_name=${branch#origin/}
# 判断是分支还是标签
if [[ "$ref_name" == tags/* ]]; then
# 标签处理:提取标签名(去掉 tags/ 前缀)
tag_name=${ref_name#tags/}
# 检查 SVN 标签是否存在
if ! svn ls "$SVN_REPO_URL/tags/$tag_name" >/dev/null 2>&1; then
echo "删除标签: $branch (SVN 中已删除)"
git branch -D -r "$branch"
fi
else
# 分支处理
if ! svn ls "$SVN_REPO_URL/branches/$ref_name" >/dev/null 2>&1; then
echo "删除分支: $branch (SVN 中已删除)"
git branch -D -r "$branch"
fi
fi
done
# 3. 清理本地引用
git fetch --prune
- 清理与转换(关键步骤)
修复 SVN 标签(转为 Git 标签):
cd <本地目录>
git for-each-ref refs/remotes/origin/tags | cut -d / -f 5- | grep -v @ | while read tagname; do git tag "$tagname" "origin/tags/$tagname"; git branch -r -d "origin/tags/$tagname"; done
修复 SVN 分支(转为 Git 分支):
git for-each-ref refs/remotes/origin | grep -v tags | cut -d / -f 4- | grep -v @ | while read branchname; do git branch "$branchname" "refs/remotes/origin/$branchname"; done
删除自动生成的 trunk 分支(若存在)
git branch -D trunk
清理远程引用:
git remote rm origin
- 推送到 GitLab 或 gitee 等远程仓库
- 在 GitLab 创建空仓库,复制仓库 URL(如 https://gitlab.com/yourname/repo.git)
- 添加 GitLab 远程地址:
git remote add origin <GitLab_URL>
- 推送所有分支和标签:
git push origin --all
git push origin --tags
注意事项
- 映射文件 authors.txt 中,
用户名 = 用户名 <邮箱地址>,邮箱地址要首先在 gitlab 或 gitee 中存在(已使用的),并验证通过, 否则会导致 Git 无法识别邮箱地址。git push origin --all 会报错:邮箱地址未公开 - 在 gitee 中,邮箱如果不是公开的,在
个人设置->邮箱管理中,复制由 gitee 生成的邮箱地址到 authors.txt 文件中。
kyan = kyan0626 <10980059+kyan0626@user.noreply.gitee.com>
命令分析
svn log -q svn://仓库地址
- 功能:获取 SVN 仓库的提交日志,-q(quiet 模式/安静模式)仅输出元数据(版本号、作者、日期),不显示提交详情
- 输出示例:
r123 | username1 | 2025-01-01 r124 | username2 | 2025-01-02- svn://仓库地址: 仓库地址。
grep -E "r[0-9]+ | .+ |"
- 功能:使用扩展正则表达式(-E)过滤出符合格式 r[版本号] | [作者] | 的行:
- -E : 扩展正则表达式。
- r[0-9]+:匹配以 r 开头的版本号(如 r123)。
- | .+ |:匹配竖线分隔的作者字段(如 | username |)。
- 关键点:确保仅处理有效的日志行,跳过空行或格式错误行
cut -d'|' -f2
- 功能:以竖线 | 为分隔符(-d'|'),提取第 2 个字段(作者名)
- -d'|' : 分隔符为 |。
- -f2 : 取第二个字段。
- 示例输入/输出:输入:r123 | username1 | 2025-01-01 → 输出:username1(注意前后空格)
sed's/ //g'
- 功能:删除作者名字段中的所有空格(如 username1 → username1),确保名称标准化
- s/old/new/ : 替换 old 为 new。
- g : 全局替换。
- 技术细节 : s/ //g 是替换命令,g 表示全局替换(所有匹配的空格)
sort -u > authors.txt
- sort : 排序,按字母顺序排序作者名。
- -u : 去重,确保每个作者仅保留一次。
> authors.txt:将结果重定向到文件 authors.txt。- 输出示例:
username1 username2将用户名映射到 Git 邮箱地址,编辑 authors.txt 文件,将用户名替换为邮箱地址。
kyan = kyan0626 <10980059+kyan0626@user.noreply.gitee.com>
命令整体流程图:

svn 迁移到 git 非标准布局
生成 authors.txt 的方式不变,同上
- 分布操作
# 创建本地目录,目录名任意
mkdir p1 && cd p1
# 初始化Git-SVN仓库
git svn init svn://svn.svnbucket.com/kyan/test_none --trunk=/
# 执行获取,并且映射用户
git svn fetch --authors-file=../authors.txt
# 清理本地引用
git fetch --prune
报错
- 在 windows 下,执行
git svn init svn://svn.svnbucket.com/kyan/test_none --trunk=/可能会出现以下报错:
$ git svn clone svn://svn.svnbucket.com/kyan/test_none --trunk=/ p1
Initialized empty Git repository in C:/Users/Administrator/Desktop/test/p1/.git/
svn-remote.svn: remote ref '/Program Files/Git:refs/remotes/origin/trunk' must start with 'refs/'
cat .git/config
# 应包含:
# [svn-remote "svn"]
# url = svn://svn.svnbucket.com/kyan/test_none
# fetch = /Program Files/Git:refs/remotes/origin/trunk
这个错误表明 Git 在解析路径时遇到了问题,特别是因为 Git 安装路径包含空格(Program Files)。
解决方案:
方式 1
# 手动编辑配置(确保只设置 trunk)
git config svn-remote.svn.fetch :refs/remotes/origin/trunk
# 手动验证配置
cat .git/config
# 应包含:
# [svn-remote "svn"]
# url = svn://svn.svnbucket.com/kyan/test_none
# fetch = :refs/remotes/origin/trunk
方式 2
# 打开配置文件(使用任意文本编辑器)
notepad .git/config
在 [svn-remote "svn"] 部分修改为以下内容:
[svn-remote "svn"]
url = svn://svn.svnbucket.com/kyan/test_none
fetch = :refs/remotes/origin/trunk
# 显式禁用分支和标签,下面这两行可以不写,因为本来就没有branches和tags
branches =
tags =
- 清理 SVN 引用
查看提交记录,看到有 git-svn-id 的引用,表示已经成功迁移。
git log
commit a849eb5e80cf6fa16ff4809983b4f246ee983a53 (HEAD -> master, origin/trunk)
Author: kyan0626 <1648200276@qq.com>
Date: Mon Jul 7 09:43:45 2025 +0000
添加一个问价
git-svn-id: svn://svn.svnbucket.com/kyan/test_none@1 831f37c6-3093-4143-9286-06fa6fea8300
查看所有分支,包括远程分支和本地分支。remotes/origin/*不是我们想要的
git branch -a
* master
remotes/origin/trunk
删除 svn 远程引用,并推送到 gitlab 或 gitee 远程仓库
# 移除 git-svn-id
git filter-branch --msg-filter 'sed "/git-svn-id:/d"' -- --all
# 删除 SVN 远程引用
git branch -r -d origin/trunk
# 移除 SVN 配置
git config --remove-section svn-remote.svn
git config --remove-section svn
# 删除 SVN 元数据
rm -rf .git/svn
# 添加 Gitee 远程
git remote add origin https://gitee.com/your_username/your_repo.git
# 强制推送
git push origin master --force
