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的流程是这样的:从 develop 拉 feature 分支,开发完合并回 develop。准备发布时,从 develop 拉 release 分支,测试没问题后合并到 master 和 develop。线上出问题,从 master 拉 hotfix 分支,修完合并回 master 和 develop。
我在项目中用过Git Flow,说实话,它适合有固定发布周期的项目。但如果你团队小、迭代快,这套流程就显得有点重了。
7.4.2 GitHub Flow
GitHub Flow就简单多了。它只有两个核心概念:master分支和feature分支。所有开发都在feature分支上做,完成后提Pull Request,经过Code Review后合并到master。
流程是这样的:
- 从master拉一个feature分支
- 在feature分支上开发、提交
- 推送到远程仓库,提Pull Request
- 团队成员Review代码,讨论修改
- 合并到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