2. 版本控制基础:Git核心概念与工作流

聊到持续集成,第一个绕不开的就是版本控制。说白了,没有版本控制,你连「集成」的资格都没有。我刚开始带团队的时候,见过太多人用「最终版v3_改_不改就不是人.zip」这种命名方式——嗯,那场面,简直灾难。

今天我们就来把 Git 的核心概念、工作流和平台操作捋一遍。我会结合自己踩过的坑来讲,希望能帮你少走弯路。

2.1 Git 核心概念:仓库、提交、分支、合并

先说说这四个最基础的东西。你只要搞懂了它们,Git 就算入门了。

仓库(Repository)

仓库就是你的项目文件夹,只不过被 Git 管起来了。我习惯把仓库想象成一个「时光机」——你可以随时回到任何一个历史节点。

创建仓库很简单:

# 初始化一个新仓库
git init

# 克隆一个远程仓库
git clone https://github.com/your/project.git
我的习惯:每个项目只建一个仓库,别搞什么「前端一个仓库、后端一个仓库」的微服务式仓库管理。除非团队真的很大,否则只会增加管理成本。

提交(Commit)

提交就是给当前代码拍一张快照。每次提交都有一个唯一的 SHA-1 哈希值,像身份证一样。

我记得刚学 Git 时,总觉得提交越少越好,恨不得一天只提交一次。后来被坑惨了——有一次改了一整天代码,最后发现某个中间步骤才是对的,但因为没有单独提交,只能全部回滚重来。

所以我的建议是:小步提交,频繁提交。每次提交只做一件事,注释写清楚。

# 添加文件到暂存区
git add index.html

# 提交并写注释
git commit -m "fix: 修复导航栏在移动端的点击区域问题"
我曾经踩过的坑:提交注释写「修改了一些bug」——结果一周后回头看,完全想不起来改了啥。现在我的提交注释都遵循 Conventional Commits 规范,比如 feat:、fix:、chore: 开头,一目了然。

分支(Branch)

分支就是平行宇宙。你在主宇宙(master/main)之外开辟一个新宇宙,随便折腾,不影响主宇宙。

为什么需要分支?你想想看,如果所有人都在 main 分支上改代码,那简直是一场噩梦。你改你的,我改我的,最后合并时冲突能让你怀疑人生。

# 创建并切换到新分支
git checkout -b feature/login-page

# 查看所有分支
git branch -a

合并(Merge)

合并就是把两个分支的修改拼在一起。Git 会自动尝试合并,如果改的是不同文件,基本没问题。但如果两个人改了同一个文件的同一行——恭喜你,冲突来了。

解决冲突其实没那么可怕。打开冲突文件,你会看到类似这样的标记:

<<<<<<< HEAD
这是当前分支的代码
=======
这是要合并进来的代码
>>>>>>> feature/login

手动选择保留哪一部分,删掉标记,然后提交即可。

核心要点:分支是廉价的,随便建;提交是频繁的,随便提;合并是日常的,别怕冲突。

2.2 Git 工作流:GitFlow 与 Trunk-Based

工作流就是团队约定好的分支使用规则。没有规则,分支就会变成一锅粥。我见过两种主流的工作流,分别适合不同的场景。

GitFlow

GitFlow 是 2010 年左右火起来的,结构比较重。它定义了五种分支:

分支类型 用途 命名示例
main 生产环境代码,只合并不直接提交 main
develop 开发主分支,日常集成点 develop
feature 开发新功能 feature/user-profile
release 发布前准备,修小bug release/1.2.0
hotfix 紧急修复生产问题 hotfix/critical-login-bug

GitFlow 的流程大概是:从 develop 拉 feature 分支 → 开发完合并回 develop → 从 develop 拉 release 分支 → 测试通过后合并到 main 和 develop → 生产出问题时从 main 拉 hotfix。

说实话,我个人觉得 GitFlow 有点重。以前在一个 20 人的团队用过,光是分支切换就够让人头疼的。而且 release 分支的存在,其实变相鼓励了「攒一堆功能再发布」——这跟持续集成的理念是相悖的。

我的建议:如果你的团队超过 10 人,或者产品有固定的发布周期(比如每月一版),GitFlow 可以考虑。否则,别给自己找麻烦。

Trunk-Based Development(主干开发)

Trunk-Based 就简单多了——所有人都在 main 分支上开发,或者从 main 拉出非常短命的分支(通常不超过一天)。

核心原则就两条:

  • 分支存活时间不超过 24 小时
  • 每天至少合并一次到 main

为什么这样好?你想想看,如果每个人都在自己的分支上开发两周,最后合并时那个冲突量——我经历过一次,整整花了两天解决冲突,还引入了新的 bug。

Trunk-Based 配合特性开关(Feature Toggle)使用效果更佳。不完整的功能通过开关隐藏,代码照样合并到 main,但用户看不到。

我的选择:现在带的团队,只要不是做嵌入式或硬件相关的,我都推荐 Trunk-Based。它天然适合持续集成,也适合 DevOps 文化。

2.3 代码托管平台:GitHub / GitLab 基础操作

有了 Git 还不够,你还需要一个远程仓库来托管代码。目前主流的就是 GitHub 和 GitLab。我两个都用过,说说我的感受。

GitHub

GitHub 是社区之王。如果你做开源项目,GitHub 是首选。它的 Pull Request 流程非常成熟,Code Review 体验也很好。

基础操作其实就几个:

  • Fork:复制别人的仓库到你的账号下,适合开源贡献
  • Pull Request:请求对方合并你的修改,是协作的核心
  • Issues:提 bug 或功能需求,可以关联 PR
  • Actions:GitHub 自带的 CI/CD,后面章节会详细讲

GitLab

GitLab 更适合企业私有部署。它的 CI/CD 是原生的,不需要额外配置。我记得有一次帮客户搭 CI,GitLab 自带的 Runner 直接就能用,省了不少事。

GitLab 的 Merge Request 和 GitHub 的 Pull Request 本质一样,只是叫法不同。但 GitLab 的权限管理更细粒度,适合企业环境。

功能 GitHub GitLab
开源社区 最强 一般
私有仓库 免费(有限制) 免费(无限制)
CI/CD Actions(需配置) 内置(开箱即用)
自托管 不支持 支持(GitLab CE)
Code Review PR 体验好 MR 功能丰富
我的建议:个人项目或开源项目用 GitHub;企业内网部署用 GitLab。别纠结,两个都学一下,反正操作逻辑差不多。

2.4 小结

这一章我们聊了 Git 的四个核心概念——仓库、提交、分支、合并。也对比了 GitFlow 和 Trunk-Based 两种工作流。最后简单介绍了 GitHub 和 GitLab 的基础操作。

嗯,版本控制是持续集成的基石。下一章我们会正式进入 CI 的世界,讲讲 Jenkins 和 GitLab CI 的配置。到时候你会发现,今天学的这些 Git 知识,全都会用上。