7、Git分支管理(二):分支冲突的产生与解决、git mergetool的使用、分支策略(Git Flow、GitHub Flow)

好,咱们接着聊分支管理。上一章我们把分支的创建、切换、合并这些基本功过了一遍。这一章要聊的,是真正让很多团队头疼的问题——冲突。说白了,冲突就是Git不知道你到底想留哪段代码,它懵了,得你来拍板。

7.1 冲突是怎么产生的?

冲突不是Bug,它只是Git的一种保护机制。我刚开始用Git那会儿,一看到冲突提示就慌,觉得是不是代码写崩了。后来才明白,冲突其实是Git在说:“我尽力了,但这里有两个不同的修改,你自己决定吧。”

冲突产生的条件其实很简单:两个分支修改了同一个文件的同一块区域。比如你改了第10行,我也改了第10行,Git就不知道听谁的。

核心原则:冲突只发生在合并时,且只针对同一文件的同一位置。

举个例子。假设你有一个 index.html,主分支上第5行是 <title>我的网站</title>。你在feature分支上改成了 <title>新版网站</title>,而同事在另一个分支上改成了 <title>官网</title>。合并时,Git就不知道选哪个——冲突来了。

7.2 冲突的解决流程

遇到冲突别慌,按步骤来就行。我个人习惯是三步走:识别 → 分析 → 解决

7.2.1 识别冲突

当你执行 git merge 时,Git会告诉你哪些文件有冲突。比如:

Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.

这时候用 git status 查看,冲突文件会标成 both modified

7.2.2 分析冲突内容

打开冲突文件,你会看到类似这样的标记:

<<<<<<< HEAD
<title>我的网站</title>
=======
<title>新版网站</title>
>>>>>>> feature-branch

这里 <<<<<<< HEAD======= 之间是当前分支的内容,=======>>>>>>> feature-branch 是你要合并进来的内容。

小技巧:我习惯用 git diff 先看冲突概览,再打开具体文件。这样心里有个底。

7.2.3 手动解决冲突

你需要手动编辑文件,把冲突标记删掉,保留你想要的内容。比如:

<title>新版网站</title>

然后保存文件,执行:

git add index.html
git commit -m "解决index.html冲突,保留新版标题"

嗯,这里要注意:解决冲突后一定要手动commit,Git不会自动帮你提交。

避坑指南:我曾经犯过一个低级错误——解决冲突时只删了冲突标记,但忘了检查上下文。结果合并后页面样式全乱了。所以解决完冲突,最好跑一遍测试。

7.3 使用 git mergetool

如果你觉得手动编辑冲突文件太麻烦,可以用 git mergetool。它会调用一个可视化工具来帮你解决冲突。

配置方法很简单:

git config --global merge.tool vimdiff
# 或者用你喜欢的工具,比如 meld、kdiff3、Beyond Compare

然后遇到冲突时,直接运行:

git mergetool

它会打开一个三栏界面:左边是当前分支,右边是合并进来的分支,中间是合并结果。你可以逐块选择保留哪边的代码。

我个人比较喜欢用 meld,界面直观,操作也顺手。不过工具这东西,看个人习惯。你想想看,用工具解决冲突就像用计算器做算术——省力,但前提是你得知道正确答案是什么。

提示:如果你用VS Code,它自带的合并编辑器其实也很好用。直接在冲突文件上点“接受当前更改”或“接受传入更改”就行。

7.4 分支策略:Git Flow vs GitHub Flow

聊完冲突,咱们说说怎么从源头上减少冲突。这就涉及到分支策略了。说白了,分支策略就是团队约定的一套“怎么用分支”的规则。

7.4.1 Git Flow

Git Flow是2010年提出的一套经典模型。它定义了五种分支:

分支类型 用途 命名示例
master 生产环境代码,只合并不直接修改 master
develop 日常开发主分支 develop
feature 新功能开发 feature/login
release 发布前准备 release/1.2.0
hotfix 紧急修复生产问题 hotfix/crash-fix

Git Flow的流程是这样的:从 developfeature 分支,开发完合并回 develop。准备发布时,从 developrelease 分支,测试没问题后合并到 masterdevelop。线上出问题,从 masterhotfix 分支,修完合并回 masterdevelop

我在项目中用过Git Flow,说实话,它适合有固定发布周期的项目。但如果你团队小、迭代快,这套流程就显得有点重了。

Git Flow 分支模型 master develop feature/login release/1.2.0 hotfix/crash master develop feature release hotfix

7.4.2 GitHub Flow

GitHub Flow就简单多了。它只有两个核心概念:master分支feature分支。所有开发都在feature分支上做,完成后提Pull Request,经过Code Review后合并到master。

流程是这样的:

  1. 从master拉一个feature分支
  2. 在feature分支上开发、提交
  3. 推送到远程仓库,提Pull Request
  4. 团队成员Review代码,讨论修改
  5. 合并到master,立即部署

GitHub Flow的核心思想是:master永远是可部署的。每次合并到master,都意味着可以上线。

我的经验:GitHub Flow更适合持续部署的团队。我之前带的一个创业团队就用这个模型,每天合并十几次,上线频率很高。但前提是测试要跟上,不然master分分钟变“灾难现场”。

7.4.3 怎么选?

你可能会问:到底用哪个?我的建议是:

  • 传统企业、固定版本周期 → Git Flow。它结构清晰,适合多人协作的大项目。
  • 互联网创业、快速迭代 → GitHub Flow。它轻量灵活,适合小团队。
  • 如果你拿不准 → 先从GitHub Flow开始。简单,容易上手。等团队大了再考虑升级。

避坑指南:我曾经在一个项目里硬套Git Flow,结果团队只有三个人,光维护分支就累得够呛。后来换成GitHub Flow,效率反而上来了。所以工具是为人服务的,别为了用而用。

7.5 减少冲突的实战技巧

最后分享几个我这些年总结的减少冲突的技巧:

  • 频繁合并:别等到功能全写完才合并。每天至少合并一次master到你的feature分支。
  • 小粒度提交:一个提交只改一个逻辑。这样冲突范围小,容易解决。
  • 沟通先行:如果要改公共模块,先在群里说一声。避免两个人同时改同一块代码。
  • 代码风格统一:格式化工具(如Prettier)能减少大量无意义的格式冲突。

嗯,这一章的内容就到这儿。冲突不可怕,可怕的是不知道怎么解决。多练几次,你就能像我一样,看到冲突提示时淡定地说一句:“哦,又来了,小事。”


公众号:蓝海资料掘金营,微信deep3321