网易首页 > 网易号 > 正文 申请入驻

码住!Git Merge 小技巧

0
分享至

作者:dxweixiao,腾讯CSIG前端开发工程师

丹尼尔:Hi,蛋兄,周杰伦都出新专辑了,你咋还不更新啊,真的打算半年一更啊?

蛋先生:好像确实是这样,要不,择日不如撞日,今天聊聊?

丹尼尔:好啊,那聊些啥呢?

蛋先生:最近搞的事情需要实现两个应用项目的代码合并,逻辑就完全参照 git merge 的基本原则,那就聊聊 git merge 吧

丹尼尔:git merge 我倒是经常用,不过却从未关心过它内部是怎么实现的。那你跟我讲一下它的工作原理呗。

合并的基本原则: three-way

蛋先生:git merge 的基本原则是 three-way

丹尼尔:3 条路?啥东东?

蛋先生:简单讲就是有 3 个分支。假设就叫 a, o, b,其中 a 和 b 都来自于 o,如下所示:

丹尼尔:嗯,然后呢?

蛋先生:现在 a 和 b 要进行合并。假设你当前在 a 分支,然后运行 git merge b,那么合并结果是根据 a, o, b 之间的内容比较结果分析得出的。

丹尼尔:哦,嗯,比较逻辑是什么呢?

蛋先生:Very 简单。只要 a, o, b 任意两个的内容一致,就放弃 o 的内容;如果都不一样,就冲突。如下图所示

丹尼尔:只要...

蛋先生:我还是列举下所有的场景吧,然后你就会明白了

1). o == a, o != b

假设内容如下: o: daniel a: daniel b: dx-b

a merge b 的结果: dx-b

2). o == b, o != a

假设内容如下: o: daniel a: dx-a b: daniel

a merge b 的结果: dx-a

3). a == b, o != a

假设内容如下: o: daniel a: dx-ab b: dx-ab

a merge b 的结果: dx-ab

4). o != a, o != b, a != b

假设内容如下: o: dx-o a: dx-a b: dx-b

a merge b 的结果: 冲突

<<<<<<< a dx-a ======= dx-b >>>>>>> b

丹尼尔:哦,懂了,就是以 o 为基准来判断该保留哪个分支的内容,如果判断不了,就提示冲突,自行解决。

蛋先生:没错

丹尼尔:上面是假设 3 个分支要对比的文件都存在,那如果某个分支的文件被删除或有新文件,该怎么处理呢?

蛋先生:你可以把缺少的文件当作空内容文件来处理。嗯,这样说好像也不太准确。我还是再列举下场景吧。以下假设要比较各分支的 dx.txt 文件

1). o 有, a 有, b 没

  • 假设 1: o == a

合并结果:删除文件

因为 o == a,所以取 b 的结果
  • 假设 2: o != a

合并结果:保留文件,内容为 a 的内容

因为 o, a, b 互不相同,结果为冲突,但 b 没有文件,所以冲突结果直接取 a 的内容

2). o 有, a 没, b 有

与(1)类似,相当于把 a 换成 b

3). o 有, a 没, b 没

合并结果:删除文件

a == b,所以取 a 或 b 的结果,即删除

4). o 没, a 有, b 没

合并结果:取 a 的内容

o == b,所以取 a 的内容

5). o 没, a 没, b 有

与 (4) 类似,相当于把 a 换成 b

6). o 没, a 有, b 有

  • 假设 1: a == b

合并结果:取 a(或 b)的内容

  • 假设 2: a != b

合并结果:冲突

丹尼尔:漂亮,这下我完全搞懂了合并逻辑了。

Diff 的实现算法:最长公共子序列

丹尼尔:但我还有一个疑问,对比文件内容的时候,是一行一行内容对比的吧

蛋先生:那是当然了

丹尼尔:那如果我加多一行,故意错开,岂不是都对不上了

蛋先生:当然...是不会犯这样低级的错误的。在实现 diff 的时候,是利用了 LCS(Longest Common Sequence,即最长公共子序列)的算法。用下图来简单了解一下

假设有两个字符串 S1 和 S2,那它们的最长公共子序列就是 abcd

S1: "abcde" S2: " a1bc2d"

丹尼尔:哦。但这是字符串,该怎么应用到文件内容的 diff 上呢?

蛋先生:把图转一转,每个方块代表文件的一行内容,是不是就一样了

丹尼尔:是哦。通过 LCS 的算法,就算我故意错开了行,也不影响比较,因为相同内容的行总是能对得上

蛋先生:恩,不过这里只是两个文件的比较,而 three-way 是三个文件内容的比较,要稍微多做点事

丹尼尔:能讲得具体一点吗?

蛋先生:上个图吧。假设我们要合并 a 和 b 分支的 dx.txt 文件,先使用 LCS 来计算三个分支该文件内容的最长公共子序列(下图就是连线的内容为a,c,e的行),然后以这些子序列对各个文件的内容行进行分割,分割的块(下图中杂乱曲线的部分)就是不相同的部分,对这些块的内容进行 three-way 分析,即可得出这些内容块合并后的结果

丹尼尔:恩,终究还是有图有真相啊,图一看就明白了。讲了这么多,要不直接 show 下代码吧

蛋先生:一样的思路,可以有各种各样的实现。我自个实现了一个简单的版本,请移步到 codepen.io 查看。也可以去瞧瞧 node-diff3 的代码实现,它比较严谨,毕竟是一个可上生产的模块

丹尼尔:好咧,等会就去观摩观摩

小插曲

丹尼尔:我刚刚特意上网查了一下,git merge 的默认策略是 recursive,为啥叫递归呢?

蛋先生:还记得 git merge 的基本原则是 three-way 吗?a 和 b 的共同祖先是 o,但有些情况下,a 和 b 的共同祖先可能不止一个,这时就需要将这些共同祖先通过 three-way 进行合并,这个动作会一直往上递归到根祖先分支,所以这也是策略叫 recursive 的原因。

丹尼尔:除了 recursive,git merge 还有哪些合并策略呢?

蛋先生:这个就要看你安装的 git 的版本了。git merge 可以指定合并策略。这里有个小技巧,你可以故意给个不存在的策略名称,git 就会显示出所有可用的策略名称,如下所示:

$ git merge -s dxCould not find merge strategy 'dx'.Available strategies are: octopus ours recursive resolve subtree. 最后

丹尼尔:要不是我买了周杰伦的专辑,才想起你也好久没更新了,也就不会有今天这一出了

蛋先生:感谢提醒,合作愉快

丹尼尔:真快,又到了说再见的时候了

蛋先生:See you next time!

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
英伟达宣布黄仁勋随特朗普访华,最后一刻如何加入?

英伟达宣布黄仁勋随特朗普访华,最后一刻如何加入?

红星新闻
2026-05-13 11:47:14
网友怀疑自助餐加了饱腹剂 记者调查揭开真相

网友怀疑自助餐加了饱腹剂 记者调查揭开真相

大唐
2026-05-13 18:58:18
玛格特·罗比机场穿搭曝光,这条43美元牛仔裤火了

玛格特·罗比机场穿搭曝光,这条43美元牛仔裤火了

追星雷达站
2026-05-13 06:04:31
杜锋下课?广东男篮做法有深意,远超外界猜测,徐杰或成交易筹码

杜锋下课?广东男篮做法有深意,远超外界猜测,徐杰或成交易筹码

萌兰聊个球
2026-05-13 16:32:05
官宣!6月1日起车管所“下岗”?3.3亿车主迎来特大喜讯

官宣!6月1日起车管所“下岗”?3.3亿车主迎来特大喜讯

生活魔术专家
2026-05-13 18:49:27
欧美为什么希望我们也不要加班?

欧美为什么希望我们也不要加班?

罗sir财话
2026-05-11 17:35:24
套路地方国资?追觅俞浩回怼资金链质疑:先还花呗再评价我们

套路地方国资?追觅俞浩回怼资金链质疑:先还花呗再评价我们

南方都市报
2026-05-13 11:54:10
释永信“开光”真相大白,过程不堪入目,易中天也被牵连

释永信“开光”真相大白,过程不堪入目,易中天也被牵连

往史过眼云烟
2026-03-24 17:05:24
兵败如山倒!国产新能源或已经证明:中国压根不需要二线豪华品牌

兵败如山倒!国产新能源或已经证明:中国压根不需要二线豪华品牌

蜉蝣说
2026-05-12 11:08:06
新婚之夜,新娘出上联:洞中水汪汪;新郎对出的下联太有意境了!

新婚之夜,新娘出上联:洞中水汪汪;新郎对出的下联太有意境了!

户外阿崭
2026-05-13 17:10:31
央视拒付天价转播费仅1天!炸出一堆牛鬼蛇神,中国球迷有话要说

央视拒付天价转播费仅1天!炸出一堆牛鬼蛇神,中国球迷有话要说

青梅侃史啊
2026-05-09 11:48:33
C罗放弃戴帽成全兄弟!本泽马曝C罗让点内幕,揭秘总裁更衣室地位

C罗放弃戴帽成全兄弟!本泽马曝C罗让点内幕,揭秘总裁更衣室地位

仰卧撑FTUer
2026-05-14 08:28:47
45岁阿娇现身活动,胯粗屁股大身高是硬伤,五官精致立体像18岁

45岁阿娇现身活动,胯粗屁股大身高是硬伤,五官精致立体像18岁

往史过眼云烟
2026-05-11 19:27:04
片仔癀依旧困在“片仔癀”

片仔癀依旧困在“片仔癀”

中国基金报
2026-05-13 23:18:24
王励勤出手了!国乒3大新星获重用,世界第1组合落选,双打大变脸

王励勤出手了!国乒3大新星获重用,世界第1组合落选,双打大变脸

阿晞体育
2026-05-13 21:24:15
上海警方通告:5月13日至5月19日,部分路段交通临时管制

上海警方通告:5月13日至5月19日,部分路段交通临时管制

上观新闻
2026-05-13 19:31:05
终于说实话了!湖人被横扫后,东契奇亲口确认:从未达到复出标准

终于说实话了!湖人被横扫后,东契奇亲口确认:从未达到复出标准

夜白侃球
2026-05-13 10:32:32
戾气为何这么重?因为问题无人去解决

戾气为何这么重?因为问题无人去解决

柴差说
2026-05-12 19:11:42
大牌摆烂外援不服管教!京沪战拿什么打白边?名记怒批,京迷不满

大牌摆烂外援不服管教!京沪战拿什么打白边?名记怒批,京迷不满

后仰大风车
2026-05-13 09:50:14
夜景中的美女,身材真好

夜景中的美女,身材真好

蓝色海洋009
2026-05-13 17:06:46
2026-05-14 09:19:00
腾讯技术工程
腾讯技术工程
不止于技术
1393文章数 601关注度
往期回顾 全部

科技要闻

马斯克:只有我和黄仁勋坐上了"空军一号"

头条要闻

专机落地特朗普又舞起熟悉手势 乘专车前往酒店

头条要闻

专机落地特朗普又舞起熟悉手势 乘专车前往酒店

体育要闻

14年半,74万,何冰娇没选那条更安稳的路

娱乐要闻

白鹿掉20万粉,网友为李晨鸣不平

财经要闻

片仔癀依旧困在“片仔癀”

汽车要闻

C级纯电轿跑 吉利银河"TT"申报图来了

态度原创

教育
本地
房产
手机
艺术

教育要闻

今年中考改革力度大,多省份普高扩招,科目缩减,河南有哪些变化

本地新闻

用苏绣的方式,打开江西婺源

房产要闻

卷疯了!最低杀到7字头!手握30万,海口楼市横着走!

手机要闻

都是Ultra,下一代不一定更新,小米、vivo、OPPO

艺术要闻

这才是真正的“史上最强毕业证”,书法堪比字帖!

无障碍浏览 进入关怀版