2、版本控制与Git工作流:Git安装与配置、分支策略(Git Flow/GitHub Flow)、代码合并与冲突解决

2.1 Git安装与基础配置

说实话,我见过太多PHP项目因为版本控制混乱导致线上事故了。有一次,一个同事直接在服务器上改代码,改完忘了备份,结果回滚花了整整一个通宵。从那以后,我要求团队所有人必须用Git,而且得按规范来。

先说说安装。这步其实很简单,但不同系统有点区别:

  • Linux(Ubuntu/Debian)sudo apt-get install git
  • macOSbrew install git 或者直接装Xcode Command Line Tools
  • Windows:去官网下载安装包,一路Next就行。记得勾选「Git Bash」选项

装完之后,第一件事就是配身份信息。我个人习惯这样配:

git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"
git config --global core.autocrlf input  # macOS/Linux
git config --global core.autocrlf true   # Windows
小提示:core.autocrlf 这个配置很关键。Windows和Linux的换行符不一样,不配好的话,你拉下来的代码全是红色警告。我在跨平台协作的项目里吃过这个亏。

还有几个我常用的配置:

git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.st status
git config --global color.ui true

嗯,别名配置能省不少事。你想想看,每天敲几十次 git status,改成 git st 多舒服。

2.2 分支策略:Git Flow vs GitHub Flow

分支策略这东西,说白了就是团队怎么协作的约定。没有规矩不成方圆,尤其是多人开发的时候。

2.2.1 Git Flow

Git Flow是我最早接触的分支模型。它把分支分成了几类:

分支类型 命名规则 用途
master master 生产环境代码,只合并不直接提交
develop develop 日常开发的主分支
feature feature/xxx 新功能开发,从develop分出
release release/x.x.x 发布前的准备分支
hotfix hotfix/xxx 紧急修复,从master分出

我在一个金融项目里用过Git Flow。当时团队20多人,功能模块多,版本迭代快。Git Flow确实能管住,但说实话,有点重。每次发布要走feature → develop → release → master,流程长了点。

核心流程:
  1. 从develop创建feature分支开发新功能
  2. 开发完合并回develop
  3. 准备发布时,从develop创建release分支
  4. release分支测试通过后,合并到master并打tag
  5. 同时合并回develop

2.2.2 GitHub Flow

后来我接触了GitHub Flow,一下子就喜欢上了。它简单得多:

  • 只有一个长期分支:master(或者main)
  • 所有开发都在feature分支上
  • 通过Pull Request来合并代码
  • 合并后立即部署

你想想看,对于中小型团队或者持续部署的项目,GitHub Flow简直太合适了。我现在的团队就用这个,配合CI/CD,一天能发布十几次。

注意:GitHub Flow要求master分支始终保持可部署状态。如果你们的测试覆盖率不够,或者代码审查不严格,建议还是用Git Flow稳一点。

2.3 代码合并与冲突解决

合并代码,这是每个开发者都躲不过的事。我见过最惨的一次,两个同事同时改了同一个文件的同一行,合并的时候吵了一架。其实冲突没那么可怕,关键是要有方法。

2.3.1 合并方式

Git提供了两种合并方式:

# 普通合并
git merge feature/login

# 变基合并
git rebase master

我个人习惯:公共分支用merge,个人分支用rebase。为什么?

  • merge:保留完整的提交历史,适合多人协作的公共分支
  • rebase:让提交历史更线性,适合个人开发分支
避坑指南:我曾经在公共分支上用了rebase,结果把别人的提交搞丢了。记住一条铁律:不要对已经推送到远程的分支执行rebase

2.3.2 冲突解决实战

冲突长什么样?看这个例子:

<<<<<<< HEAD
echo "这是当前分支的内容";
=======
echo "这是要合并进来的内容";
>>>>>>> feature/login

解决步骤其实就三步:

  1. 找到冲突文件,打开看看
  2. 手动选择保留哪部分,或者重新写
  3. 删掉 <<<<<<<=======>>>>>>> 这些标记

嗯,这里要注意。别急着用可视化工具,先理解冲突的原因。我遇到过有人直接全选「接受当前」,结果把别人的代码全覆盖了。

推荐几个好用的工具:

  • VS Code:自带冲突解决界面,点一下就行
  • Beyond Compare:老牌工具,对比清晰
  • Meld:开源免费,Linux上很好用

2.3.3 避免冲突的技巧

说实话,冲突是不可避免的,但可以减少。我总结了几个经验:

  • 小步提交:每次提交只改一个功能点,别攒一堆
  • 及时同步:每天上班先 git pull --rebase
  • 模块化开发:尽量别让两个人同时改同一个文件
  • 代码审查:Pull Request一定要有人review
我的日常流程:
# 开始新功能
git checkout -b feature/payment

# 开发中... 提交代码
git add .
git commit -m "feat: 添加支付接口"

# 同步主分支
git fetch origin
git rebase origin/master

# 推送到远程
git push origin feature/payment

# 创建Pull Request,等review通过后合并

最后说一句,版本控制不只是工具,更是团队协作的契约。选对分支策略,学会解决冲突,你的项目才能跑得稳。我在面试PHP工程师时,一定会问Git相关的问题。因为一个连版本控制都搞不好的团队,代码质量可想而知。