icodingicoding
主页
JavaScript
Vue
React
TypeScript
Node
bug
笔记
时间线
主页
JavaScript
Vue
React
TypeScript
Node
bug
笔记
时间线
  • Markdown 语法
  • 插件
  • Vue
  • 组件设计
  • Element-Ui
  • WebSocket
  • CSS
  • Uniapp
  • 进阶
  • 扫码枪
  • Nginx
  • Nuxt.js
  • Vue 时钟
  • Learning
  • Linux
  • 打包优化
  • 大屏可视化
  • Jenkins
  • SVN
  • JsDocs
  • 代码规范

SVN

svn 使用教程

vscode 使用 svn 插件

  • 步骤一 image

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

where svn

image

添加 .gitignore 文件

使用 svn propset 命令

  1. 在项目根目录下创建 .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
  1. 绑定忽略规则到版本库 通过命令行将 .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 .
  1. 查看属性内容

查看 svn:ignore 属性内容:

svn propget svn:ignore .

image

TIP

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

查看属性列表 ​

svn proplist . -v

image

  1. 提交变更

  2. 后续修改 .gitignore 文件,需要再次执行 svn propset svn:ignore -F .gitignore . 命令绑定新的忽略规则到版本库。然后提交变更。

使用 TortoiseSVN 图形界面操作

  1. 右键菜单操作

在项目根目录右键选择 TortoiseSVN → 属性 → 新建(如果没有 svn:ignore 属性则新建) → 其他 → svn:ignore → 一行一个配置

  • 右键-属性

image

  • 新建-其他

image

  • 选择 svn:ignore

image

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

image

  1. 提交变更

svn 迁移到 git 标准布局

  • svn 迁移到 git
  • svn 迁移 git 官网
  1. 通过命令提取所有作者列表(在 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>
  1. 克隆 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 本地分支

image

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

image

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

image

  1. 过滤掉 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
  1. 清理与转换(关键步骤)

修复 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
  1. 推送到 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 文件中。 image
    kyan = kyan0626 <10980059+kyan0626@user.noreply.gitee.com>
    

命令分析

  1. svn log -q svn://仓库地址

    • 功能:获取 SVN 仓库的提交日志,-q(quiet 模式/安静模式)仅输出元数据(版本号、作者、日期),不显示提交详情
    • 输出示例:
    r123 | username1 | 2025-01-01
    r124 | username2 | 2025-01-02
    
    • svn://仓库地址: 仓库地址。
  2. grep -E "r[0-9]+ | .+ |"

    • 功能:使用扩展正则表达式(-E)过滤出符合格式 r[版本号] | [作者] | 的行:
    • -E : 扩展正则表达式。
    • r[0-9]+:匹配以 r 开头的版本号(如 r123)。
    • | .+ |:匹配竖线分隔的作者字段(如 | username |)。
    • 关键点:确保仅处理有效的日志行,跳过空行或格式错误行
  3. cut -d'|' -f2

    • 功能:以竖线 | 为分隔符(-d'|'),提取第 2 个字段(作者名)
    • -d'|' : 分隔符为 |。
    • -f2 : 取第二个字段。
    • 示例输入/输出:输入:r123 | username1 | 2025-01-01 → 输出:username1(注意前后空格)
  4. sed's/ //g'

    • 功能:删除作者名字段中的所有空格(如 username1 → username1),确保名称标准化
    • s/old/new/ : 替换 old 为 new。
    • g : 全局替换。
    • 技术细节 ​​: s/ //g 是替换命令,g 表示全局替换(所有匹配的空格)
  5. sort -u > authors.txt

    • sort : 排序,按字母顺序排序作者名。
    • -u : 去重,确保每个作者仅保留一次。
    • > authors.txt:将结果重定向到文件 authors.txt。
    • 输出示例:
    username1
    username2
    
  6. 将用户名映射到 Git 邮箱地址,编辑 authors.txt 文件,将用户名替换为邮箱地址。

    kyan = kyan0626 <10980059+kyan0626@user.noreply.gitee.com>
    

命令整体流程图:

image

svn 迁移到 git 非标准布局

生成 authors.txt 的方式不变,同上

  1. 分布操作
# 创建本地目录,目录名任意
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 =
  1. 清理 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
最后编辑:
上一页
Jenkins
下一页
JsDocs