第二章:版本控制与Git工作流

版本控制这件事,说白了就是给代码拍照片。每拍一张,你就能回到那个瞬间。我见过太多团队还在用「代码_v3_最终版.zip」这种命名方式,嗯,那画面太美我不敢看。

今天咱们聊聊Git的核心操作、分支策略,还有那些年我们踩过的坑。

2.1 Git核心操作:你每天都在用的那些命令

Git的基本操作其实不多。我习惯把它们分成三类:本地操作、同步操作、还有后悔药操作。

本地操作三板斧

git add .          # 把改动放进暂存区
git commit -m "feat: 添加用户登录功能"  # 拍一张快照
git status         # 看看现在什么状态

这里有个小细节。很多人喜欢用 git add . 一股脑全加上去。我在项目中遇到过好几次,不小心把配置文件、日志文件都加进去了。后来我养成了一个习惯:先用 git status 看看改了啥,再用 git add 一个个加。

我的习惯:git add -p 交互式添加。它会让你选择每个改动的区块,要不要加进去。这样能避免把调试代码也提交了。

同步操作:别让队友等你

git pull           # 拉取最新代码
git push           # 推送你的改动
git fetch          # 只拉取,不合并

你想想看,git pull 其实是 git fetch + git merge 的组合拳。我建议团队新人多用 git fetch 看看远程有啥变化,再决定怎么合并。直接 git pull 有时候会搞出奇怪的合并冲突。

后悔药:Git 的时光机

git reset HEAD~1   # 撤销最近一次提交
git revert HEAD    # 用新提交来撤销旧提交
git stash          # 临时藏起你的改动
注意: 已经推送到远程的分支,千万别用 git reset。我曾经手滑 reset 了一个公共分支,结果整个团队都在骂我。用 git revert 才是正道。

2.2 分支策略:选对路子,事半功倍

分支策略这东西,没有银弹。我待过几个团队,用过不同的策略,各有各的坑。

GitFlow:经典但有点重

GitFlow 把分支分成了五类:

分支类型 用途 生命周期
master 生产环境代码 永久
develop 开发主分支 永久
feature/* 新功能开发 短期
release/* 发布准备 短期
hotfix/* 紧急修复 短期

说实话,GitFlow 适合那种有固定发布周期的项目。比如一个月发一次版,有专门的测试阶段。我在一个金融项目里用过,效果不错。但如果是互联网项目,每天发好几次,GitFlow 就有点太重了。

Trunk-Based:简单粗暴

Trunk-Based 的核心思想就一句话:所有人都在主干上开发,分支活不过一天。

# 主干开发流程
git checkout main
git pull
# 写代码...
git commit -m "fix: 修复支付超时问题"
git push

为什么会有人喜欢这个?因为简单。没有花里胡哨的分支,没有合并地狱。我现在的团队就用这个模式,配合特性开关(Feature Toggle),每天能发布十几次。

关键区别: GitFlow 适合「计划性发布」,Trunk-Based 适合「持续交付」。选哪个,看你的发布频率。

2.3 代码评审:不只是找bug

代码评审这件事,我刚开始觉得是浪费时间。直到有一次,我写的支付逻辑有个边界条件没处理,被同事在评审时发现了。嗯,那次差点造成线上事故。

评审清单

  • 功能正确性: 代码真的解决了问题吗?
  • 代码风格: 符合团队的规范吗?
  • 测试覆盖: 有没有对应的单元测试?
  • 性能影响: 会不会拖慢系统?
  • 安全性: 有没有SQL注入、XSS等风险?

我的评审习惯

我个人习惯把评审分成两轮。第一轮只看逻辑,不看细节。第二轮再看代码风格和命名。为什么?因为人的注意力是有限的,一次看太多东西,反而容易漏掉关键问题。

小技巧: 评审时用「提问」代替「指责」。比如「这里为什么要用双重循环?」比「你写的代码效率太低了」要好得多。代码评审是帮队友,不是找茬。

2.4 避坑指南:那些年我踩过的坑

最后分享几个我亲身经历过的坑,希望能帮你少走弯路。

坑一:大文件提交

我曾经不小心把一个 500MB 的日志文件提交到了 Git 仓库。结果每次 clone 都要等半天。后来用 git filter-branch 才清理掉。现在我会在项目根目录放一个 .gitignore,把日志、编译产物、IDE配置都排除掉。

坑二:合并冲突处理不当

有一次两个同事同时改了同一个文件的不同位置,合并时产生了冲突。结果有人直接删掉了对方的代码。嗯,那天的发布回滚了三次。我的建议是:遇到冲突别慌,用 git mergetool 可视化解决,或者找当事人一起看。

坑三:分支命名混乱

团队刚开始没有统一的分支命名规范,结果出现了 fix-bugbug-fixfixbug 这种分支。后来我们统一用 类型/描述 的格式,比如 feat/user-loginfix/payment-timeout。清爽多了。

小结

版本控制和 Git 工作流,说白了就是让团队协作更顺畅。选什么策略不重要,重要的是大家能达成共识,并且严格执行。我个人建议小团队从 Trunk-Based 开始,等团队大了再考虑 GitFlow。

下一章咱们聊聊持续集成,到时候我会分享一个让我印象深刻的 CI 事故。嗯,那故事可精彩了。