三层配置:默认层(能力包自带)、团队层(进仓库走 review)、个人层(不进仓库)。 个人层改「偏好」可以,改「权限」要拦——比如把自动提交从关改成开。 能力包一旦被两个项目用,就必须版本化:让升级变成可选项。
上一篇讲了什么时候该共享。这一篇讲共享什么、怎么合。 为什么不能大家都用同一份配置? 因为「约定」和「偏好」是两种东西。 行宽多少是约定,要不要自动提交是权限——混在一份文件里,改行宽的人会顺手把权限也改了。 Demo 拿三份配置真合并一遍:默认六个键、团队覆盖三个、个人又覆盖两个。 再对比三个项目在能力包升级时的损坏数:锁版本零处,不锁两处。
一、规则怎么共享
三层,各管一段。
| 层 | 放哪 | 谁能改 | 盖谁 |
|---|---|---|---|
| 默认层 | 能力包自带 | 维护者 | — |
| 团队层 | 仓库里的配置文件 | 团队,走 review | 默认层 |
| 个人层 | 本地文件,不进仓库 | 本人 | 团队层 |
三层的关键是「个人层不进仓库」这条。 它让人可以为自己调,但调的东西不会污染别人。 如果没有这一层,会发生两件事: 一是所有人都在改团队文件,改完就冲突; 二是有人干脆不改,忍着用不合适的配置,然后慢慢不用了。 合并顺序是「默认 → 团队 → 个人」,后盖前。 Demo 里团队盖了三个键、个人又盖了两个,六个键里五个被改过—— 这很正常。团队化的目的不是「所有人一样」,是「不一样的地方有个说法」。 所以合并的时候要留一条痕迹:谁盖了谁、盖成了什么。 这条痕迹不拦人,它的作用是「出问题的时候能查」。
二、权限怎么分
有一类配置不该跟偏好混在一起。
| 配置 | 性质 | 能不能个人改 |
|---|---|---|
| 行宽、缩进 | 偏好 | 能 |
| 测试命令 | 约定 | 能,但要跟团队说 |
| 自动提交、跳过检查 | 权限 | 不能 |
| 凭据、密钥 | 秘密 | 不进配置 |
第三行是这一节的落点。
「自动提交」听起来是个效率开关,但它实际改变的是「没人看过就进主干」这件事的边界。
这种开关放在个人层,等于每个人自己决定要不要审批。
Demo 里那句话说得直白:那属于权限,不属于偏好。
判据是「这个开关会不会让某道闸门失效」——会让闸门失效的,一律不许个人改。
第四行也值得注意:凭据不进配置。
它应该进环境变量或者密钥管理,而不是一份会被 commit 的文件。
这一条在很多团队是「知道但没做」,直到某次提交里出现一串 sk- 开头的东西。
三、能力包怎么版本化
Demo 里三个项目:服务 A 锁 v1、服务 B 锁 v2、服务 C 不锁。 能力包从 v1 升到 v2 时改了两处签名,结果 A 和 B 一处都没坏,C 坏了两处。 这个对比说明版本化的真正作用:让「升级」从「必然发生」变成「可以选择」。 不锁版本,升级是被动的——别人发了新版,你下次安装就跟着变。 版本化要做得有用,得满足两条。 第一条:旧版本还能用——如果 v1 发布后就被删了,锁版本是空话。 第二条:变更要说清是「破坏性」还是「兼容」——这跟 11.2 讲接口契约的判定是同一套标准。 为什么「被两个以上项目用」是版本化的触发条件? 因为一个项目用的时候,改坏了当场就知道;两个项目用的时候,改坏了是「另一个项目下周构建挂了」。 时间差就是成本。
四、共享什么、不共享什么
| 共享 | 不共享 |
|---|---|
| 规则文件 | 个人的快捷键和别名 |
| 能力包(带版本) | 本地路径与绝对目录 |
| CI 的检查项 | 个人的登录凭据 |
右边三样有一个共同点:换个人就跑不通。
换个人跑不通的东西一旦共享,第一个受害的是新同事。
「本地路径」这一条特别常见。
有人把 /Users/zhang/work/... 写进了共享配置,自己跑得好好的,别人一跑就报「文件不存在」。
这种错查起来很费劲,因为报错说的是「文件不存在」,没人会想到是配置里写死了别人的路径。
所以共享的判据可以写得很硬:把这份配置给一个新人,他能不能直接跑通。
能,就可以共享;不能,就说明里面还有属于你的东西。
五、动手 Demo:共享规则、权限与能力包:三层配置怎么合
三份配置:默认六个键、团队覆盖三个、个人又覆盖两个。真合并一遍。 再对比三个项目在能力包升级时的损坏数:锁版本和不锁版本。 合并是按「后盖前」做的,冲突是逐键比出来的——三张表里的每个值都是脚本算的,不是我填的。
DEFAULT_CFG = {"format.line_width": "98", "agent.max_files": "10",
"agent.auto_commit": "false", ...}
TEAM_CFG = {"format.line_width": "100", "agent.max_files": "6", ...}
LOCAL_CFG = {"format.indent": "2", "agent.auto_commit": "true"}
merged = dict(DEFAULT_CFG)
merged.update(TEAM_CFG)
merged.update(LOCAL_CFG)
for k in sorted(DEFAULT_CFG):
print(k, DEFAULT_CFG[k], TEAM_CFG.get(k, "—"),
LOCAL_CFG.get(k, "—"), merged[k])
实跑输出:
--------------------------------------------------------------------
共享规则、权限与能力包:三层配置怎么合
--------------------------------------------------------------------
团队化的核心不是「大家用同一个工具」,是「大家对同一套约束有一致的理解」。
① 三层配置,谁盖谁
--------------------------------------------------------------------
| 层 | 放哪 | 谁能改 | 盖谁 |
|---|---|---|---|
| 默认层 | 能力包自带 | 维护者 | — |
| 团队层 | 仓库里的配置文件 | 团队,走 review | 默认层 |
| 个人层 | 本地文件,不进仓库 | 本人 | 团队层 |
三层的关键是「个人层不进仓库」。它让人可以为自己调,但调的东西不会污染别人。
② 真合并一遍
--------------------------------------------------------------------
| 键 | 默认 | 团队 | 个人 | 结果 |
|---|---|---|---|---|
| agent.auto_commit | false | — | true | true |
| agent.max_files | 10 | 6 | — | 6 |
| format.indent | 4 | — | 2 | 2 |
| format.line_width | 98 | 100 | — | 100 |
| linter.enabled | true | — | — | true |
| test.command | unittest discover | unittest -s tests | — | unittest -s tests |
团队层覆盖了 3 个键,个人层又覆盖了 2 个。
③ 合并要报冲突,不能默默盖
--------------------------------------------------------------------
| 键 | 被盖的值 | 盖上去的值 | 性质 |
|---|---|---|---|
| agent.max_files | 10 | 6 | 团队盖默认 |
| format.line_width | 98 | 100 | 团队盖默认 |
| test.command | unittest discover | unittest -s tests | 团队盖默认 |
3 条里 3 条是「团队盖默认」——那是正常的。
标注出来的意义是「留下一条能查的痕迹」,不是「拦下来」。
! 真正该拦的只有一种:个人层把「安全相关」的键改宽了。
比如把 agent.auto_commit 从 false 改成 true——那属于权限,不属于偏好。
④ 能力包版本化
--------------------------------------------------------------------
| 项目 | 用的版本 | 锁没锁 | 升级后坏几处 |
|---|---|---|---|
| 服务 A | v1 | 锁 v1 | 0 |
| 服务 B | v2 | 锁 v2 | 0 |
| 服务 C | v1 | 不锁 | 2 |
锁了版本的两个项目,升级到 v2 时一处都不坏;不锁的那个坏 2 处。
! 能力包一旦被两个以上项目用,就必须版本化。版本化不是「好看」,是「让升级这件事变成可选的」。
⑤ 共享什么、不共享什么
--------------------------------------------------------------------
| 共享 | 不共享 |
|---|---|
| 规则文件 | 个人的快捷键和别名 |
| 能力包(带版本) | 本地路径与绝对目录 |
| CI 的检查项 | 个人的登录凭据 |
右边三样有一个共同点:它们换个人就跑不通。换个人跑不通的东西一旦共享,第一个受害的是新同事。
合并表五行要看最后一列。
它跟前面三列一比,你就知道每个值是谁定的——
line_width 是团队定的,indent 是个人定的,linter 谁都没动。
冲突那三行全是「团队盖默认」,这是正常的。
真正要拦的是另一种:个人层把 auto_commit 从 false 改成 true。
它在合并表里显示成「个人盖团队」,性质却完全不同——前者是偏好,后者是权限。
能力包那张表三行,只有第三行坏了。
「不锁」这一行看起来最省事,实际上把「什么时候升级」的决定权交给了别人。
最后那张「共享 / 不共享」的表,右边三行的共同点是「换个人跑不通」。
这个判据比「重不重要」好用——
因为「重要」是主观的,而「换个人能不能跑」一试就知道。
30 秒实验
- 翻你们的共享配置,找出三个绝对路径。 每一个都是一颗留给新同事的雷。
- 数一下你们有几个项目在用同一份能力包。 超过两个而没版本号的,现在加上。
- 检查一下你们的配置里有没有「跳过检查」「自动合并」这类键。 有的话,把它从个人层挪到团队层。
常见误区
- 「所有人用同一份配置最省事。」 省的是维护,贵的是适配。 没有个人层,人要么改团队文件,要么忍着不用。
- 「能力包不用版本号,反正只有一个版本。」 现在是,下个月就不是了。 等第二个项目接入再补版本号,已经有一次坏构建了。
- 「配置里写死路径方便调试。」 你调试方便,别人一跑就报「文件不存在」。 这种错查起来最费劲,因为报错完全不提配置。
自测三问(点开对答案)
1. 三层配置里哪一层不进仓库?为什么? —— **个人层。** **它让人可以为自己调,而调的东西不会污染别人。** 2. 哪种配置个人不能改?判据是什么? —— **会让某道闸门失效的那种,比如自动提交、跳过检查。** **那不是偏好,是权限。** 3. 能力包版本化的真正作用是什么? —— **让「升级」从必然发生变成可以选择。** **不锁版本,升级是被动的。**下一篇讲多人同时改一个仓库:worktree 解决什么,以及异步协作靠什么交接。
- ☐ (本篇完,下一篇 13.3 Worktrees、云任务与异步协作)