如何解决代码冲突

1,549 阅读3分钟

下文分支命名不规范,太山寨,忽略就好,因为不是重点。

很抗拒写这类文章,感觉这是作为开发最基本的技能要求,但现实狠狠的打了我的脸,很多同学并不知道怎么解决冲突,甚至不知道为什么会有冲突?

image.png

冲突从何来?

不会画图,看文字描述吧

正常的项目开发我们不会直接基于主干(master)开发,而是基于 master checkout 出我们自己的迭代分支 dev,然后大家基于 dev 分支再次切出自己的开发分支,例如 A 同学基于 dev 分支切出了 a 分支 , B 同学基于 dev 分支切出了 b 分支,然后大家一起愉快的进行代码开发。

但不巧的是,A  和 B 修改了相同的文件(index.ts)

branch: a

/** 开发分支 */
export const NAME = "柯南";

branch: b

/** 开发分支 */
export const NAME = "小敏";
export const AGE = 18;

由于 A 效率比较高,先将代码提 PR 合并到 dev 分支上了,当 B 去提 PR 时收到了冲突反馈

image.png

遇到这种情况,我们一般使用如下方案:

  1. 基于最新的 dev 分支重新拉个分支出来,将 b 的代码 merge 进去

  2. 将最新的 dev 分支直接 merge 到  b 分支

这里我们介绍第二种,将最新代码 merge 到 b 分支,在 b 分支终端执行如下命令:


git merge --squash origin/dev

如果我们本地没有远程分支 dev 的话需要先 fetch 一下,git fetch -p

  • --squash:不携带 a 分支的 commit 信息

  • origin: 远程分支

执行完成后,我们会得到如下完美代码,这就是代码冲突。

image.png

如何解决?

使用当前更改

这个时候 a 提交到改动会被删除,完全使用 b 的代码,点击Accept Current Change即可。

image.png

结果:

/** 开发分支 */
export const NAME = "小敏";
export const AGE = 18;

使用远程更改

这个时候 b 的冲突代码会被删除,完全使用 a 的代码,点击 Accept Incoming Change 即可。

结果:

/** 开发分支 */
export const NAME = "柯南";

两者合并

前面两种情况都比较简单,而且少见,例如我们期望的最终代码如下:

/** 开发分支 */
export const AGE = 18;
export const NAME = "柯南";

这个时候我们就需要接受 2 者(Accept Both Changes)的改动,来形成一个最终的更改

image.png

然后删除无用代码:

/** 开发分支 */
export const AGE = 18;
export const NAME = "柯南";

然后再次 commit 并提交 PR 即可。

这里需要注意,由于不同平台检测代码的方式不一样,我们虽然解决了冲突,但提交 PR 时还有可能提示冲突,这个时候需要在平台上进行处理,例如 GitHub 的 PR。

image.png

VS Code 提供了很多便捷操作,我们在足够自信的时候可以使用右侧的批量操作,鼠标右键即可,可一次选中多个文件进行操作。

image.png

原则

解决冲突的方式很多,但我们应该遵循远程最优原则

  1. 不是自己修改的代码,使用远程代码

  2. 自己没有新增的文件,如果 PR 里面有 diff ,删除

  3. 遇到不确定的点,找线上代码的同学确认