仓库迁到 Scion 之后,最容易返工的不是迁移动作本身,而是两件被当成习惯带过去的事:合并冲突在哪里解决、由谁解决;以及谁能写主分支。开始迁正式仓库前,先在一个副本仓库把这两件事各演练一次,把规则写成团队能复述的清单,比迁过去之后再回头改流程便宜得多。下面所有操作都建议在副本上做,如果团队客户端仍走 git 协议,命令可以直接照搬;如果 Scion 把合并放在网页上完成,把命令换成页面上对应动作,观察点不变。
迁到 Scion 后先别急着搬正式仓库:在副本上人为造一次冲突,记录冲突标记、状态命令和冲突文件列表出现的位置;再确定解决顺序与提交前的最小检查(标记已解决、确认未合并项清空、跑最小构建或单测)。权限上分清只读、可提交、可合并三类角色,并用一个只读测试账号对主分支做一次越权推送,确认拒绝提示与日志记录位置。任何一条在副本里走不通,先修规则再迁移。
在副本上人为造一次冲突
冲突规则只有落在真实仓库现场才有意义。用副本仓库建一条实验分支,让两个分支改同一行,是成本最低的造冲突方式。操作顺序建议固定为:从副本拉取、在分支 A 改某一行并提交、从主干再切分支 B 改同一行并提交、回到分支 A 去合并 B。顺序反过来也能造冲突,但先固定一种,团队复述时才不会各说各的。
git clone <副本仓库地址> scion-conflict-lab
cd scion-conflict-lab
git switch -c lab/a
# 修改 README 中同一处内容(例如第 3 行)
git commit -am 'lab/a: 改第 3 行'
git switch main
git switch -c lab/b
# 修改 README 第 3 行为另一段内容
git commit -am 'lab/b: 改第 3 行'
git switch lab/a
git merge lab/b
冲突出现时通常能看到三个信号:终端提示 CONFLICT (content) 并说明自动合并失败;合并停在未完成状态,不会自动产生新的提交;工作区文件里插入冲突标记,状态命令显示该文件处于双方都修改的状态。如果分支 B 那次提交没有落在同一行,常见结果是自动合并成功而没有冲突,这时回到副本把两边改成完全同一行重做一次,不要拿一个没触发冲突的现场去定规则。
记录冲突现场能看到的信息
确认工具给出的信息够不够判断下一步。冲突标记的形态通常是这样,默认只有三方分界,打开 merge.conflictstyle=diff3 后会多出一段共同祖先内容,判断谁改了什么会更清楚:
<<<<<<< HEAD
分支 A 的内容
=======
分支 B 的内容
>>>>>>> lab/b
状态命令的输出要单独记一次,它决定了后面怎么确认冲突已清空。git status `--short` 里冲突文件通常显示为 UU 或 AA,普通修改显示为 M;git ls-files -u 会直接列出未合并的路径,没有输出就表示没有未合并项。冲突文件列表在三个地方出现:命令行的合并输出、状态命令的未合并区、以及网页端合并请求的变更文件列表页(如果有)。把这三处截图或记录进团队说明,后面判断“冲突是否真的处理完”就不用靠猜。
确定解冲突的顺序与提交前的最小验证
解冲突要从个人习惯变成可复述的流程。建议顺序为:先看冲突范围有多大、再决定由谁解、解完后用命令标记已解决、最后跑最小检查再提交。谁解这件事本身要写清楚——改同一行的两个人之一优先,跨模块冲突由合并请求发起方解,主干公共文件的冲突由维护者解,避免出现“都以为对方会解”。
- 解决内容后用
git add <文件>把文件标记为已解决,不要用提交动作代替标记。 - 用
git ls-files -u确认未合并项已清空,用git status `--short`确认不再出现UU这类标记。 - 用
git diff `--check`看是否有残留冲突标记或空白错误,再全文搜一遍分界线。 - 跑最小检查:能构建就跑一次构建,有单测就跑受影响的测试集,至少保证合并后的文件不是语法残缺状态。
- 提交信息里写清解决方式,例如“合并 lab/b:保留 A 的接口说明,删除 B 的重复段落”。
grep -rn '<<<<<<<\|^=======$\|>>>>>>>' .
git diff `--check`
git ls-files -u
git status `--short`
这四步在任何一次冲突后都应该能跑通。如果某一步在副本里报错或输出不符合预期,说明规则还没定完,别把这套流程带进正式仓库。
梳理主分支的写入权限层级
把角色分成只读、可提交、可合并三类,实际差别在于对主分支的写入能力,而不是头衔名称。只读角色能拉取和查看;可提交角色能推送自己的分支、发起合并请求,但推不动主分支;可合并角色能批准或直接写入主分支。检查位置通常在仓库设置页的分支保护规则、成员与角色管理页、以及合并请求页面上的按钮状态三处,具体入口名称需要按 Scion 实际页面确认。
- 只读:在成员页确认角色,再在客户端试一次向主分支推送,预期被拒绝。
- 可提交:确认能创建自己的分支并推送,确认合并请求能发起但合并按钮不可用或需他人批准。
- 可合并:确认分支保护规则里该角色在允许名单内,确认强制检查项(例如必过的检查任务、必填的评审)没有被该角色绕过。
角色变更后需要重新确认的项:默认分支是否仍在保护规则覆盖范围内、保护规则是否对某些角色设置例外、合并必过检查是否还开着、机器人和服务账号的凭据范围是否跟着变了。这些都要在副本仓库里看得到、点得到,不能只停留在文档描述上。
用一次越权操作验证权限是否真的生效
规则写在页面上不等于生效。用一个只有只读权限的测试账号登录,在副本仓库对主分支做一次明确的越权动作,看系统怎么拒绝。建议用空提交探测,避免真的改动内容:
git switch main
git commit `--allow-empty` -m '权限探测:只读账号尝试写主分支'
git push origin main
预期被拒绝的表现形态通常有三种:命令以非零状态退出并提示权限不足或分支受保护;网页端合并按钮置灰或点击后弹出拒绝提示;推送被接受但被转到新分支或进入待评审状态(不同工具行为不同,需要按实际返回判断)。查看拒绝记录的位置一般是客户端输出、页面上的操作记录或审计日志页,如果团队能访问服务端访问日志,也可以在日志里按账号和时间找到这次请求。
探测完必须确认主分支没有被写入任何东西,用 git log origin/main -1 对比探测前的提交号即可。如果越权操作意外成功,说明保护规则没有覆盖到这个账号或这条路径,先修规则再迁移正式仓库;如果拒绝提示含糊到看不出原因,把提示原文记进团队说明,让后来者不用重复试错。