Skip to content

Git 工作流与版本控制练习册 ​

通过练习掌握 Git 高级操作、分支策略、Code Review 与版本管理。


难度分级 ​

  • 🟢 基础:理解概念,能执行基本命令。
  • 🟡 进阶:能应用知识解决协作问题。
  • 🔴 深入:能设计团队级 Git 工作流和治理方案。

一、选择题 ​

第 1 题(🟢) ​

以下哪个命令用于将当前修改临时保存,切换到其他分支?

A. git reset
B. git stash
C. git rebase
D. git cherry-pick

第 2 题(🟢) ​

Conventional Commits 中,feat 表示什么类型?

A. 修复 Bug
B. 新功能
C. 文档更新
D. 代码重构

第 3 题(🟡) ​

Git Flow 中,用于修复线上紧急问题的分支是?

A. feature/*
B. release/*
C. hotfix/*
D. develop

第 4 题(🟡) ​

以下哪种情况适合使用 git rebase?

A. 已推送到远程的公共分支
B. 本地功能分支整理提交历史
C. 合并两个长期分支并保留完整历史
D. 撤销某个已发布提交

第 5 题(🟡) ​

语义化版本 2.1.3 中,1 代表什么?

A. 主版本号
B. 次版本号
C. 修订号
D. 预发布版本

第 6 题(🔴) ​

在 Trunk-Based Development 中,未完成的功能如何管理?

A. 长期 feature 分支
B. 特性开关(Feature Toggle)
C. 不提交代码
D. 单独 release 分支

第 7 题(🟡) ​

以下哪个 Git Hook 适合用来校验 Commit Message 格式?

A. pre-commit
B. commit-msg
C. pre-push
D. post-commit

第 8 题(🔴) ​

团队使用 Git Flow,线上发现紧急 Bug,正确的操作顺序是?

A. 从 main 切 hotfix 分支 → 修复 → 合并到 main 和 develop
B. 从 develop 切 hotfix 分支 → 修复 → 合并到 main
C. 直接在 main 上修复 → 推送
D. 从 feature 切 hotfix 分支 → 修复 → 合并到 feature


二、代码分析题 ​

第 9 题(🟡) ​

分析以下 Git 操作是否存在问题:

bash
git checkout main
git pull origin main
git rebase feature/login
git push origin main

第 10 题(🟡) ​

以下 Commit Message 是否符合 Conventional Commits 规范?如何改进?

update login page

fixed some bugs and changed styles

第 11 题(🔴) ​

团队使用 Trunk-Based Development,某开发者将以下代码推送到 main:

javascript
if (featureFlags.newCheckout) {
  // 新结账流程,尚未完成
  renderNewCheckout();
} else {
  renderOldCheckout();
}

请问这个做法存在什么问题?如何改进?

第 12 题(🟡) ​

分析以下场景的冲突原因和解决方案:

Alice 在 feature/a 分支上修改了 src/styles/button.css 的第 50 行,Bob 在 feature/b 分支上修改了同一文件的第 55 行。两人都基于 main 分支开发。Bob 先合并到 main,Alice 合并时遇到冲突:

bash
git checkout main
git merge feature/a
# 提示:Auto-merging src/styles/button.css
# CONFLICT (content): Merge conflict in src/styles/button.css

请问:

  1. 冲突的可能原因是什么?
  2. 正确的解决步骤是什么?
  3. 如何避免此类冲突?

第 13 题(🔴) ​

一个团队经常出现以下问题:

  • main 分支频繁被打断,无法稳定发布。
  • PR 平均 500+ 行改动,Review 效率低。
  • Commit Message 混乱,无法生成 CHANGELOG。

请分析问题根源并给出改进方案。

第 14 题(🟡) ​

以下 Husky pre-commit hook 配置是否正确?如果不正确,请指出问题:

bash
# .husky/pre-commit
npm run test
npm run lint
npm run build
git add .

第 15 题(🔴) ​

开发者执行了以下命令后,发现丢失了重要代码:

bash
git reset --hard HEAD~3

请问如何找回丢失的提交?请给出完整的恢复步骤。


三、设计/开放题 ​

第 16 题(🟡) ​

为一个 10 人前端团队设计 Git 工作流,要求:

  • 每周发布一次
  • 支持 hotfix
  • 需要 Code Review
  • 能自动生成 CHANGELOG

第 17 题(🔴) ​

设计一套大型 Monorepo 的 Git 治理方案,包括:

  • 分支策略
  • Code Review 规则
  • 版本管理(Changesets)
  • 权限与 CODEOWNERS
  • 性能优化(浅克隆、稀疏检出)

第 18 题(🔴) ​

你作为前端负责人,发现团队 Code Review 流于形式,经常出现:

  • Reviewer 只关注代码格式
  • 大 PR 一次性合并
  • Review 响应慢,阻塞发布

请设计一个可落地的 Code Review 改进计划。

第 19 题(🟡) ​

团队有两个长期并行的功能分支(feature-a 和 feature-b),都已经开发了 3 周。现在 feature-a 需要合并 feature-b 的最新改动,但两者都与 main 产生了大量冲突。

请设计一种使用 git rerere 来减少合并痛苦的具体实施方案。

第 20 题(🔴) ​

设计一个 50 人团队的 Git 分支策略和发布管理方案,要求:

团队背景:

  • 前端 20 人,后端 20 人,QA 5 人,DevOps 5 人。
  • 产品有 Web、Mobile Web 和 WeChat Mini Program 三个端。
  • 每周一个版本,每季度一个大版本。
  • 需要支持多个历史版本的 hotfix(至少维护最近两个版本)。

请给出:

  1. 分支策略选择及理由。
  2. 版本 Tag 命名规范。
  3. Release 管理流程。
  4. 多版本 Hotfix 策略。
  5. 代码所有权(CODEOWNERS)设计。

参考答案 ​

第 1 题 ​

查看答案与解析

答案:B

git stash 用于临时保存当前工作目录的修改,方便切换到其他分支处理紧急任务。

第 2 题 ​

查看答案与解析

答案:B

feat 表示新增功能(feature)。

第 3 题 ​

查看答案与解析

答案:C

hotfix/* 分支用于从 main 分出来修复线上紧急问题,修复后合并回 main 和 develop。

第 4 题 ​

查看答案与解析

答案:B

git rebase 适合在本地整理提交历史,使历史更线性。不应对已推送的公共分支执行 rebase。

第 5 题 ​

查看答案与解析

答案:B

语义化版本 MAJOR.MINOR.PATCH 中,1 是 MINOR(次版本号),表示向下兼容的功能新增。

第 6 题 ​

查看答案与解析

答案:B

Trunk-Based Development 通过特性开关(Feature Toggle)管理未完成的功能,实现高频集成。

第 7 题 ​

查看答案与解析

答案:B

commit-msg hook 在提交信息被创建之后、提交完成之前触发,适合校验 commit message 格式。pre-commit 在 commit 前触发,适合代码检查;pre-push 在 push 前触发,适合运行测试。

第 8 题 ​

查看答案与解析

答案:A

Git Flow 的 hotfix 流程:

  1. 从 main 切出 hotfix/* 分支。
  2. 在 hotfix 分支上修复 Bug。
  3. 修复后合并回 main(打上补丁版本 Tag)。
  4. 同时合并到 develop,确保修复同步到开发分支。

B 错误:hotfix 应该从 main 而不是 develop 切出。C 错误:直接在 main 上修改变更了受保护分支。D 错误:hotfix 不应该从 feature 分支切出。

第 9 题 ​

查看答案与解析

问题分析:

  1. git rebase feature/login 是在 main 上 rebase feature/login 的提交,方向反了。
  2. 如果 main 是公共分支且已经推送到远程,git push 会因为历史不一致而失败。

正确操作:

bash
# 在 feature/login 分支上 rebase main,然后合并到 main
git checkout feature/login
git rebase main

git checkout main
git merge feature/login --no-ff
git push origin main

第 10 题 ​

查看答案与解析

问题:

  • 没有 type(feat/fix 等)。
  • subject 不够具体。
  • body 中混合了多个类型的变更。

改进示例:

fix(login): 修复登录页样式错位

- 修复移动端下登录按钮被遮挡的问题
- 调整表单间距以匹配设计规范

Closes #456

第 11 题 ​

查看答案与解析

存在的问题:

  1. 将未完成的功能代码(newCheckout 流程)推送到了 main 分支。
  2. 如果 feature flag 意外开启,用户会看到未完成的功能。

改进方案:

  1. 使用合适的 toggle 类型:对于未完成的功能,toggle 应该默认关闭,且值存储在服务端配置或环境变量中,而非硬编码在代码中。

  2. 添加 toggle 守卫:

javascript
// 使用环境变量控制,确保生产环境关闭
const features = {
  newCheckout: process.env.FEATURE_NEW_CHECKOUT === 'true',
};

// 添加守卫逻辑,即使 toggle 打开,也检查功能完整性
if (features.newCheckout && isFeatureComplete('newCheckout')) {
  renderNewCheckout();
} else {
  renderOldCheckout();
}
  1. 短期分支策略:即使使用 Trunk-Based Development,也建议通过短生命周期分支 + PR 合入 main,而非直接推送。

  2. 自动清理:功能完成后及时清理 toggle 和相关条件分支,保持代码整洁。

第 12 题 ​

查看答案与解析

1. 冲突的可能原因:

  • 虽然两人修改了同一文件的不同行号,但如果附近的代码上下文(如函数调用、导入语句等)发生了变化,Git 无法确定合并顺序,可能产生冲突。
  • 也可能是因为一方修改的行涉及到了另一方改动的上下文区域。

2. 正确的解决步骤:

bash
# 1. 拉取最新的 main
git checkout main
git pull origin main

# 2. 合并 feature/a 到 main
git merge feature/a

# 3. 手动解决冲突文件
# 编辑 src/styles/button.css,保留双方的合理修改

# 4. 标记冲突已解决
git add src/styles/button.css

# 5. 提交合并
git commit

# 6. 推送
git push origin main

3. 避免此类冲突的方法:

  • 小步提交、频繁集成,减少分支偏离时间。
  • 与团队成员沟通,避免多人同时修改同一文件。
  • 明确模块边界,使用文件拆分减少冲突概率。
  • 使用 git rerere 记住冲突解决方案,减少重复处理。

第 13 题 ​

查看答案与解析

问题根源:

  1. 缺少分支保护,允许直接推送 main。
  2. PR 规模过大,Review 难以深入。
  3. 缺少 Commit Message 规范。

改进方案:

  1. 启用 main 分支保护,强制通过 PR 合并。
  2. 设定 PR 大小上限(如 300 行),超过需拆分。
  3. 引入 Conventional Commits 和 commitlint 检查。
  4. 使用 Changesets 或 semantic-release 自动生成 CHANGELOG。
  5. 设定 Review SLA,纳入团队绩效考核。
  6. 引入 Husky pre-commit hook 自动检查代码格式。

第 14 题 ​

查看答案与解析

存在两个问题:

  1. 命令执行时机错误:test、lint、build 在 pre-commit 中运行会导致 commit 前等待较长时间,使开发者产生挫败感。建议将 build 移至 pre-push,test 放在 CI 中。

  2. git add . 不应该在 hook 中使用:自动添加所有文件可能导致意外文件被提交。如果配合 lint-staged,应该由 lint-staged 管理 staged 文件的添加。

改进后的配置:

bash
# .husky/pre-commit — 只做轻量检查
npx lint-staged
bash
# .husky/pre-push — 运行耗时操作
npm run test
npm run build

lint-staged 配置:

json
{
  "lint-staged": {
    "*.{js,ts,tsx}": ["eslint --fix", "prettier --write"]
  }
}

第 15 题 ​

查看答案与解析

恢复步骤:

bash
# 1. 查看 reflog,找到被 reset 之前的 HEAD 位置
git reflog

# 输出示例:
# a1b2c3d HEAD@{1}: reset: moving to HEAD~3
# e5f6g7h HEAD@{2}: commit: feat(cart): 添加购物车计算逻辑
# i9j0k1l HEAD@{3}: commit: fix(checkout): 修复价格显示问题
# m2n3o4p HEAD@{4}: commit: feat(user): 添加用户等级展示

# 2. 从 reflog 中找到 reset 之前的最新提交(HEAD@{1} 或直接使用 e5f6g7h)
git reset --hard HEAD@{1}
# 或
git reset --hard e5f6g7h

# 3. 验证恢复结果
git log --oneline -5

注意事项:

  • reflog 只在本地有效,如果已经执行了 git gc 或 reflog 超时(默认 90 天),可能无法恢复。
  • 如果丢失的提交已经推送到远程,可以直接从远程拉取。
  • 建议立即执行恢复操作,不要在 reset 后做其他可能导致 reflog 被覆盖的操作。

第 16 题 ​

查看答案与解析

参考方案:

采用简化版 Git Flow:

main:稳定分支,始终可发布
develop:集成分支,日常开发合并到这里
feature/*:功能分支,从 develop 切出
release/*:发布分支,从 develop 切出,测试后合并到 main
hotfix/*:从 main 切出,修复后合并回 main 和 develop

配套流程:

  • 每个功能分支通过 PR 合并到 develop。
  • 发布前从 develop 切出 release 分支,只修复 Bug,不新增功能。
  • release 合并到 main 后打 Tag。
  • 使用 Changesets 生成 CHANGELOG。
  • hotfix 合并后立即发布补丁版本。

第 17 题 ​

查看答案与解析

参考方案:

分支策略:

  • main:受保护,只接受 PR 合并。
  • feature/*:短生命周期,完成后删除。
  • 考虑 Trunk-Based Development,配合 Feature Toggle。

Code Review 规则:

  • 每个 PR 至少 1 名 CODEOWNERS 批准。
  • PR 必须通过 CI(lint/test/build)。
  • 单 PR 改动不超过 400 行。

版本管理:

  • 使用 Changesets 管理多包版本。
  • CI 自动发布变更的包。

权限与 CODEOWNERS:

  • 按目录划分负责人。
  • 关键目录(如 core、utils)需要多人批准。

性能优化:

  • 新成员使用 --depth 1 浅克隆。
  • 使用 git sparse-checkout 只检出需要的包。
  • 大文件使用 Git LFS。

第 18 题 ​

查看答案与解析

改进计划:

  1. 建立 Review 检查清单:明确 Review 应关注的维度(设计、测试、安全、性能、可访问性),不只是格式。
  2. 控制 PR 大小:设定 300-400 行上限,超过需说明原因或拆分。
  3. 设定 Review SLA:如 24 小时内必须响应,阻塞超过 12 小时升级。
  4. 引入自动化检查:lint、test、format 由 CI 完成,Reviewer 专注于设计问题。
  5. 建立 Review 文化:
    • 对事不对人。
    • Reviewer 也承担质量责任。
    • 定期 Review Review,分析常见遗漏。
  6. 工具支持:使用 GitHub/GitLab 的 Review 工具,支持 suggestion、thread、approval 流程。

第 19 题 ​

查看答案与解析

实施方案:

第一步:启用 rerere

bash
# 全局启用 git rerere
git config --global rerere.enabled true

第二步:feature-b 先合并到 feature-a(第一次解决冲突)

bash
git checkout feature-a
git merge feature-b
# 遇到冲突,手动解决
# Git rerere 会记录这次冲突解决方案
git add .
git merge --continue

第三步:后续频繁同步时,rerere 自动应用已记录的解决方案

bash
# 当 feature-b 有新的提交时,再次合并
git merge feature-b
# Git 会提示:Resolved 'path/to/file' using previous resolution.
# 只处理新增的冲突部分

第四步:合并到 main 前的最终同步

bash
# rebase main 时 rerere 同样有效
git rebase main
# 已解决的冲突自动应用,只需处理新增冲突

注意事项:

  • rerere 记录保存在 .git/rr-cache 目录中,不会推送到远程。
  • 如果冲突解决方案在后续需要调整,rerere 会自动更新记录。
  • 团队成员都需要启用 rerere 才能享受完整收益。

第 20 题 ​

查看答案与解析

参考方案:

1. 分支策略选择(Trunk-Based Development + 版本分支)

选择理由:

  • 50 人团队并发高,需要减少合并冲突(TBD 的短分支策略)。
  • 三个端共享核心代码,TBD 的频繁集成有助于发现跨端兼容问题。
  • 需要维护历史版本,引入版本分支支持 LTS。
main ──●──●──●──●──●──●──●──●──●─────  (始终可发布)
         \  /  \  /  \  /  \  /
short     ●    ●    ●    ●              (feature 分支 < 2 天)
                                       
v1.x ─────●────●────●────●────●─────    (LTS 分支,仅修 Bug)
v2.x ───────────●────●────●────●─────   (当前大版本)

2. 版本 Tag 命名规范

v<MAJOR>.<MINOR>.<PATCH>-<端标识>.<构建号>

示例:
v2.1.0                  # 全端统一版本
v2.1.0-web              # Web 端特定版本
v2.1.1-wechat           # 小程序端补丁
v2.1.0-rc.1             # 候选发布版本

3. Release 管理流程

周一至周三:功能开发(feature 分支 → main)
周四:冻结新功能,只修 Bug
周五上午:从 main 切出 release 分支进行回归测试
周五下午:release 合并到 main,打 Tag,部署生产

4. 多版本 Hotfix 策略

bash
# 当前最新版本 v2.1.0 有 Bug,同时需要修复 v1.5.0 LTS

# 修复最新版本
git checkout -b hotfix/v2.1.1 main
# 修复、提交
git checkout main
git merge hotfix/v2.1.1
git tag v2.1.1

# 修复 LTS 版本
git checkout -b hotfix/v1.5.1 v1.x
# 修复、提交
git checkout v1.x
git merge hotfix/v1.5.1
git tag v1.5.1

# 如果有必要,将修复 cherry-pick 到 main
git checkout main
git cherry-pick <hotfix-commit-hash>

5. CODEOWNERS 设计

# 全局默认负责人
*                          @team/frontend-core

# 各端代码负责人
/packages/web/**          @team/frontend-web
/packages/mobile/**       @team/frontend-mobile
/packages/wechat/**       @team/frontend-wechat

# 共享工具库
/packages/shared/**       @team/frontend-core

# CI/CD 配置
/.github/workflows/**     @team/devops

# 安全相关
**/security/**            @team/security
**/auth/**                @team/security @team/backend-auth

# 测试
/tests/e2e/**             @team/qa

关键成功因素:

  • 高度自动化的 CI/CD 流水线(每个 PR 自动构建、测试、部署预览环境)。
  • Feature Toggle 管理系统(支持灰度发布和 A/B 测试)。
  • 清晰的包划分和模块边界,减少跨团队冲突。
  • 定期(每季度)回顾和调整工作流。

标签:#git #version-control #code-review #branching-strategy #monorepo

最后更新:2026-07-06

基于 MIT 协议发布