Commit Graph

2 Commits

Author SHA1 Message Date
77be044c44 fix(versioning): 修复首改文件 diff 基准丢失导致全文件计新增
根因:track_edit 在编辑前备份的 v1(修改前内容)只存在于该消息的
中间行,make_snapshot 用最终行(v2 修改后内容)整体替换该行后,
v1 不再被任何快照引用。对会话中首次被跟踪的文件,diff 配对找不到
上一条消息里的基准,按 added 处理并把全文件计为新增(+479 -0)。
26f31a09 修的是重复行配对,未覆盖这一数据丢失路径,故跨平台复现。

修复(不改数据模型,纯读取侧恢复):
- 新增 _resolve_diff_base_backup:优先用上一条消息快照里的备份;
  缺失时利用备份名确定性(sha256(绝对路径)@vN)与版本逐文件连续的
  不变量,回退到 v(N-1) 作为消息前状态(新建文件 v1 不落盘,自然
  仍判 added);首次出现即 v1 说明消息未改动该文件,与自身比较得 0。
- get_diff_stats / get_file_diff_stats / get_file_patch_lines 三处
  统一走该解析;旧 state 数据(v1 备份文件仍在)透明愈合,亦兼容
  MAX_SNAPSHOTS 逐出旧行的场景。
- 新增 5 个回归测试(生产顺序:track_edit 先于写入);修正 2 个旧
  测试的模拟顺序使其与生产一致(原顺序先写后 track,把新建文件
  误模拟成 v1 首现)。

验证:11/11 通过;旧代码跑新测试 4/5 失败(复现);用事故对话
conv_20260731_114736_581 真实数据只读复算,#1 由 +479/-0 added
修正为 +4/-1 modified(与实际编辑一致),#2 保持 +0/-0;全量测试
失败/错误数与 HEAD 基线完全相同(2+10,均为预存在/环境问题)。
2026-07-31 04:39:35 +00:00
26f31a09ec fix(versioning): 修复 shallow 快照日志重复行导致的 diff 配对错误
根因:state.jsonl 采用只追加日志,track_edit 的中间半成品快照与
make_snapshot 的完整快照各自成行;加载时每行都被回放为独立快照,
_find_snapshot_pair 简单取下标-1 作为上一快照,导致 diff 基准落在
同一条消息自己的半成品行上——半成品中缺失的已跟踪文件被全部判为
added 并按全文件计新增(如 +1928 -0)。

彻底修复(非补丁):
- 持久化改为原子全量重写(temp + os.replace),结构性保证磁盘上
  一条 message_id 永远只有一行
- _load_state 幂等重载并在加载时折叠历史重复行(保留每消息最后一行),
  旧脏数据无需迁移即可透明愈合
- track_edit / make_snapshot 在按 state 文件加锁的临界区内执行
  重载->变更->保存,避免短生命周期实例间丢行
- _find_snapshot_pair 防御性跳过同 message_id 行
- 新增 6 个回归测试(test/test_shallow_versioning.py)

验证:新测试 6/6 通过;test_server_refactor_smoke 6/6 通过;
用 conv_20260721_175016_796 真实数据只读复算,seq8 由 +1295/-0
修正为 +796/-7(3 文件),seq10 由 +1928/-0 修正为 +592/-3(4 文件),
seq31 与历史正确记录 +482/-1 完全一致。
2026-07-22 15:48:11 +08:00