起因
在某次需求开发中新增了一个npm包,在进行代码合并时,yarn.lock
产生了合并冲突。
这种情况下,我通常都是直接 yarn install
解决。
不过一直都没关注 yarn install
到底怎么解决的冲突,这次就来简单梳理下 yarn.lock
冲突解决背后发生了什么。
解决 yarn.lock
冲突的方法
经过一番搜寻,发现目前有三种方式来搞。
一是手动解决,纯手工一个一个对比冲突。
这种方式如果只有几个小的改动还行,当你的 yarn.lock
改动很多,那么手动是没法搞定的。
二是先将 yarn.lock
还原为 base branch
的版本(通常是 origin/master
),解决完 package.json
的冲突后,再进行 yarn install
。
git checkout origin/master -- yarn.lock
yarn install
三是直接进行 yarn install
,把冲突解决交给 yarn
来处理。
yarn install
...
yarn install v1.22.4
info Merge conflict detected in yarn.lock and successfully merged.
...
那么 yarn install
的冲突解决策略是怎样的呢?我又搜寻了一番,但并没有发现有相关的文章描述这个策略。
不过我通过Yarn 1.0的发布日志找到了这个feature的merge request,并在这个mr下找到了对应的测试用例,我们可以通过这些测试用例来大概了解下 yarn install
的冲突解决策略。
(既然找到了对应的文件,我选择直接看最新版本的测试用例就好了)
https://github.com/yarnpkg/yarn/blob/master/__tests__/lockfile.js
测试用例中 yarn install
的冲突解决策略有这几种情况:
- 单个简单冲突
const file = `
a:
no "yes"
<<<<<<< HEAD
b:
foo "bar"
=======
c:
bar "foo"
>>>>>>> branch-a
d:
yes "no"
`
{
a: {no: 'yes'},
b: {foo: 'bar'},
c: {bar: 'foo'},
d: {yes: 'no'},
}
- 带CRLF的单个简单冲突
const file =
'a:\r\n no "yes"\r\n\r\n<<<<<<< HEAD\r\nb:\r\n foo "bar"' +
'\r\n=======\r\nc:\r\n bar "foo"\r\n>>>>>>> branch-a' +
'\r\n\r\nd:\r\n yes "no"\r\n';
{
a: {no: 'yes'},
b: {foo: 'bar'},
c: {bar: 'foo'},
d: {yes: 'no'},
}
- 多个冲突
const file = `
a:
no "yes"
<<<<<<< HEAD
b:
foo "bar"
=======
c:
bar "foo"
>>>>>>> branch-a
d:
yes "no"
<<<<<<< HEAD
e:
foo "bar"
=======
f:
bar "foo"
>>>>>>> branch-b
`
{
a: {no: 'yes'},
b: {foo: 'bar'},
c: {bar: 'foo'},
d: {yes: 'no'},
e: {foo: 'bar'},
f: {bar: 'foo'},
}
- 冲突合并失败
const file = `
<<<<<<< HEAD
b:
foo: "bar
=======
c:
bar "foo"
>>>>>>> branch-a
`
0
- 丢弃冲突的公共祖先
const file = `
<<<<<<< HEAD
b:
foo "bar"
||||||| common ancestor
d:
yes "no"
=======
c:
bar "foo"
>>>>>>> branch-a
`
{
b: {foo: 'bar'},
c: {bar: 'foo'},
}
简单浏览完之后,发现大致的策略就是冲突时尽量保留两者,感兴趣的同学还可以直接看看源码中是怎么处理 lockfile
的,位置在 /src/lockfile/parse.js
在我看来,手动解决适合一两个冲突的解决。
而直接使用 yarn install
和 还原 yarn.lock
到 base branch
后再进行 yarn install
都是可行的方法。
当然,还有上面没提及的:直接删除 yarn.lock
,再 yarn install
,这种方式风险巨大,强烈不推荐。
小结
解决 yarn.lock
冲突背后还涉及很多知识点,比如
yarn.lock
、package-lock.json
的机制?- 安装缓存
yarn cache
npm cache
yarn install
的过程,模块扁平化
… …
平时还是应该多多深入了解使用的工具,来避免一些令人惊喜的BUG的产生。