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 操作是否存在问题:
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:
if (featureFlags.newCheckout) {
// 新结账流程,尚未完成
renderNewCheckout();
} else {
renderOldCheckout();
}请问这个做法存在什么问题?如何改进?
第 12 题(🟡)
分析以下场景的冲突原因和解决方案:
Alice 在 feature/a 分支上修改了 src/styles/button.css 的第 50 行,Bob 在 feature/b 分支上修改了同一文件的第 55 行。两人都基于 main 分支开发。Bob 先合并到 main,Alice 合并时遇到冲突:
git checkout main
git merge feature/a
# 提示:Auto-merging src/styles/button.css
# CONFLICT (content): Merge conflict in src/styles/button.css请问:
- 冲突的可能原因是什么?
- 正确的解决步骤是什么?
- 如何避免此类冲突?
第 13 题(🔴)
一个团队经常出现以下问题:
- main 分支频繁被打断,无法稳定发布。
- PR 平均 500+ 行改动,Review 效率低。
- Commit Message 混乱,无法生成 CHANGELOG。
请分析问题根源并给出改进方案。
第 14 题(🟡)
以下 Husky pre-commit hook 配置是否正确?如果不正确,请指出问题:
# .husky/pre-commit
npm run test
npm run lint
npm run build
git add .第 15 题(🔴)
开发者执行了以下命令后,发现丢失了重要代码:
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(至少维护最近两个版本)。
请给出:
- 分支策略选择及理由。
- 版本 Tag 命名规范。
- Release 管理流程。
- 多版本 Hotfix 策略。
- 代码所有权(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 流程:
- 从
main切出hotfix/*分支。 - 在 hotfix 分支上修复 Bug。
- 修复后合并回
main(打上补丁版本 Tag)。 - 同时合并到
develop,确保修复同步到开发分支。
B 错误:hotfix 应该从 main 而不是 develop 切出。C 错误:直接在 main 上修改变更了受保护分支。D 错误:hotfix 不应该从 feature 分支切出。
第 9 题
查看答案与解析
问题分析:
git rebase feature/login是在 main 上 rebase feature/login 的提交,方向反了。- 如果 main 是公共分支且已经推送到远程,
git push会因为历史不一致而失败。
正确操作:
# 在 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 题
查看答案与解析
存在的问题:
- 将未完成的功能代码(newCheckout 流程)推送到了 main 分支。
- 如果 feature flag 意外开启,用户会看到未完成的功能。
改进方案:
使用合适的 toggle 类型:对于未完成的功能,toggle 应该默认关闭,且值存储在服务端配置或环境变量中,而非硬编码在代码中。
添加 toggle 守卫:
// 使用环境变量控制,确保生产环境关闭
const features = {
newCheckout: process.env.FEATURE_NEW_CHECKOUT === 'true',
};
// 添加守卫逻辑,即使 toggle 打开,也检查功能完整性
if (features.newCheckout && isFeatureComplete('newCheckout')) {
renderNewCheckout();
} else {
renderOldCheckout();
}短期分支策略:即使使用 Trunk-Based Development,也建议通过短生命周期分支 + PR 合入 main,而非直接推送。
自动清理:功能完成后及时清理 toggle 和相关条件分支,保持代码整洁。
第 12 题
查看答案与解析
1. 冲突的可能原因:
- 虽然两人修改了同一文件的不同行号,但如果附近的代码上下文(如函数调用、导入语句等)发生了变化,Git 无法确定合并顺序,可能产生冲突。
- 也可能是因为一方修改的行涉及到了另一方改动的上下文区域。
2. 正确的解决步骤:
# 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 main3. 避免此类冲突的方法:
- 小步提交、频繁集成,减少分支偏离时间。
- 与团队成员沟通,避免多人同时修改同一文件。
- 明确模块边界,使用文件拆分减少冲突概率。
- 使用
git rerere记住冲突解决方案,减少重复处理。
第 13 题
查看答案与解析
问题根源:
- 缺少分支保护,允许直接推送 main。
- PR 规模过大,Review 难以深入。
- 缺少 Commit Message 规范。
改进方案:
- 启用 main 分支保护,强制通过 PR 合并。
- 设定 PR 大小上限(如 300 行),超过需拆分。
- 引入 Conventional Commits 和 commitlint 检查。
- 使用 Changesets 或 semantic-release 自动生成 CHANGELOG。
- 设定 Review SLA,纳入团队绩效考核。
- 引入 Husky pre-commit hook 自动检查代码格式。
第 14 题
查看答案与解析
存在两个问题:
命令执行时机错误:
test、lint、build在 pre-commit 中运行会导致 commit 前等待较长时间,使开发者产生挫败感。建议将 build 移至 pre-push,test 放在 CI 中。git add .不应该在 hook 中使用:自动添加所有文件可能导致意外文件被提交。如果配合lint-staged,应该由 lint-staged 管理 staged 文件的添加。
改进后的配置:
# .husky/pre-commit — 只做轻量检查
npx lint-staged# .husky/pre-push — 运行耗时操作
npm run test
npm run buildlint-staged 配置:
{
"lint-staged": {
"*.{js,ts,tsx}": ["eslint --fix", "prettier --write"]
}
}第 15 题
查看答案与解析
恢复步骤:
# 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 题
查看答案与解析
改进计划:
- 建立 Review 检查清单:明确 Review 应关注的维度(设计、测试、安全、性能、可访问性),不只是格式。
- 控制 PR 大小:设定 300-400 行上限,超过需说明原因或拆分。
- 设定 Review SLA:如 24 小时内必须响应,阻塞超过 12 小时升级。
- 引入自动化检查:lint、test、format 由 CI 完成,Reviewer 专注于设计问题。
- 建立 Review 文化:
- 对事不对人。
- Reviewer 也承担质量责任。
- 定期 Review Review,分析常见遗漏。
- 工具支持:使用 GitHub/GitLab 的 Review 工具,支持 suggestion、thread、approval 流程。
第 19 题
查看答案与解析
实施方案:
第一步:启用 rerere
# 全局启用 git rerere
git config --global rerere.enabled true第二步:feature-b 先合并到 feature-a(第一次解决冲突)
git checkout feature-a
git merge feature-b
# 遇到冲突,手动解决
# Git rerere 会记录这次冲突解决方案
git add .
git merge --continue第三步:后续频繁同步时,rerere 自动应用已记录的解决方案
# 当 feature-b 有新的提交时,再次合并
git merge feature-b
# Git 会提示:Resolved 'path/to/file' using previous resolution.
# 只处理新增的冲突部分第四步:合并到 main 前的最终同步
# 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 策略
# 当前最新版本 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