1. 先搞清楚:合并冲突到底是怎么发生的
1.1 冲突的本质:同一行代码的“双人舞”
先说一个很多人没想明白的事:SVN合并冲突不是软件出bug了,也不是你的操作姿势不对,而是两个改动真正“撞车”了。想象一下你和同事同时改了同一个文件里的同一行,你提交之后,他再 svn up 或者把分支合并回主干,SVN拿到两份不同的修改,不知道该听谁的,只能把问题抛给你——这就是冲突。
所以处理冲突的第一步,不是急着点选项,而是冷静下来搞清楚:这次冲突到底动了哪几行?动代码的人分别是谁?两边改动的意图分别是什么?
我曾经见过一个团队新人,遇到冲突后想都没想就点了“use mine”(使用我的版本),结果把同事重构的接口签名整个覆盖了,项目直接编译失败。后来排查了大半天才找到原因。这个教训说明:处理选项不是随机抽奖,选错了比不选更致命。
1.2 SVN能自动做哪些事,必须人工处理的又是什么
很多人以为“合并”是SVN把两个文件完全融合起来,这其实是误会。SVN的自动合并能力只限于文本文件中互不重叠的修改区域。
举个例子:你改了文件第10行,同事改了第80行,两份修改互不干扰,SVN会自动把两处改动都保留,完成一次无声无息的合并。但如果你们俩都改了第50行附近,哪怕改的具体内容不同,SVN就无法判断谁是对的,只能标记冲突,等你决策。
这里有个关键认知:冲突并不代表别人改得有问题,也不代表你改得有问题,它只是代表“两个改动在语义上可能存在矛盾,需要人类判断”。所以处理冲突的核心能力不是会点按钮,而是能读懂两边的代码,判断出哪种组合才是正确的最终结果。
1.3 三种冲突类型,先分清敌人是谁
很多教程上来就直接讲按钮,结果读者看到一堆英文选项就懵了。我建议先从冲突类型入手,因为不同冲突的处理方式完全不同。
SVN冲突分三类:
| 冲突类型 | 触发场景 | 处理复杂度 |
|---|---|---|
| 文本冲突 | 两份修改改了同一文件的相同区域 | 中,需要逐块判断 |
| 属性冲突 | 两份修改改了同一个SVN属性(如svn:mergeinfo) |
低,通常选一个即可 |
| 树冲突 | 一个改动涉及文件新增/删除/重命名,另一个改动也涉及同一文件 | 高,往往需要额外命令配合 |
我见过最多的是文本冲突,其次是树冲突。属性和树冲突往往出现在分支合并场景中,很多人第一次遇到时完全摸不着头脑。所以下面我会分别展开讲,还会给出一套“看到冲突不慌”的处理流程图思路。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 处理选项逐个拆解:“我的”“他们的”到底是谁
2.1 先记住一个原则:不同的操作,主语完全不同
这是全文最重要的一块。TortoiseSVN也好,命令行也好,冲突处理选项里都会出现 mine 和 theirs 两个词,中文界面翻译成“我的”和“他们的”。但问题是:在不同操作场景下,“我”和“他们”指的对象是完全不一样的。
我整理了一张表,建议你直接收藏:
| 操作场景 | “我的”(mine) | “他们的”(theirs) |
|---|---|---|
svn update(更新工作副本) |
我本地未提交的修改 | 仓库里别人的最新提交 |
svn merge(分支合并) |
当前工作副本/目标分支的内容 | 从源分支合并进来的修改 |
svn switch(切换分支) |
本地已做的修改 | 目标分支差量带来的内容 |
举个最常见的例子。你在trunk上改了几行代码,还没提交,这时候同事在trunk上提交了也改到同一区域的版本,你执行svn update时冲突了。此时TortoiseSVN弹窗里的“use mine”指保留你本地改的,“use theirs”指采用仓库里的新版本。
但在另一个场景下就不一样了:你在feature-branch分支上开发完,要把trunk合并过来(svn merge trunk .),这时冲突弹窗里“mine”指你分支上已有的内容,“theirs”指从trunk合并进来的内容。这和svn update场景正好打了个调。
所以,**遇到冲突不要急着选,先确认你现在做的是update
