Files
leaudit-platform-backend/docs/项目总览/团队Git协作完整规范-2026-05-07.md
T
2026-05-09 20:04:08 +08:00

23 KiB
Raw Blame History

团队 Git 协作完整规范

适用对象:个人项目、小项目、大项目 版本:v1.0 · 2026-05-07


一、核心原则

不论团队规模大小,所有 Git 协作都遵守以下 5 条铁律:

  1. 主干(main)永远可发布
  2. 凡是会影响他人的操作,事前通知、事中可见、事后可恢复
  3. 分支属于"任务",不属于"人"(详见第六章)
  4. 推送前先同步git pull --rebase 后再 git push
  5. 重要分支禁止直接 push,必须走 PR

二、如何选择工作流

决策树

你一个人做这个项目吗?
├─ 是 → 【方案 A】个人极简流
└─ 否 → 团队 ≥ 6 人 或 同时维护多版本?
        ├─ 是 → 【方案 C】Git Flow Lite(带 develop
        └─ 否 → 【方案 B】GitHub Flow90% 小项目适用)

三种方案对比

维度 A·个人 B·小项目 C·大项目
团队规模 1 人 2-5 人 6+ 人
主分支 main main main + develop
是否需 develop
是否需 release 分支 (可选)
是否需 hotfix 分支
部署策略 手动 / tag 持续部署 阶段部署
发布周期 不固定 随时 双周 / 月度
PR Review 自看 ≥1 人 ≥2 人
复杂度 ★★ ★★★★

升级信号

A → B:第二个人加入,立刻配 main 保护 + PR 流程。

B → C:满足以下任一即升级

  • 同时维护多个版本(v1 还在用,v2 在开发)
  • 有专门 QA 阶段,main 不能合并即上线
  • 发布周期 ≥ 2 周
  • 团队 ≥ 6 人

⚠️ 宁可滞后升级,也不要预防性复杂化。多数团队过度设计,把简单事搞复杂。


三、方案 A:个人项目工作流

分支模型

main (主线 + 发布锚点)
└─ feature/* (按需,仅用于实验性大改动)

日常工作流

小改动 → 直接上 main

git add .
git commit -m "fix: 修复登录按钮样式"
git push

大改动 / 不确定的实验 → 开分支保命

git checkout -b feature/重构数据层
# ...开发...

# 没问题 → 合并
git checkout main
git merge --no-ff feature/重构数据层
git push
git branch -d feature/重构数据层

# 实验失败 → 直接丢弃
git checkout main
git branch -D feature/重构数据层

发布流程

git tag -a v1.2.0 -m "release: v1.2.0 - 评查详情页上线"
git push --tags

版本号遵循 SemVer

  • v主版本.次版本.补丁
  • 主版本:不兼容改动
  • 次版本:新功能(向下兼容)
  • 补丁:bug 修复

个人项目最低纪律

习惯 价值
每天 push 到远程 硬盘坏了不丢工
commit 信息写人话 半年后能看懂
重大改动前打 tag 有回滚锚点
README 记录关键决策 时间久了不抓瞎
.gitignore 配齐 不把密钥推上去

不要做的事

  • git commit -m "update" / "修改" / "123"
  • 一周不 push
  • 在 main 上做不确定的实验
  • .env 推到远程

四、方案 B:小项目工作流(GitHub Flow

适用:2-5 人,持续部署

分支模型

main (受保护,PR 合并,自动部署到生产)
├─ feature/评查详情页
├─ fix/登录闪退
└─ hotfix/支付失败  (紧急修生产)

核心思想

  • main 永远可发布
  • feature 分支生命周期短1-3 天最佳,最长 1 周)
  • 所有改动走 PR

日常工作流(每个任务都按这个跑)

# 1. 开分支前先同步 main
git checkout main
git pull --rebase

# 2. 创建任务分支(任务命名,不要带人名)
git checkout -b feature/评查详情页

# 3. 开发,频繁小步提交,频繁推送
git add .
git commit -m "feat(评查): 新增详情页骨架"
git push -u origin feature/评查详情页

# 4. 推送前同步 main,避免冲突堆积
git fetch origin
git rebase origin/main
# 解决冲突 → 本地测试通过

# 5. 推送(rebase 后需要 force-with-lease
git push --force-with-lease

# 6. 提 PR → Review → 合并 → 自动部署

# 7. 合并后清理本地
git checkout main
git pull
git branch -d feature/评查详情页

PR 流程规范

提 PR 时

  • 标题:<type>(<scope>): <简短描述>,例:feat(评查): 新增详情页
  • 描述模板:
    ## 改动内容
    - ...
    
    ## 测试方法
    - ...
    
    ## 截图(如有 UI 改动)
    
    ## 关联 Issue
    Closes #123
    
  • 自检:lint 通过、测试通过、不含调试代码

Review 时

  • 24 小时内响应
  • 给具体可操作的反馈,不要"建议优化一下"
  • Approve 前自己心里跑一遍代码逻辑

紧急修复(hotfix

git checkout main && git pull
git checkout -b hotfix/支付失败
# 修 → 测 → push → PR → 紧急合并 → 立即部署

仓库一次性配置(落地关键)

main 分支保护(GitHub/GitLab 后台)

  • 禁止直接 push
  • 禁止 force push
  • 必须 PR + ≥1 Approve
  • 必须通过 CIlint + test
  • 合并后自动删除分支

五、方案 C:大项目工作流(Git Flow Lite

适用:6+ 人 / 多版本并存 / 有 QA 测试期

分支模型

main      (生产版本,受保护,只接受来自 release/hotfix 的合并)
└─ develop (开发主线,受保护,所有 feature 合并到这里)
    ├─ feature/评查详情页    (个人功能分支)
    ├─ feature/登录优化
    ├─ release/v2.3.0       (准备发布的快照分支)
    └─ hotfix/支付失败       (从 main 拉,修完合并回 main + develop)

各分支角色

分支 来源 合并去向 生命周期
main 永久 永久
develop 永久 永久
feature/* develop develop 任务期
release/* develop main + develop 发布周期
hotfix/* main main + develop 紧急修复

develop 的角色

  • 开发主线:所有 feature 合并到 develop
  • 集成测试环境QA 在 develop 上测试
  • 不直接发布:发布前从 develop 拉 release 分支封板

release 分支:发布前的"封板"

# 1. 从 develop 拉 release 分支(功能冻结)
git checkout develop && git pull
git checkout -b release/v2.3.0

# 2. 在 release 上只修 bug,不加新功能
# QA 测试 → 修 bug → 改版本号 → 写 changelog

# 3. 测试通过,合并到 main 并打 tag
git checkout main && git pull
git merge --no-ff release/v2.3.0
git tag -a v2.3.0 -m "release: v2.3.0"
git push --tags

# 4. 合并回 develop(带上 release 上的 bug 修复)
git checkout develop
git merge --no-ff release/v2.3.0
git push

# 5. 删除 release 分支
git branch -d release/v2.3.0

hotfix 分支:紧急修生产

# 1. 从 main 拉 hotfix 分支
git checkout main && git pull
git checkout -b hotfix/支付失败

# 2. 修 → 测 → 提 PR

# 3. 合并到 main 并打 patch tag
git checkout main
git merge --no-ff hotfix/支付失败
git tag -a v2.3.1 -m "hotfix: 修复支付失败"
git push --tags

# 4. 必须合并回 develop!否则下次发布 bug 复发
git checkout develop
git merge --no-ff hotfix/支付失败
git push

# 5. 删除 hotfix 分支
git branch -d hotfix/支付失败

日常 feature 工作流

# 从 develop(不是 main!)开分支
git checkout develop && git pull --rebase
git checkout -b feature/评查详情页

# 开发 → 推送 → PR 到 develop(不是 main!)
git push -u origin feature/评查详情页
# 提 PRfeature/评查详情页 → develop

大项目仓库配置

  • main:禁止 push、禁止 force push、只接受 release/hotfix 合并、必须 ≥2 Approve
  • develop:禁止 push、必须 PR + ≥1 Approve、必须通过 CI
  • CI 要求:lint + 单元测试 + 集成测试 + 静态分析

六、为什么禁止使用个人分支【专题】

反模式(团队中常见错误)

❌ feature/评查详情页-zhangsan
❌ zhangsan-dev
❌ feature/zhangsan/xxx
❌ 张三的分支
❌ wy-dev / wy-test

5 大问题

1️⃣ 强化"个人所有权",破坏协作精神

分支带人名 → 同事潜意识"这是张三的地盘,我别动" → 协作变独行 → 出问题没人帮看。

好的协作是任务驱动:分支属于任务,谁有空谁接手。

2️⃣ 离职、休假、轮岗时难交接

真实场景

张三休假一周,留下 5 条 feature/xxx-zhangsan 分支。李四接手时是改名(影响远程)、还是新开 feature/xxx-lisi(造成分裂)?怎么处理都别扭。

如果分支叫 feature/评查详情页,李四直接 git checkout 接着干,零摩擦

3️⃣ 分支语义模糊,看名字不知道做什么

zhangsan-dev 这条分支在做啥?

  • 评查模块?
  • 登录优化?
  • 性能调优?
  • 还是张三的"我啥都往这塞"草稿?

好的分支名 = 一句话任务说明,看到 feature/评查详情页 立刻明白。

4️⃣ 容易堆积成"杂物分支"

人名分支没有边界,张三会把"评查详情页 + 顺手优化的登录 + 试验性能改动"都塞进 feature/zhangsan-dev。结果:

  • PR 改动巨大,没人能 Review
  • 一个 bug 拖延了三个功能
  • 不能单独 revert 某项改动

任务分支天然有边界feature/评查详情页 只装评查相关改动,超出范围就该开新分支。

5️⃣ 多人协作同一功能时命名混乱

真实场景

评查详情页很大,张三李四王五一起做。分支会变成:

  • feature/评查详情页-zhangsan
  • feature/评查详情页-lisi
  • feature/评查详情页-wangwu

三人改动如何同步?合并顺序?谁先合谁后合?混乱。

正确做法:开一条父分支 feature/评查详情页,每人开子任务分支

  • feature/评查详情页-头部
  • feature/评查详情页-列表
  • feature/评查详情页-筛选

子任务都合并回父分支,最后父分支整体合到 develop。


真实案例:人名分支造成的事故

案例 1:交接黑洞

某团队张三离职前留下 zhangsan/refactor-payment 分支,里面有他重构支付的工作(约 60% 完成)。半年后团队想接着做,发现:分支与 main 已差异巨大,无法 rebase;分支内 commit 信息全是"WIP",没人知道每个 commit 在做什么;最终只能放弃,重做

案例 2:紧急修复无法落地

周五晚上生产支付功能挂了。值班发现修复需要改一个文件,但该文件在 feature/支付重构-zhangsan 分支上张三已改了一周。要么强行修生产(与张三的分支冲突会变大),要么等张三周一来。最终用了一个肮脏的 hotfix,技术债累计

案例 3PR Review 无人能审

feature/zhangsan-dev 一个 PR 改了 2000 行,包含评查、登录、列表、性能 4 个不相关的改动。Review 同事看了一上午放弃,盖章通过。两天后线上 bug,无法定位是哪个改动引起的


正确做法

任务命名规范

feature/<任务描述>              feature/评查详情页
feature/<issue号>-<描述>        feature/PROJ-123-评查详情页
fix/<bug简述>                  fix/登录闪退
hotfix/<紧急bug>               hotfix/支付失败
refactor/<范围>                refactor/数据层

任务归属体现在 PR/Issue Assignee

谁负责这个任务 → 在 PR/Issue 的 Assignee 字段标记,不要污染分支名。

分支只与「任务/目标」关联

看到 feature/评查详情页 应当能立刻回答:

  • 这条分支在做什么
  • 合并目标是什么
  • 何时该删除

例外:可以带人名的场景

仅限以下短期、可丢弃的情况

1. 个人探索/草稿分支(明确不打算合并)

zhangsan/试个性能方案
zhangsan/sandbox

用斜线作为"个人 sandbox 命名空间"前缀,与正式 feature 分支区分。

2. Fork 工作流(开源项目常见)

你 fork 仓库到自己账号后,分支名随意,提 PR 时再说。这是远程 fork 模式,不属于"单仓库协作"场景。

3. 多人并行试方案的临时区分

feature/评查详情页/方案A-zhangsan
feature/评查详情页/方案B-lisi

验证完保留赢的方案,删除全部分支,重命名为正式分支。

核心:这些场景都是短期、明确不污染主流分支的。


七、通用规范

分支命名

<type>/<description>
<type>/<issue-id>-<description>

type 类型

  • feature/ 新功能
  • fix/ bug 修复
  • hotfix/ 紧急修复(生产)
  • refactor/ 重构
  • docs/ 文档
  • test/ 测试
  • chore/ 杂项(依赖升级、配置)
  • release/ 发布分支(仅 Git Flow

示例

feature/评查详情页
feature/PROJ-123-评查详情页
fix/登录闪退
hotfix/v2.3-支付失败

禁止

  • 人名前缀/后缀
  • 拼音缩写如 wy-dev
  • 没有 type 前缀
  • 空格、特殊字符

提交信息(Conventional Commits

<type>(<scope>): <简短描述>

<可选详细说明>

<可选 footer>

type

  • feat: 新功能
  • fix: 修 bug
  • refactor: 重构(不改外部行为)
  • perf: 性能优化
  • test: 测试
  • docs: 文档
  • style: 格式(不改代码逻辑)
  • chore: 杂项
  • build: 构建相关
  • ci: CI 相关

示例

feat(评查): 新增详情页骨架屏

- 添加加载占位组件
- 实现进入动画
- 适配移动端

Closes #123

禁止

  • updatefix修改123
  • 一个 commit 改 N 个不相关的事
  • WIP(合并前应 squash 掉)

标签(Tag)规范

版本标签遵循 SemVer

v1.2.3              正式版
v1.2.3-beta.1       beta 版
v1.2.3-rc.1         发布候选版

打 tag 时机

  • 个人项目:每次发布
  • 小项目:每次部署到生产
  • 大项目:release 合并到 main 时

.gitignore 通用模板

# 依赖
node_modules/
__pycache__/
*.pyc
venv/
.venv/

# 环境变量(永远不要提交)
.env
.env.*
!.env.example

# 编辑器
.vscode/
.idea/
*.swp
.DS_Store

# 构建产物
dist/
build/
*.log
coverage/

# 本地配置
.cache/
*.local

八、共享资源协作守则

通用原则

凡是会影响他人的操作,事前通知、事中可见、事后可恢复。

共享资源守则表

共享资源 守则
共享开发/测试机 默认主分支;切换通知;用完还原;优先 git worktree
共享数据库 不在共用库做破坏性改动;每人独立 schema;测试用 docker 起本地
共享 API Key / Secret 用 secret manager;禁止贴 IM/代码/截图
CI/CD pipeline 改流水线前通知;不在大家忙时触发昂贵任务
第三方账号 SSO + 审计;操作记录可追溯
部署环境 部署窗口公告;锁机制(谁部署谁举手)

切换共享资源的标准动作

1. 群里通知:"我要 [操作] [资源],预计 [时间]"
2. 操作
3. 用完恢复默认状态
4. 群里告知:"已恢复"

优先用隔离手段,而不是切换

# git worktree:在不同目录跑不同分支,主目录不动
git worktree add ../preview-xxx feature/xxx
git worktree remove ../preview-xxx

# Docker:每个分支起独立容器
docker compose -p preview-xxx up

终极方案:消除"共享"本身

  • 每个 PR 自动起一个独立预览环境(Vercel / Netlify / K8s preview
  • 每人独立数据库 schema(自动迁移)
  • 每人独立云资源(云厂商沙盒账号)

根本不需要"共享调试机"。


九、常见问题 FAQ

Q1:合并前应该用 merge 还是 rebase

场景 推荐
个人 feature 分支同步 main git rebase(历史干净)
多人协作的分支 git merge(不重写他人 commit
合并 PR 到 main Squash and mergemain 历史干净)
已推送的分支 谨慎使用 rebase,需 --force-with-lease

Q2:feature 分支多久合并一次?

  • 理想1-3 天
  • 可接受1 周
  • 超过 1 周必须警惕:分支过大 → 拆分;同步频率提高(每天 rebase main

Q3commit 太多太乱怎么办?

合并到主分支前 squash 整理:

git rebase -i HEAD~5
# 把第二个开始的 pick 改成 squash 或 fixup

或在 PR 合并时选择 "Squash and merge"

Q4:误推了敏感信息(密钥)怎么办?

  1. 立即作废这个密钥(去后台重新生成)
  2. git filter-repo 或 BFG 清除历史
  3. 强制推送所有分支
  4. 通知所有人重新 clone

预防:

  • .gitignore 配齐 .env
  • 用 secret manager
  • git-secrets / gitleaks pre-commit 钩子

Q5rebase 时遇到冲突怎么办?

# 1. 解决冲突文件
# 2. git add <冲突文件>
# 3. git rebase --continue

# 实在搞不定就放弃
git rebase --abort

Q6:误删了分支怎么恢复?

# 找到最后一次 commit
git reflog

# 恢复
git checkout -b feature/xxx <commit-sha>

Q7git push 被拒(rejected

意味着远程分支有新 commit 你本地没有。

# 同步后再推
git pull --rebase
git push

# 如果是 rebase 后推自己的分支
git push --force-with-lease  # 注意是 --force-with-lease,不是 --force

⚠️ 永远不要对 main / develop 用 --force

Q8:什么时候删分支?

  • 合并到主干后立即删除远程和本地
  • GitHub/GitLab 可设置"合并后自动删除"
  • 本地:git branch -d feature/xxx

Q9:长期废弃的分支能直接删吗?

git log feature/xxx 看是否有未合并 commit。若有:

  • 询问作者是否还需要
  • 或导出 patchgit format-patch main..feature/xxx

Q10Reviewer 检查清单

审视 PR 是否值得合并:

  • 分支命名规范,无人名
  • 改动只做一件事,与 PR 标题一致
  • 提交信息规范
  • 测试覆盖关键路径
  • CI 全绿
  • 无调试代码(console.log、注释掉的代码)
  • 无敏感信息(API Key、密码)
  • 文档/注释 同步更新
  • 跑过本地测试

十、配套工具与一键配置

全员 Git 配置(每台机器跑一次)

# pull 默认 rebase(避免无意义 merge commit
git config --global pull.rebase true

# push 自动追踪上游
git config --global push.autoSetupRemote true

# rebase 自动 stash
git config --global rebase.autoStash true

# 默认分支名
git config --global init.defaultBranch main

# 换行符处理
git config --global core.autocrlf input  # Mac/Linux
git config --global core.autocrlf true   # Windows

推荐工具

类型 工具 作用
提交检查 husky + lint-staged commit 前自动跑 lint/format
提交规范 commitlint 强制 Conventional Commits
密钥扫描 gitleaks / git-secrets 防止推送密钥
图形化客户端 Fork / SourceTree / GitKraken 新人友好
CLI 增强 gh / lazygit 命令行高效操作
CI/CD GitHub Actions / GitLab CI 自动测试和部署
PR 预览 Vercel / Netlify 每 PR 一个独立环境

一键安装 husky + lint-staged + commitlintNode 项目)

bun add -D husky lint-staged @commitlint/cli @commitlint/config-conventional

# 初始化 husky
bunx husky init

# 配置 commitlint
echo "export default { extends: ['@commitlint/config-conventional'] }" > commitlint.config.mjs

# 添加 hooks
echo "bunx commitlint --edit \$1" > .husky/commit-msg
echo "bunx lint-staged" > .husky/pre-commit

package.json 添加:

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

附录:决策速查表

我该开什么类型的分支?

我要做的事 分支前缀 例子
新功能 feature/ feature/评查详情页
修 bug fix/ fix/登录闪退
紧急修生产 hotfix/ hotfix/支付失败
重构 refactor/ refactor/数据层
写文档 docs/ docs/api文档
升级依赖 chore/ chore/升级react18

我该写什么 commit type

我做了什么 type
写了新功能 feat
修 bug fix
重构(不改行为) refactor
性能优化 perf
改文档 docs
改格式(空格、缩进) style
加测试 test
杂项 chore

我该用哪个工作流?

1 人        → 方案 Amain + 偶尔 feature
2-5 人      → 方案 BGitHub Flowmain + feature + PR
6+ 人 / 多版本 → 方案 CGit Flow Litemain + develop + ...

附录:一页纸速查(打印贴墙)

┌─────────────────────────────────────────────────────────┐
│            团队 Git 协作 · 一页纸速查                    │
├─────────────────────────────────────────────────────────┤
│ 1. 永远从最新主干开任务分支                              │
│    git checkout main && git pull --rebase               │
│    git checkout -b feature/任务描述                      │
│                                                         │
│ 2. 分支命名 = 任务,不带人名!                           │
│    ✅ feature/评查详情页                                 │
│    ❌ feature/评查详情页-zhangsan                        │
│                                                         │
│ 3. commit 写人话                                         │
│    ✅ feat(评查): 新增详情页骨架                         │
│    ❌ update                                            │
│                                                         │
│ 4. 推送前先同步                                          │
│    git fetch && git rebase origin/main                  │
│                                                         │
│ 5. 主分支 = PR 入口,禁止直推                            │
│                                                         │
│ 6. 共享资源 = 通知 → 操作 → 还原 → 告知                 │
│                                                         │
│ 7. 永远不对 main/develop --force                         │
│                                                         │
│ 8. 合并后立刻删分支                                      │
└─────────────────────────────────────────────────────────┘