一、惨案现场:三个"最终版"
周一早上,大刘在群里发了一条消息:
"@技术部 库存模块我改好了,放在共享盘:库存系统-最终版.py"
五分钟后,小雯回复:
"等一下,我早上也改了一版,放的是:库存系统-最终版2.py"
又过了半小时,阿杰说:
"……你们谁把最终版2 又改了一遍?现在盘里还有'库存系统-最终版真的不改了.py'。到底哪个是最新的?"
小陈打开共享盘,看到了这样一幕:
共享盘/代码/
├── 库存系统-最终版.py
├── 库存系统-最终版2.py
├── 库存系统-最终版真的不改了.py
├── 库存系统-最新-别动.py
└── 库存系统-改坏了别怪我.py
"师傅,这……这怎么搞?"小陈快哭了,"五个人改了五个版本,谁都不知道哪个是对的。"
老周站在他身后,很平静:"这就是人类在没有工具时,面对'多人同时改同一份代码'这个问题,交出的答卷——用文件名表达绝望。版本控制的诞生,就是为了消灭这场惨案。"
二、什么是版本控制:给代码装"时光机 + 并行车道"
老周在白板上画:
没有版本控制:
你改 → 存成"最终版2" → 我改 → 存成"最终版3" → 谁也说不清哪个新
有版本控制(Git):
┌── 你建一条分支(车道),在上面随便改
│
主分支(主干) ←── 改好了,合并回来(merge)
│
└── 我建另一条分支,我改我的,互不干扰
"版本控制系统(VCS)做两件事:"老周竖起两根手指。
- 记录历史(时光机):每一次改动都有记录——谁、什么时候、改了什么。想回到三天前的版本?一键回去。再也不需要"最终版3"这种文件名了。
- 并行开发(车道):每个人在自己的"分支(branch)"上干活,互不覆盖;干完了,再合并(merge)回主干。
"现在全世界用得最多的版本控制工具,叫 Git。它是软件协作的第一块地基——没有 Git 的团队,就像没有仓库的图书馆,书只能堆在地上。"
小陈:"那咱们赶紧上 Git!"
"别急。工具只是第一步,真正的管理功夫在'怎么用'。 我们一条条来。"
三、Git 的核心动作:一次"提交"的解剖
老周先教了最核心的动作——提交(commit):
# 第一次使用前:告诉 Git 你是谁(每次提交都会记录)
git config --global user.name "陈小陈"
git config --global user.email "chen@yunjian.com"
# 日常流程
git status # 看看现在改了什么
git add 结算页.py # 把文件放进"暂存区"(准备提交)
git commit -m "优化结算页:图片懒加载,首屏提速" # 提交:记下一个快照
git push # 把本地提交推到共享服务器(别人就能看到了)
"git commit 是灵魂。它就像给你的代码拍一张照片,并且写上'为什么这么改'。好的提交信息,是给未来同事(包括三个月后的自己)看的情书。"
老周给团队定下提交规范:
云间书店 · 提交信息规范
格式:<类型>: <做了什么,一句话说清>
feat: 新功能 feat: 满减活动后台配置
fix: 修 bug fix: 结算页弱网超时问题
refactor: 重构不改行为 refactor: 拆分库存计算函数
docs: 文档 docs: 更新部署手册
test: 测试 test: 补充满减边界用例
chore: 杂项 chore: 升级依赖库版本
"为什么规范?因为六个星期后回看历史,你要能一眼看懂'这个提交在干嘛'。提交信息乱,历史就是一团乱麻;提交信息清楚,历史就是一本团队日记。"
四、分支策略:怎么让六个人同时干活不撞车
"有了提交,还要有分支策略。"老周说,"六个人不可能都直接在主干上改——那就又回到互相覆盖了。我们要定一套'怎么分叉、怎么合并'的规矩。"
老周推荐了最经典的 Git Flow 简化版(适合云间书店这种小团队):
main(主干) ← 永远是可以上线的稳定版本
│
├── develop(开发线) ← 日常开发都往这合
│ │
│ ├── feature/满减活动 ← 小陈:做功能的分支
│ ├── feature/报表改版 ← 小雯:做功能的分支
│ └── hotfix/支付崩溃 ← 紧急修复(直接从 main 拉,改完立刻合回)
规则:
云间书店 · 分支规则
1. main 永远是稳定可发布的,谁都不能直接往 main 上改
2. 新功能从 develop 拉一条 feature/xxx 分支
3. feature 分支做完 → 代码评审通过 → 合并回 develop
4. develop 验证稳定 → 合并到 main → 上线
5. 线上紧急 bug → 从 main 拉 hotfix 分支,修完合并回 main 和 develop
"这就是分工不分家:六个人各在自己的 feature 分支上干活,谁也不踩谁;合并有节奏,不会乱。"
五、合并与冲突:两个人都改了同一行
小陈很快遇到了 Git 生涯的第一个坎——合并冲突(merge conflict)。
他和小雯都改了 pricing.py 的第 20 行,他先合并了,小雯再合并时,Git 报警:
CONFLICT (content): Merge conflict in pricing.py
<<<<<<< HEAD
discount = 0.88 # 小雯改的
=======
discount = 0.9 # 小陈改的
>>>>>>> feature/会员折扣
"冲突不可怕,可怕的是害怕冲突。"老周说,"冲突的本质是:两个人对同一处代码有不同想法,需要人类来决定谁对——Git 只是把这个'需要沟通'的地方标记出来而已。"
"处理冲突三步走:"
1. 找到冲突标记(<<<<<<< ======= >>>>>>>)
2. 看看两边的代码,判断哪个对(或者两个都不对,需要第三种写法)
3. 删掉标记,保留正确的代码,提交
关键:拿不准时,把写这两行代码的同事拉过来一起看,别自己拍板。
"记住:冲突不是'有人搞砸了',是'两个人碰巧动了同一处',这是并行开发的正常代价。 规范的分支策略 + 频繁合并(小步合并,冲突就小),能把代价压到最低。"
六、代码评审:版本控制之上的"第二道闸门"
"版本控制解决了'代码怎么存',但没解决'代码好不好'。"老周说,"所以我们还有一道闸门——代码评审(Code Review)。所有 feature 分支合并回 develop 之前,必须至少一个同事看一遍。"
代码评审清单(云间书店版):
□ 逻辑对不对(有没有 bug、边界情况)
□ 命名清不清楚(变量名、函数名读得懂吗)
□ 有没有重复代码(该抽出来的抽出来了吗)
□ 有没有明显的性能/安全问题
□ 有没有配套测试
"评审不是'挑刺大会',是四只眼睛比两只眼睛看得全。你写的代码自己看不出问题,同事一眼就能看出来——因为他的脑子和你的脑子不是同一台机器。"
七、章末:老周的第二层总结
第二层:版本控制(协作地基)
├── Git 核心 → commit(快照+原因)、push/pull、分支
├── 提交规范 → feat/fix/refactor... 让历史可读
├── 分支策略 → main 稳定 + develop 开发 + feature/xxx 并行
├── 合并与冲突 → 冲突是正常代价,小步合并最省事
└── 代码评审 → 合并前必须过"四只眼"
"小陈,版本控制是软件工程的地基——它把'六个人改一堆文件'变成了'六个人各改各的,最后有序合并'。有了它,团队的代码才开始'长在一起'。"
"但是——"老周话锋一转,"代码是存好了,合进去了。可你有没有想过一个问题:我们合进去的代码,真的能跑吗? 每次上线前,都是大刘手动打包、手动部署,出了一堆幺蛾子……"
"师傅,我听说这叫'构建和集成'?"
"对。而且更重要的在后面:测过了吗? 下一章,我们从'代码合到一起'讲到'怎么保证合出来的东西是对的'——代码质量与测试。那是我们技术部要踩的另一个大坑。"