SDD 工程要求¶
这一页解释的是这个项目的工程红线。这里的 SDD 不是一句口号,而是要求规格、设计、开发、测试和安全边界同步推进。
对一个 Git 复现项目来说,这一点非常现实。因为它会做这些事情:
- 写对象;
- 改 refs;
- 重写 index;
- checkout 工作区;
reset --hard;- 删除文件;
- 处理冲突;
- 解包 pack;
- 改写远端状态。
如果没有强工程约束,这类项目最容易出现“功能看起来能用,但某个边界条件会直接损坏仓库或误删文件”的问题。
SDD 在这个项目里是什么意思¶
在这里,任何功能都不应该只从“代码写出来了”这一个角度算完成。它至少要同时具备五个维度:
- 规格清楚;
- 设计清楚;
- 代码实现清楚;
- 测试清楚;
- 安全边界清楚。
只满足其中一两个维度,不算真正完成。
先规格,后编码¶
一个功能动手之前,至少要回答这些问题:
- 输入是什么;
- 输出是什么;
- 读哪些
.pygit文件; - 写哪些
.pygit文件; - 会不会改工作区;
- 失败时怎么处理;
- 需不需要回滚;
- 兼容性目标是什么。
对于 Git 这类状态系统,如果这些问题不先写清楚,后面实现时就会把假设藏进代码里,越来越难改。
设计原则不是摆设¶
项目明确要求:
- 遵循 SOLID;
- 遵循 DRY;
- 危险逻辑集中复用;
- 二进制格式逻辑不能被随意抽象到看不清字节布局的地步;
- 依赖方向清晰,底层模块不要反向依赖 CLI 编排层。
这些要求的目的不是让代码看起来“像大厂风格”,而是让对象、index、refs、merge、pack 这类核心模块保持可审计、可替换、可测试。
测试要求¶
这个项目的测试目标不是刷覆盖率,而是证明仓库状态真的正确。
测试范围应覆盖:
- 对象库;
- Index V2;
- refs;
- 管道命令;
- 瓷器命令;
- merge;
- pack;
- remote;
- 异常路径;
- 回滚和半失败状态。
只测 happy path 是不够的。对于会修改磁盘状态的命令,至少要测:
- 成功路径;
- 失败路径;
- 失败之后仓库有没有保持一致。
为什么强调 no mock¶
这个项目明确要求:核心 Git 行为的测试不能靠 mock 冒充。
原因不复杂。项目声称自己实现的是:
- 真实对象;
- 真实 index;
- 真实 refs;
- 真实工作区改写;
- 真实 merge 冲突;
- 真实 pack 和传输行为。
如果测试里把这些东西都 mock 掉了,那么测试通过只能说明“假对象配合得不错”,不能说明仓库真的工作。
危险指令安全要求¶
危险操作包括但不限于:
- 删除工作区文件;
reset --hard;checkout/switch重写文件;rm;stash pop;- 改写分支或标签;
- pack 解包;
- 远端同步对目标目录和 refs 的改写。
这些操作都必须保证:
- 目标路径在仓库内部;
- 防住
..; - 防住绝对路径逃逸;
- 防住符号链接逃逸;
- 防住平台路径分隔差异;
- 不能误删未追踪用户文件;
- 在真正删除旧文件之前,先确认目标对象、tree、commit 都可读。
本机保护要求¶
这个项目默认把运行环境当成用户真实电脑,而不是临时容器。
所以默认策略必须保守:
- 不能递归清理仓库外目录;
- 不能把用户家目录、桌面、下载目录之类当成可误操作范围;
- 目录清理只能针对明确可解释的追踪路径;
- 危险测试必须在临时目录中做。
数据一致性要求¶
index、refs、配置文件、pack 相关元数据写入都应该通过锁文件或临时文件,再用原子替换落盘。
对象写入也应遵循这个原则:先完成校验,再进入正式路径。
如果写入中断,不能把正式文件留下一个半写入状态。
中文注释要求¶
项目还明确要求 Python 源码使用充分中文注释:
- 文件开头写意图;
- 函数写职责、参数、返回值、副作用和异常;
- 复杂判断、二进制布局、关键边界和兼容性规则写清楚中文解释。
这是因为 Git 复现项目里有大量“当时写的人懂、几周后自己都容易忘”的逻辑,不能靠默认记忆维持。
提交质量要求¶
commit 也属于工程要求的一部分:
- 一次提交只解决一个明确问题;
- commit 信息使用中文;
- 不能只写“改了什么文件”,要说明为什么改;
- 只要涉及安全边界、数据一致性、危险操作或二进制格式,提交说明就必须更详细。
在这种项目里,模糊 commit 不是小问题。它会直接降低后续排错和审计效率。