第一部分:SVN 分支管理最佳实践

一、标准目录结构(约定优于配置)

SVN 本身不强制目录结构,但业界公认的标准布局是 trunk / branches / tags 三件套

repository/
├── trunk/                    # 主干:主开发线,始终保持可用
│   ├── rtl/
│   ├── verification/
│   └── docs/
├── branches/                 # 分支:并行开发
│   ├── feature_uart/         # 特性分支
│   ├── bugfix_clk_issue/     # 缺陷修复分支
│   └── dev_team_a/           # 团队/个人分支
└── tags/                     # 标签:只读版本快照
    ├── v1.0_tapeout/         # 流片版本
    ├── v1.1_release/
    └── milestone_rtl_freeze/

大型项目(多模块)布局

repository/
├── project_soc/
│   ├── trunk/
│   ├── branches/
│   └── tags/
├── project_ip_uart/
│   ├── trunk/
│   ├── branches/
│   └── tags/
└── ...

每个独立可发布单元(IP/子系统)拥有自己的 trunk/branches/tags。


二、三类目录的职责

目录职责规则
trunk主开发线,集成所有功能保持随时可编译/可仿真,不放未完成的破坏性代码
branches隔离开发,不影响主干特性、修复、实验都在分支进行,完成后合并回 trunk
tags版本快照,只读创建后绝不修改,仅用于标记里程碑/发布/流片

三、分支策略(何时建分支)

1. 特性分支(Feature Branch)

为新功能开发创建,避免半成品污染主干:

svn copy https://repo/trunk \
         https://repo/branches/feature_axi_dma \
         -m "create feature branch for AXI DMA"

适用:开发周期长、影响范围大的新功能。

2. 缺陷修复分支(Bugfix Branch)

针对已发布版本修 bug,不引入主干新功能:

svn copy https://repo/tags/v1.0_release \
         https://repo/branches/bugfix_v1.0_clk \
         -m "fix clock bug on v1.0"

3. 发布分支(Release Branch)

发布前稳定化,主干可继续开发新功能:

svn copy https://repo/trunk \
         https://repo/branches/release_v2.0 \
         -m "create release branch v2.0"

4. 个人/团队分支

大团队隔离工作,减少互相干扰(但要定期同步主干)。


四、分支生命周期管理

         创建分支               定期同步trunk            合并回trunk        删除分支
trunk ─────●──────────────────────────●─────────────────────●──────────────►
            \                         ↑                     ↗
             \                   (merge trunk→branch)      /
branch        ●──────●──────●──────────────────●──────────●
              开发    开发    开发              开发完成

1. 创建分支

svn copy <trunk-url> <branch-url> -m "说明"
svn switch <branch-url>           # 切换工作副本到分支

2. 在分支上开发

# 正常 update / commit
svn up
svn ci -m "develop on branch"

3. 定期同步主干改动到分支(关键!)★

最重要的最佳实践:分支要定期合并 trunk 的更新,避免最后合并时冲突爆炸。

# 在分支工作副本中
svn merge https://repo/trunk         # 把 trunk 的新改动合进当前分支
svn ci -m "sync trunk changes to branch"

4. 分支合并回主干

# 切换到 trunk 工作副本
svn switch https://repo/trunk
svn up

# 合并分支(SVN 1.5+ 自动跟踪合并历史)
svn merge https://repo/branches/feature_axi_dma
svn ci -m "merge feature_axi_dma into trunk"

5. 删除已合并的分支

svn delete https://repo/branches/feature_axi_dma \
           -m "remove merged branch"

删除不丢历史,需要时可从历史版本恢复。


五、合并(Merge)的关键技巧

1. SVN 1.5+ 的自动合并跟踪

SVN 1.5 起引入 mergeinfo 属性,自动记录已合并的版本,避免重复合并

svn merge <branch-url>            # 自动合并未合并的部分
svn mergeinfo <branch-url>        # 查看合并状态
svn mergeinfo --show-revs eligible <branch-url>  # 查看待合并版本

2. 合并指定版本范围

svn merge -r 100:150 <branch-url>     # 合并版本100到150
svn merge -c 120 <branch-url>         # 只合并版本120这一次提交
svn merge -c 120,125,130 <branch-url> # 合并多个特定版本

3. 反向合并(撤销某次提交)

svn merge -c -120 <url>               # 撤销版本120的改动(负号)
svn merge -r 120:119 <url>            # 等效写法

4. 预演合并(试运行,不实际改动)★

svn merge --dry-run <branch-url>      # 只显示会发生什么,不真正合并

强烈建议:正式合并前先 --dry-run 看看影响范围。

5. 合并后必检

svn status                        # 查看冲突和改动
# 解决冲突...
svn diff                          # 确认合并结果正确
# 编译/仿真验证后再提交
svn ci -m "merge xxx"

六、Tag 标签最佳实践

1. 创建标签(里程碑/流片)

svn copy https://repo/trunk \
         https://repo/tags/v1.0_tapeout_20240115 \
         -m "tag for v1.0 tapeout"

2. Tag 命名规范建议

场景命名示例
版本发布v1.0, v2.1.3
流片v1.0_tapeout_20240115
RTL 冻结rtl_freeze_milestone1
回归基线regression_baseline_w12

3. Tag 铁律

⚠️ Tag 创建后绝对不要修改! Tag 是某一时刻的只读快照,修改 tag 会破坏可追溯性。如需基于 tag 改动,应从 tag 创建分支

# 从 tag 创建修复分支(正确做法)
svn copy https://repo/tags/v1.0 \
         https://repo/branches/fix_v1.0 \
         -m "branch from v1.0 for hotfix"

七、芯片团队特有最佳实践

实践说明
流片打 Tag每次 tapeout 必须打 tag,永久固化版本
RTL 冻结 Tag验证/后端介入前冻结 RTL 版本
回归基线管理每周/每日回归对应一个 tag/revision,便于复现
二进制文件锁定库/版图/文档在分支上也要 svn lock
分支命名带日期/负责人如 dev_zhang_20240115,便于管理
大文件慎合并二进制不可 merge,分支策略上避免多分支同改一个二进制

八、分支管理常见误区与建议

误区正确做法
长期不合并 trunk定期同步,至少每周一次
分支存活过久功能完成尽快合并并删除,避免"僵尸分支"
直接在 trunk 上做大改动大改动开分支,保护主干稳定
修改 tagtag 只读,要改就从 tag 开分支
不写合并说明合并提交注明来源分支和版本范围
合并前不 dry-run先 --dry-run 预演
合并后不验证合并后编译/仿真通过再提交


第二部分:SVN 与 Git 命令对照表

一、核心概念差异(先理解再对照)

维度SVNGit
架构集中式(中央仓库)分布式(每人完整仓库)
提交直接提交到中央服务器先本地 commit,再 push 到远程
版本号全局递增整数(r123)40 位哈希(a3f5e9c...)
离线工作受限(需连服务器)完全支持
分支成本较重(服务器端副本)极轻量(指针)
暂存区有(staging area)

最大区别:Git 的 commit 是本地操作,需要 push 才到远程;SVN 的 commit 直接到中央服务器


二、基础操作对照

操作SVNGit
获取仓库svn checkout <url>git clone <url>
更新代码svn updategit pull
查看状态svn statusgit status
查看差异svn diffgit diff
添加文件svn add <file>git add <file>
删除文件svn delete <file>git rm <file>
移动/重命名svn move <a> <b>git mv <a> <b>
提交svn commit -m "msg"git commit -m "msg" + git push
查看历史svn loggit log
查看文件历史svn log <file>git log <file>
逐行作者svn blame <file>git blame <file>

三、提交流程对照(核心差异)

SVN(两步)

svn add new.v               # 1. 添加新文件
svn commit -m "add new.v"   # 2. 直接提交到服务器

Git(四步)

git add new.c               # 1. 添加到暂存区
git commit -m "add new.c"   # 2. 提交到本地仓库
git pull                    # 3. 同步远程(合并)
git push                    # 4. 推送到远程仓库

SVN 一次 commit = Git 的 commit + push。


四、撤销操作对照

操作SVNGit
撤销工作区改动svn revert <file>git checkout -- <file><br>或 git restore <file>
撤销所有改动svn revert -R .git checkout -- .<br>或 git restore .
撤销暂存(无暂存区概念)git reset HEAD <file><br>或 git restore --staged <file>
撤销某次提交svn merge -c -N .git revert <commit>
回退到旧版本svn up -r Ngit reset --hard <commit>
清理锁定svn cleanup(一般不需要)

五、分支与标签对照

操作SVNGit
创建分支svn copy <trunk> <branch> -m "..."git branch <name>
切换分支svn switch <branch-url>git checkout <name><br>或 git switch <name>
创建并切换svn copy ... + svn switch ...git checkout -b <name>
查看分支svn list <branches-url>git branch
合并分支svn merge <branch-url>git merge <branch>
删除分支svn delete <branch-url> -m "..."git branch -d <name>
创建标签svn copy <trunk> <tag> -m "..."git tag <name>
查看标签svn list <tags-url>git tag

关键差异:SVN 的分支/标签本质是目录拷贝(用 copy 命令);Git 的分支是轻量指针,标签是特定提交的引用


六、查看与比较对照

操作SVNGit
查看仓库文件内容svn cat <url>git show <commit>:<file>
列出远程内容svn list <url>git ls-tree <branch>
比较两版本svn diff -r 100:200git diff <c1> <c2>
比较分支svn diff <url1> <url2>git diff <b1> <b2>
合并预演svn merge --dry-rungit merge --no-commit --no-ff
查看合并状态svn mergeinfo <url>git log --merges

七、冲突处理对照

操作SVNGit
冲突标记状态 C状态 UU(both modified)
解决后标记svn resolve --accept working <file>git add <file>
用我的版本svn resolve --accept mine-fullgit checkout --ours <file>
用对方版本svn resolve --accept theirs-fullgit checkout --theirs <file>

八、忽略文件对照

SVN

svn propset svn:ignore "*.log" .
svn propset svn:ignore -F ignore_list .

Git

# 创建 .gitignore 文件,写入:
*.log
*.o
build/

Git 用 .gitignore 文件(更直观);SVN 用 svn:ignore 属性。


九、独有命令(无直接对应)

SVN 独有

命令功能Git 类比
svn lock/unlock文件加锁(独占编辑)git lfs lock(需 LFS)
svn cleanup清理工作副本锁一般不需要
svn co <子目录>部分检出git sparse-checkout(较新)

Git 独有

命令功能SVN 类比
git stash临时储藏改动无(只能用补丁)
git rebase变基
git cherry-pick挑拣单个提交svn merge -c N 类似
git reflog引用日志
git add -p部分暂存
git push/pull远程同步SVN 自动(集中式)

十、典型工作流对照

日常修改提交

SVN:

svn up                          # 更新
# 修改文件...
svn st                          # 看状态
svn ci -m "fix bug"             # 提交(直接到服务器)

Git:

git pull                        # 更新
# 修改文件...
git status                      # 看状态
git add .                       # 暂存
git commit -m "fix bug"         # 本地提交
git push                        # 推送到远程

创建特性分支开发

SVN:

svn copy <trunk> <branch> -m "new feature"
svn switch <branch>
# 开发、提交...
svn switch <trunk>
svn merge <branch>
svn ci -m "merge feature"

Git:

git checkout -b feature
# 开发、提交...
git checkout main
git merge feature
git push

十一、思维方式转换提示

如果你习惯 SVN,用 Git 要记住如果你习惯 Git,用 SVN 要记住
commit 是本地的,要 push 才上传commit 直接上传到服务器
分支是廉价的,随便建分支是目录拷贝,相对重
有暂存区,先 add 再 commit没有暂存区,add 只针对新文件
版本是哈希,不是递增数字版本是全局递增整数
用 .gitignore 文件用 svn:ignore 属性
pull = fetch + mergeupdate 直接合并

十二、命令对照速查表(汇总)

功能SVNGit
检出/克隆svn co <url>git clone <url>
更新svn upgit pull
状态svn stgit status
添加svn addgit add
提交svn ci -mgit commit -m + git push
差异svn diffgit diff
日志svn loggit log
撤销改动svn revertgit restore
删除svn rmgit rm
移动svn mvgit mv
建分支svn copygit branch
切分支svn switchgit switch
合并svn mergegit merge
打标签svn copy ...tags/git tag
作者追溯svn blamegit blame
加锁svn lockgit lfs lock

总结

SVN 分支管理黄金法则

  1. trunk 保持稳定,随时可编译仿真
  2. 大改动开分支,隔离风险
  3. 分支定期同步 trunk(最重要,避免合并地狱)
  4. 合并前 dry-run,合并后验证
  5. tag 只读,流片/发布必打 tag
  6. 及时删除僵尸分支

SVN vs Git 一句话

SVN 集中式:commit 直达服务器,分支是目录拷贝,版本号递增,适合大文件+强管控(芯片行业)。 Git 分布式:commit 在本地,分支是轻量指针,需要 push/pull,适合文本代码+并行协作(软件行业)。

核心记忆svn commit ≈ git commit + git pushsvn update ≈ git pull

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐