编程进阶网 编程进阶网
首页
  • 在线工具
  • JSON工具
  • 文本工具
  • 图片处理
  • 文档转化
  • 代码压缩
  • 加解密
  • 时间日期
  • 网络工具
  • 颜色设计
  • 二维码
  • 开发实用
  • 计算机组成原理
  • 操作系统原理
  • 网络协议原理
  • 数据库系统原理
  • 序卷导读
  • 数据本质
  • 运行模型
  • 并发设计
  • 内存真相
  • 交互系统
  • 面向对象
  • 设计原则
  • 设计模式
  • 系统架构
  • 体系建设
  • 代码品质
  • 方案设计
  • 稳定可靠
  • 工程运维
  • 性能优化
  • 数据结构导论
  • 线性结构详解
  • 树哈希结构论
  • 容器设计实战
  • 经典算法思想
  • 工程案例剖析
  • 算法题库精练
  • C语言入门
  • C综合案例
  • C专栏博客
  • C标准集库
  • C++入门教程
  • C++综合案例
  • C++专栏博客
  • C++编程技巧
  • Java入门教程
  • Java综合案例
  • Java专栏博客
  • Go入门教程
  • Go综合案例
  • Go专栏博客
  • Go开发技巧
  • JavaScript入门
  • JavaScript案例
  • JavaScript高级
  • Android库解读
  • Android专栏
  • iOS ObjC入门
  • iOS Swift入门
  • iOS入门精通
  • Web之Html手册
  • Web之TypeScript
  • Web之Vue高级进阶
  • Linux之QML入门
  • Linux之QT核心库
  • Python教程
  • Shell&Bash教程
  • 工具脚本
  • 自动化脚本
  • 质量保障
  • 产品思考
  • 软实力
  • 开发流程
  • Git应用
  • 技术模版
  • 技术规范
  • Markdown
  • Mermaid
  • 开源协议
  • 毛选解读
  • 自我精进
  • 关于我
  • 自我精进
  • 职场管理
  • 职场面试
  • 心情杂货
  • 友情链接

杨充

专注编程 · 终身学习者
首页
  • 在线工具
  • JSON工具
  • 文本工具
  • 图片处理
  • 文档转化
  • 代码压缩
  • 加解密
  • 时间日期
  • 网络工具
  • 颜色设计
  • 二维码
  • 开发实用
  • 计算机组成原理
  • 操作系统原理
  • 网络协议原理
  • 数据库系统原理
  • 序卷导读
  • 数据本质
  • 运行模型
  • 并发设计
  • 内存真相
  • 交互系统
  • 面向对象
  • 设计原则
  • 设计模式
  • 系统架构
  • 体系建设
  • 代码品质
  • 方案设计
  • 稳定可靠
  • 工程运维
  • 性能优化
  • 数据结构导论
  • 线性结构详解
  • 树哈希结构论
  • 容器设计实战
  • 经典算法思想
  • 工程案例剖析
  • 算法题库精练
  • C语言入门
  • C综合案例
  • C专栏博客
  • C标准集库
  • C++入门教程
  • C++综合案例
  • C++专栏博客
  • C++编程技巧
  • Java入门教程
  • Java综合案例
  • Java专栏博客
  • Go入门教程
  • Go综合案例
  • Go专栏博客
  • Go开发技巧
  • JavaScript入门
  • JavaScript案例
  • JavaScript高级
  • Android库解读
  • Android专栏
  • iOS ObjC入门
  • iOS Swift入门
  • iOS入门精通
  • Web之Html手册
  • Web之TypeScript
  • Web之Vue高级进阶
  • Linux之QML入门
  • Linux之QT核心库
  • Python教程
  • Shell&Bash教程
  • 工具脚本
  • 自动化脚本
  • 质量保障
  • 产品思考
  • 软实力
  • 开发流程
  • Git应用
  • 技术模版
  • 技术规范
  • Markdown
  • Mermaid
  • 开源协议
  • 毛选解读
  • 自我精进
  • 关于我
  • 自我精进
  • 职场管理
  • 职场面试
  • 心情杂货
  • 友情链接
  • README
  • 业务思考

  • 产品思考

  • 软实力

  • 开发流程

  • Git应用

    • README
    • 版本控制的诞生:从一场灾难说起
    • 单人工作流:在 Git 的时光机里自由穿梭
    • 分支:Git 的灵魂——像开平行宇宙一样开发
    • 远程协作:把你的代码推到全世界
    • Git特种作战:stash、cherry-pick、bisect三件套
    • 团队工作流实战:从一个人能打到一队人能战
      • 一、团队失控
      • 二、Git Flow
        • 2.1 五种分支,各司其职
        • 2.2 完整的 Git Flow 模拟
        • 2.3 Git Flow 的优势与劣势
      • 三、GitHub流
        • 3.1 只有一条长期分支 + 临时 feature 分支
        • 3.2 GitHub Flow 实战
        • 3.3 选 Git Flow 还是 GitHub Flow?
      • 四、保护分支
        • 4.1 在 GitHub 上配置
        • 4.2 配置后的效果
        • 4.3 保护分支的典型配置组合
      • 五、提交规范
        • 5.1 为什么消息格式很重要?
        • 5.2 Conventional Commits 规范
        • 5.3 Commit 规范速查
        • 5.4 用交互式 rebase 修正之前的 message
      • 六、忽略文件
        • 6.1 基本用法
        • 6.2 全局 .gitignore
        • 6.3 如果已经提交了不该提交的文件
      • 七、CI/CD 集成
        • 7.1 概念
        • 7.2 GitHub Actions 示例
      • 八、综合实战
        • 场景设定
        • 实战开始
        • 🎯 Sprint 时间线
      • 九、本章回顾
        • 📎 本章涉及的命令速查
    • Git故障排除:遇到报错不再慌的急诊手册
    • Git 场景速查地图:遇到问题对号入座
    • 常见操作实践:从理论到实战的最后一步
  • 技术模版

  • 技术规范

  • markdown

  • mermaid

  • license

  • 博客部署

  • 技术招聘

  • 八股文

  • 技术规划

  • 技术
  • Git应用
杨充
2025-06-06
目录

团队工作流实战:从一个人能打到一队人能战

# 第6章 · 团队工作流

# 一、团队失控

前五章,小李都是一个人或两三个人协作。虽然偶尔有点混乱,但靠沟通就能解决——喊一嗓子「别 push,我在改这个文件」,大家就停下来。

三个月后,公司拿到了融资,团队从 3 人扩到 15 人。噩梦开始了:

周一早上 9 点,小李打开 Slack,看到 47 条未读消息:

小王:「谁 push 了 broken code 到 master?线上挂了!」 小张:「我昨天推的,但我本地是好的啊。」 小王:「你是不是没 pull 最新代码就 push 了?」 小张:「我 pull 了啊……可能是李哥的吧?」 小李:「我改的是 coupons.js,跟支付无关。」

没人知道线上挂的原因,也没人知道谁应该修。 更糟的是:

  • 🚫 有人直接往 master 推未经审查的代码,线上两次回滚
  • 🚫 有人在同一个 feature 分支上同时做三个功能,想拆都拆不开
  • 🚫 没有发布流程——每次上线靠「感觉差不多了就推」
  • 🚫 Commit message 惨不忍睹:fix、update、改了一下、asdf

问题本质:不是团队缺 Git 技能,而是缺一套每个人都遵守的游戏规则。

这就是团队工作流要解决的问题:不是让你更会用 Git,而是让 15 个人像一个人一样协同。


# 二、Git Flow

# 2.1 五种分支,各司其职

Git Flow 是 Vincent Driessen 在 2010 年提出的,虽然现在被认为「重量级」,但它把「分支职责」这个概念讲得最透彻。

                    ┌─ feature/支付 ─┐
                   ╱                  ╲
──○──○────○──────○────────────────────○────────────○──  main
       ╲        ╱ ╲                  ╱ ╲          ╱
        ○──○──○───○──○──○────○────○───○──○──○──○──  develop
                              ╲   ╱          ╲   ╱
                          release/1.0    hotfix/紧急
分支 生命周期 来源 合并到 命名
main 永久 - - main 或 master
develop 永久 main - develop
feature 临时 develop develop feature/xxx
release 临时 develop main + develop release/v1.2.0
hotfix 临时 main main + develop hotfix/xxx

核心规则:

  • main 只存生产代码——任何时候从 main 拉出来的代码都能直接部署。
  • develop 是集成分支——所有 feature 先合到 develop,测试通过后才合到 main。
  • feature 从 develop 出,回 develop——一个 feature 一个分支,做完就删。
  • release 是发布前的最后一道关——修 bug、改版本号、打 tag,不改新功能。
  • hotfix 从 main 出,同时回合 main 和 develop——确保修复在主线和开发线都不丢失。

# 2.2 完整的 Git Flow 模拟

mkdir gitflow-lab && cd gitflow-lab && git init

# ==================== Step 1:建立主分支结构 ====================
echo "const app = 'Shop v0.0.1';" > app.js
git add . && git commit -m "init: 项目初始化"

# 从 main 分出 develop
git branch develop

# main 打初始标签
git tag v0.0.1


# ==================== Step 2:两人并行开发两个 feature ====================

# 小李:开发商品搜索
git switch develop
git switch -c feature/商品搜索

echo '
function searchProducts(keyword) {
  return db.query("SELECT * FROM products WHERE name LIKE ?", [`%${keyword}%`]);
}
' > search.js

git add . && git commit -m "feat: 商品搜索功能"

# 小张:开发购物车(从 develop 开出另一个分支)
git switch develop
git switch -c feature/购物车

echo '
const cart = [];
function addToCart(id) { cart.push(id); }
function getCartTotal() { return cart.length; }
' > cart.js

git add . && git commit -m "feat: 购物车添加功能"

echo '
function removeFromCart(id) {
  const idx = cart.indexOf(id);
  if (idx > -1) cart.splice(idx, 1);
}
' >> cart.js
git add . && git commit -m "feat: 购物车移除功能"


# ==================== Step 3:feature 合并到 develop ====================

# 小李先合并搜索功能
git switch develop
git merge --no-ff feature/商品搜索 -m "merge: 合并商品搜索功能"
git branch -d feature/商品搜索

# 小张接着合并购物车功能
git merge --no-ff feature/购物车 -m "merge: 合并购物车功能"
git branch -d feature/购物车

git log --oneline --graph
# 输出:
# *   merge: 合并购物车功能
# |\
# | * feat: 购物车移除功能
# | * feat: 购物车添加功能
# |/
# *   merge: 合并商品搜索功能
# |\
# | * feat: 商品搜索功能
# |/
# * init: 项目初始化


# ==================== Step 4:准备发布——创建 release 分支 ====================
git switch -c release/v1.0.0 develop

# 在 release 上只做发布准备:修小 bug、改版本号
echo "const APP_VERSION = '1.0.0';" >> app.js
git add . && git commit -m "chore: 更新版本号到 1.0.0"

# 发现一个 display bug——修复
echo "// 修复:移动端搜索框宽度问题" >> search.js
git add . && git commit -m "fix: 搜索框移动端适配"

# 测试通过 → 发布!

# 合并到 main
git switch main
git merge --no-ff release/v1.0.0 -m "release: v1.0.0 正式发布"

# 打发布标签
git tag -a v1.0.0 -m "v1.0.0 正式版:商品搜索 + 购物车"

# 别忘了:release 分支上的修复也要同步回 develop!
git switch develop
git merge --no-ff release/v1.0.0 -m "merge: 同步 release v1.0.0 的修复"

# 清理 release 分支
git branch -d release/v1.0.0


# ==================== Step 5:线上出 bug → hotfix ====================
# v1.0.0 发布后,线上发现购物车的移除功能在空购物车时报错

# hotfix 从 main 开出
git switch -c hotfix/空购物车崩溃 main

# 修复
cat > cart.js << 'EOF'
const cart = [];
function addToCart(id) { cart.push(id); }
function getCartTotal() { return cart.length; }
function removeFromCart(id) {
  const idx = cart.indexOf(id);
  if (idx > -1) cart.splice(idx, 1);
}
// 修复:空购物车返回空数组而非报错
function getCartItems() {
  return [...cart];
}
EOF

git add . && git commit -m "hotfix: 修复空购物车调用 remove 崩溃"

# 修改版本号
echo "const APP_VERSION = '1.0.1';" > app.js
git add . && git commit -m "chore: 版本号 1.0.1"

# 合并到 main
git switch main
git merge --no-ff hotfix/空购物车崩溃 -m "merge: hotfix 空购物车崩溃"
git tag -a v1.0.1 -m "v1.0.1 热修复:空购物车崩溃"

# 🚨 关键!合并到 develop!否则 develop 上还会有这个 bug!
git switch develop
git merge --no-ff hotfix/空购物车崩溃 -m "merge: 同步 hotfix 空购物车修复"

# 清理
git branch -d hotfix/空购物车崩溃

# 2.3 Git Flow 的优势与劣势

优势:

  • ✅ 结构清晰,五种分支各司其职,新人一看就懂
  • ✅ 严格的发布流程,不会发生「忘记修了什么就上线了」
  • ✅ main 永远稳定,任何时候都能部署

劣势:

  • ❌ 重型——小团队三四个人的项目,走完整流程太慢
  • ❌ 分支多——同时维护 feature / release / hotfix 多条线,容易忘同步
  • ❌ 不适合持续部署——如果你的团队一天发 10 次版,等 release 分支太慢了

# 三、GitHub流

# 3.1 只有一条长期分支 + 临时 feature 分支

   main ──○────────○─────────○──────────○────
           ╲        ╲         ╲          ╲
            ○──○──○  ○──○  ○──○──○  ○──○   ← feature 分支

规则极其简单:

  1. main 永远是可部署状态。
  2. 任何新东西,从 main 开出 feature 分支。
  3. feature 分支开发完,提 Pull Request。
  4. PR 审查通过 → 合并到 main → 立即部署。
  5. 部署后发现 bug → 从 main 开新的分支修复(同步骤 2~4)。

没有 develop,没有 release,只有 main + 一堆短暂的 feature 分支。

# 3.2 GitHub Flow 实战

# 和 Git Flow 的区别:没有 develop,直接从 main 出分支
git switch main
git switch -c feature/商品推荐

# 开发...
echo "function recommend() { /* 推荐算法 */ }" > recommend.js
git add . && git commit -m "feat: 商品推荐功能"

# push + 提 PR
git push -u origin feature/商品推荐

# 去 GitHub 创建 PR:base main ← compare feature/商品推荐
# 审查 → 通过 → Merge → 立即部署到生产环境

# 清理
git switch main
git pull origin main
git branch -d feature/商品推荐

# 3.3 选 Git Flow 还是 GitHub Flow?

维度 Git Flow GitHub Flow
长期分支 main + develop 只有 main
发布节奏 定期发布(周/月) 持续部署(每天多次)
适用场景 有固定发版周期的项目(App、硬件) Web 服务、SaaS
团队规模 中大型(10+ 人) 不限
学习曲线 陡 平
回滚难度 低(有 release 分支做缓冲) 中等(main 即生产)

💡 建议:如果你的项目有「版本号」这个概念且用户不能随时更新(如手机 App),用 Git Flow。如果你的项目是 Web 服务、用户访问时自动拿到最新版,用 GitHub Flow。


# 四、保护分支

无论用哪种 Flow,有一个铁律必须强制执行:禁止任何人直接 push 到 main。

# 4.1 在 GitHub 上配置

在仓库 → Settings → Branches → Add branch protection rule:

Branch name pattern: main(或 master)

☑ Require a pull request before merging
  ☑ Require approvals (至少 1 人通过)
☑ Require status checks to pass before merging
☑ Require branches to be up to date before merging
☑ Include administrators  (连管理员也不能绕过)

# 4.2 配置后的效果

# 当有人试图直接 push main:
git push origin main

# 输出:
# remote: error: GH006: Protected branch update failed for refs/heads/main.
# remote: error: At least 1 approving review is required.
# ! [remote rejected] main -> main (protected branch hook declined)

直接 push 被拒绝! 只能通过 Pull Request 合入。

# 4.3 保护分支的典型配置组合

# 最小保护(小团队推荐):
- 需要 PR 才能合并
- 至少 1 人审查通过

# 标准保护(中大型团队):
- 需要 PR 才能合并
- 至少 2 人审查通过
- CI 测试必须通过
- 分支必须是最新的(不能和 main 有冲突)
- 禁止 force push

# 严格保护(金融/医疗):
- 以上全部
- 要求的审查者必须来自 CODEOWNERS 文件
- 提交必须签名验证
- 合并前必须解决所有评论

# 五、提交规范

# 5.1 为什么消息格式很重要?

看两组 commit log:

# 组 A(混乱)
fix
update
改了一下
asdf
修 bug
feat: 具体的功能
真的修好了
# 组 B(规范)
feat: 添加商品搜索功能
fix: 修复购物车空数组崩溃
docs: 更新 API 文档
refactor: 重构支付模块回调逻辑
chore: 升级依赖到 v2.0
test: 添加搜索功能单元测试

组 B 的好处:

  • 📜 git log --oneline 就是你的 CHANGELOG
  • 🤖 可以自动生成版本号(feat → 次版本号 +1,fix → 修订号 +1)
  • 👀 Code Review 时,审查者一秒知道你的意图
  • 🔍 git log --grep="fix:" 快速过滤所有修复

# 5.2 Conventional Commits 规范

<type>(<scope>): <subject>

# type(必填):
feat      → 新功能
fix       → 修复 bug
docs      → 文档
style     → 格式(不影响逻辑)
refactor  → 重构(不增功能也不修 bug)
perf      → 性能优化
test      → 测试
chore     → 构建/依赖/工具
ci        → CI 配置
build     → 构建系统

# scope(可选):
feat(cart): 添加购物车优惠计算
fix(auth): 修复 token 过期未刷新
docs(api): 更新商品接口文档

# subject(必填):
- 用祈使句("添加" 而不是 "添加了")
- 首字母小写
- 结尾不加句号
- 不超过 72 字符

# body(可选):
为什么这么改、怎么改的、有什么副作用

# footer(可选):
BREAKING CHANGE: 不兼容变更说明
Closes #123

# 5.3 Commit 规范速查

你的改动 用这个 type 例子
加了登录功能 feat feat(auth): 添加用户登录接口
修了空指针崩溃 fix fix(cart): 修复空购物车 remove 崩溃
改了 README docs docs: 更新安装说明
重命名变量 refactor refactor(user): 重命名 getUser 为 fetchUser
删了无用 import style style: 移除未使用的 import
加了单元测试 test test(cart): 添加购物车计算测试
升级 React 版本 chore chore(deps): 升级 react 到 18.2

# 5.4 用交互式 rebase 修正之前的 message

# 最近 3 个 commit 的 message 写得不规范
git rebase -i HEAD~3

# 把 pick 改成 reword:
# reword aaa111 fix
# reword bbb222 update
# reword ccc333 改了一下

# Git 依次弹出编辑器让你改 message:
# fix       → fix(cart): 修复空购物车崩溃
# update    → feat(cart): 添加优惠计算
# 改了一下   → refactor(auth): 简化 token 验证逻辑

# 六、忽略文件

# 6.1 基本用法

# .gitignore 文件
node_modules/         # 忽略整个目录
dist/                 # 构建产物
.env                  # 环境变量(含密钥!)
*.log                 # 所有日志文件
.DS_Store             # macOS 系统文件
*.swp                 # vim 临时文件
.vscode/              # 编辑器配置(看团队约定)

# 例外:虽然忽略 .env,但要保留模板
!.env.example         # 感叹号 = 不忽略

# 6.2 全局 .gitignore

# 对于所有项目的通用忽略(如 .DS_Store):
git config --global core.excludesfile ~/.gitignore_global

# 编辑 ~/.gitignore_global
echo ".DS_Store" >> ~/.gitignore_global
echo "*.swp" >> ~/.gitignore_global

# 6.3 如果已经提交了不该提交的文件

# 第一步:从 Git 跟踪中移除(但保留本地文件)
git rm --cached node_modules/ -r

# 第二步:把 node_modules/ 加入 .gitignore
echo "node_modules/" >> .gitignore

# 第三步:提交
git add .gitignore
git commit -m "chore: 从仓库移除 node_modules,加入 gitignore"

# 第四步:push
git push

# 七、CI/CD 集成

# 7.1 概念

  git push ──→ CI 自动运行 ──→ 测试通过? ──→ 自动部署
                    │                        │
                    └── 测试失败? ← 通知开发者修复

CI(持续集成):每次 push 自动跑测试、lint、构建。 CD(持续部署):测试通过后自动部署到生产环境。

# 7.2 GitHub Actions 示例

# .github/workflows/ci.yml
name: CI

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: '18'
      - run: npm ci
      - run: npm test
      - run: npm run lint

有了这个文件,每次 push 或提 PR,GitHub 自动跑测试。测试不通过 → PR 不能合并(配合保护分支的 Require status checks)。


# 八、综合实战

# 场景设定

团队要发布电商平台 v1.1.0,这个版本包含:

  • 小李:商品收藏功能
  • 小王:订单历史查询
  • 期间:一个线上紧急 bug(图片加载失败)

采用 GitHub Flow(因为这是个 Web 项目,持续部署)。

# 实战开始

mkdir team-workflow && cd team-workflow && git init

# 初始化项目
echo 'const app = { name: "Shop", version: "1.0.0" };' > app.js
echo 'node_modules/' > .gitignore
git add . && git commit -m "init: 电商平台 v1.0.0"
git tag -a v1.0.0 -m "v1.0.0 初始版本"


# ==================== Sprint 1:并行开发两个 feature ====================

# --- 小李:商品收藏 ---
git switch -c feature/商品收藏

echo '
const favorites = [];
function addFavorite(productId) {
  if (!favorites.includes(productId)) {
    favorites.push(productId);
  }
}
function removeFavorite(productId) {
  const idx = favorites.indexOf(productId);
  if (idx > -1) favorites.splice(idx, 1);
}
' > favorites.js

git add . && git commit -m "feat(favorites): 添加商品收藏功能"

echo '
function isFavorite(productId) {
  return favorites.includes(productId);
}
' >> favorites.js
git add . && git commit -m "feat(favorites): 添加收藏状态查询"

# 整理 commit
git rebase -i HEAD~2
# squash 成一个:feat(favorites): 实现完整商品收藏功能

git push -u origin feature/商品收藏
# 去 GitHub 创建 PR


# --- 小王:订单历史 ---
git switch main
git switch -c feature/订单历史

echo '
const orders = [];
function getOrderHistory(userId) {
  return orders.filter(o => o.userId === userId);
}
function getOrderDetail(orderId) {
  return orders.find(o => o.id === orderId);
}
' > orders.js

git add . && git commit -m "feat(orders): 添加订单历史查询"

echo '
function getOrdersByDate(userId, startDate, endDate) {
  return orders.filter(o =>
    o.userId === userId &&
    o.date >= startDate &&
    o.date <= endDate
  );
}
' >> orders.js
git add . && git commit -m "feat(orders): 添加按日期范围查询"

git rebase -i HEAD~2
# squash → feat(orders): 实现完整订单历史查询功能

git push -u origin feature/订单历史
# 去 GitHub 创建 PR


# ==================== 审查 & 合并 ====================

# Code Review 流程:
# 1. 小李审查小王的 PR → 提了一个问题:"缓存策略是什么?"
# 2. 小王回复:"第一版不做缓存,下个 Sprint 加"→ 审查通过 → Merge
# 3. 小王审查小李的 PR → 建议:"addFavorite 应该返回布尔值表示是否成功"
# 4. 小李修改:
git switch feature/商品收藏
sed -i '' 's/favorites.push(productId);/favorites.push(productId); return true;/' favorites.js
git add . && git commit -m "fix(favorites): 收藏操作返回布尔结果"
git push origin feature/商品收藏
# PR 自动更新 → 审查通过 → Merge

# 拉最新 master
git switch main
git pull origin main


# ==================== 🚨 紧急:线上图片加载失败 ====================
# 用户反馈:商品详情页图片全部不显示
# 排查:CDN 链接过期

git switch -c hotfix/图片CDN main

echo 'const IMAGE_CDN = "https://new-cdn.example.com";' > config.js
git add . && git commit -m "hotfix(cdn): 修复图片 CDN 链接过期"

# 提 PR,紧急审查,2 分钟通过 → Merge 到 main
# 自动部署 → 线上恢复 🎉


# ==================== 发布 v1.1.0 ====================
git switch main
git pull origin main

# 更新版本号
echo 'const app = { name: "Shop", version: "1.1.0" };' > app.js
git add . && git commit -m "chore(release): 准备发布 v1.1.0"

git tag -a v1.1.0 -m "v1.1.0: 商品收藏 + 订单历史 + 图片 CDN 修复"
git push origin main --tags

# 🎉 v1.1.0 发布完成!


# ==================== Sprint 回顾 ====================
git log --oneline --graph main

# 输出:
# * chore(release): 准备发布 v1.1.0
# * Merge PR #3 (hotfix/图片CDN)
# * Merge PR #2 (feature/订单历史)
# * Merge PR #1 (feature/商品收藏)
# * init: 电商平台 v1.0.0

# 🎯 Sprint 时间线

  周一                周三                   周五
────┼───────────────────┼─────────────────────┼────→
    │                   │                     │
  Sprint 开始          🚨 线上 CDN bug       v1.1.0 发布
  小李开收藏分支       紧急 hotfix 修复       两个 feature 合并
  小王开订单分支       15分钟搞定            打 tag 上线
                               │
                               └── hotfix 修复直接部署,不阻塞 feature 开发

# 九、本章回顾

我学会了什么 一句话总结
Git Flow 五种分支:main / develop / feature / release / hotfix,适合定期发版
GitHub Flow 只有 main + feature 分支,PR 合并即部署
保护分支 禁止直接 push main,必须 PR + 审查 + CI 通过
Conventional Commits feat: / fix: / docs: 等规范前缀,让 log 变成 changelog
.gitignore 排除 node_modules、.env、日志等不该进仓库的文件
CI/CD 每次 push 自动跑测试,通过后自动部署
Code Review 到具体代码行提建议,修改后 PR 自动更新

🎯 团队工作流的核心不是技术,是纪律:

  1. 永远不直接 push main——无论多小的改动,一律走 PR。
  2. Commit 用规范前缀——feat: / fix: / docs:,让历史自己说话。
  3. Hotfix 的修复必须同步到所有活跃分支——修了 main 别忘了 develop。
  4. 合并完就删分支——别让 git branch 输出滚三页。

🏃 下一章预告:现在你已经能在团队中作战了。但 Git 不是完美的——有时候你会遇到各种报错、误操作、灾难现场。下一章是故障排除 & 常见问题:detached HEAD 是什么鬼、merge conflict 的五种场景、误删分支怎么恢复、大文件误提交怎么清理历史。从「会用」到「能排错」。


# 📎 本章涉及的命令速查

# === Git Flow 完整流程 ===
git branch develop                            # 从 main 创建 develop
git switch -c feature/xxx develop             # 从 develop 开 feature
git merge --no-ff feature/xxx                 # 合并 feature(保留历史)
git switch -c release/v1.0.0 develop          # 从 develop 开 release
git merge --no-ff release/v1.0.0              # release 合并到 main + develop
git tag -a v1.0.0 -m "message"                # 打发布标签
git switch -c hotfix/xxx main                 # 从 main 开 hotfix
# hotfix 必须同时合并到 main 和 develop!

# === GitHub Flow ===
git switch -c feature/xxx main                # 从 main 开 feature
git push -u origin feature/xxx                # 推送
# 去 GitHub 创建 PR → 审查 → Merge → 部署
git branch -d feature/xxx                     # 清理本地

# === 保护分支(在 GitHub 网页端配置) ===
# Settings → Branches → Add rule
# Branch name pattern: main
# ☑ Require a pull request before merging
# ☑ Require approvals
# ☑ Require status checks to pass

# === Commit 规范 ===
# feat(scope): 描述       → 新功能
# fix(scope): 描述        → 修复 bug
# docs(scope): 描述       → 文档
# refactor(scope): 描述   → 重构
# chore(scope): 描述      → 构建/依赖
# test(scope): 描述       → 测试
# 修改历史 message:git rebase -i HEAD~N → reword

# === .gitignore ===
# node_modules/   → 依赖目录
# .env            → 环境变量(密钥!)
# dist/ build/    → 构建产物
# *.log           → 日志文件
# .DS_Store       → macOS 系统文件
# !.env.example   → 例外(不忽略模板)

# === 已推送的大文件清理 ===
git rm --cached <file>                      # 从跟踪中移除
git commit -m "chore: 移除大文件"
git push
#Git
上次更新: 2026/06/28, 17:55:19
Git特种作战:stash、cherry-pick、bisect三件套
Git故障排除:遇到报错不再慌的急诊手册

← Git特种作战:stash、cherry-pick、bisect三件套 Git故障排除:遇到报错不再慌的急诊手册→

最近更新
01
科学方法实践论法
06-28
02
辩证思维矛盾论法
06-28
03
毛选中的调查观念
06-28
更多文章>
Theme by Vdoing | Copyright © 2019-2026 杨充 | MIT License | 鄂ICP备2024073355号-1 | 鄂ICP备2024073355号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式