搜「大厂 Git 分支管理规范」的人,多半不是想要一份目录模板,而是想确认两件事:自己这套仓库该用单主干,还是 main 加 develop 再加 release 分支;以及保护规则、合并方式、发布 tag 这三处到底怎么配才不会越用越乱。这两件事的判断依据不在任何文档里,而在你仓库当前的分支拓扑和代码平台的保护分支面板里,先把这两处读出来,比先挑一套模型更省时间。
分支管理规范的判断起点是分支拓扑与保护规则,不是命名约定。先用 git ls-remote --heads origin 列出远端存活分支,再到面板的 Protected branches / Branch protection rules 核对 Allowed to merge、Require approvals 等字段,两者对不上就说明规范只写在文档里。合并方式(merge commit、squash、rebase)一旦在团队内混用,release 分支回合并时会出现重复提交与反复冲突,这是最常见的坑。建议先在主线上统一一种合并方式,再谈分支模型。
团队项目的Git分支管理规范
「团队项目的 Git 分支管理规范」在分支管理规范里对应的是「分支拓扑与保护规则」这一步,不是提交信息格式,也不是 Code Review 流程。确认是不是它,看两个可核对的位置就够。
第一处是远端引用列表,在仓库任意目录执行:
git ls-remote --heads origin
输出里 refs/heads/ 后面的每一行就是远端仍存活的分支。只出现 refs/heads/main(或 master),说明是单主干;同时出现 refs/heads/develop、refs/heads/release/x.y 这类,说明团队在跑多条长期分支。第二处是平台面板:GitLab 在 Settings → Repository → Protected branches,GitHub 在 Settings → Branches → Branch protection rules,要看的字段是 Allowed to merge、Allowed to push、Require approvals。远端有 develop 分支但面板里没有任何保护项,说明规范没落到仓库上,只在 wiki 里躺着。
分支管理规范:先把能核对的事实摆清楚
把对象、前提和现象分开列,这一段不下判断。对象是四样:长期分支集合、保护规则、主线合并方式、发布 tag 规则。前提是你有该仓库的读权限;面板设置项需要 Maintainer 或 Admin 权限才能看到,看不到就只核对前三项。
分支存活时间与最近提交,用来判断哪些分支其实已经没人用:
git for-each-ref refs/remotes/origin --format='%(refname:short) %(committerdate:iso8601)'
主线历史形状,决定合并方式:
git log --graph --oneline --decorate --first-parent origin/main -20
本地与合并相关的配置,注意这是个人配置,不能代表团队约定,只能说明你这台机器会怎么合并:

git config --get-regexp '^(pull|merge|push|branch)\.'
三条输出的读法:第一条看哪条分支的 committerdate 停在几个月前,那就是没人维护的残留分支;第二条看有没有 merge commit 的菱形结构;第三条看 pull.rebase、merge.ff 的值。这三项都能贴到工单里,属于可核对的事实。
分支管理规范最容易搞错的一点
最常见的误解是把「分支命名规范」当成了「分支管理规范」。命名只影响可读性,真正决定协作成本的是主线合并方式有没有统一。分界线很清楚:主线上有没有 merge commit。
一个能把两种情况区分开的检查动作:
git log --merges --oneline origin/main -5
有输出,说明主线保留了合并提交,走的是 merge --no-ff 或平台的 Create a merge commit;没有输出,说明走的是 squash 或 rebase 快进。再执行 git log --oneline origin/main -5,如果每个功能只对应一行提交、且提交信息是 PR 标题,那就是 squash。这个区别决定了 release 分支往回合并时会不会出现重复改动:merge 方式下 cherry-pick 过的提交回合时通常能自动识别,squash 方式下每次都是新提交,同一改动会在主线上出现两次,冲突也会反复出现。
分支管理规范:一个照着就能做完的做法
下面的路径按「单主干 + 短生命周期功能分支 + squash 合并 + tag 发布」来写,这是目前改动量较小、回滚也清楚的一种做法。多长期分支的团队需要把第 2 步的基分支换成 develop,其余不变。
第一步,把本地基础配置固定下来,在仓库根目录执行:
git config --local pull.ff only
git config --local push.default simple
git config --local rebase.autoStash true
git config --local merge.ff false
第二步,从最新主线切功能分支,分支名带上模块和意图:

git switch main
git pull --ff-only
git switch -c feature/order-export-timeout
pull --ff-only 报 diverged 就停下,说明本地 main 和远端已经分叉,先查清是谁直接推了 main,不要用 merge 掩盖过去。
第三步,提交前把分支对齐主线,避免 MR 里混入无关提交:
git fetch origin
git rebase -i origin/main
git push -u origin feature/order-export-timeout
push 之后终端会打印创建远端分支的提示,同时给出平台上的新建 MR 链接,正常情况下可以直接点开。
第四步,在平台上以 squash 方式合并,合并后打 tag:
git switch main
git pull --ff-only
git tag -a v1.4.0 -m "release v1.4.0"
git push origin v1.4.0
tag 前先跑一次 git describe --tags --abbrev=0,确认上一个版本号,避免跳号。这一步该看到的是 push 输出里出现 [new tag] v1.4.0。
分支管理规范:怎么验证结果对不对
验证分三处,都在本地能做,不需要额外工具。

其一,确认远端分支集合符合约定,且没有偷偷新增的长期分支:
git ls-remote --heads origin
正常结果应该只有约定内的那几个 refs/heads/ 条目,功能分支在合并后应当被删除;如果 feature/ 开头的分支已经堆积很多,说明合并后删分支这一步没有执行。
其二,确认主线历史形状符合选定方式:
git log --oneline --first-parent origin/main -10
选 squash 的话,正常结果是一行一个功能、提交信息为 PR 标题,且看不到零散的 fix typo 这类提交;选 merge commit 的话,应当能看到菱形结构。
其三,确认 tag 指向的就是这次上线的主线提交:
git rev-parse v1.4.0^{commit}
git rev-parse origin/main
两条输出的哈希一致,说明 tag 打在主线最新提交上;不一致就说明合并后主线又被推了新提交,或者 tag 打在了功能分支上。
面板侧再核对一次:Protected branches 页面里 main 的 Allowed to push 应当为空或只有自动化账号,Require approvals 至少为 1;CI 页面上一次流水线应当由 tag 或 main 的合并触发,而不是由任意 push 触发。这四项都对上,规范才算真正生效,否则只是写在了文档里。