Skip to content

release-v0.1.10

Choose a tag to compare

@Moowningstar Moowningstar released this 28 Oct 08:46
· 11 commits to main since this release

0.1.10

0.1.9 让索引说清楚「我知道什么、不知道什么」。0.1.10 做的是另一半:在漂移影响到你之前先说出口——提交时间线终于是一张图、每个提交带着它碰过的文件、被查询的工具会在结果前面加一句实话,CI 也能用一个退出码挡住「索引漏了文件」。

新增

提交时间线是图,不是一列点

0.1.9 的泳道有三个毛病被人一眼看出来:线宽 10px 而点直径只有 6.4px,相邻两列差不到一个点的宽度;颜色编码的是「索引裁决」,于是每条分支都是同一个绿;git log 只走 HEAD,除 merge 外根本没有并行可画。三处一起改:

  • 列宽 14、每列一个固定色(八色调色板),点用自己列的颜色,索引裁决改成点外面的细环——两套语义不再抢同一个通道。
  • --all:时间线读所有 ref,才真的出现并行分支;代价是聚合统计(提交者、改动数)也计入未合并分支,这一点写进了命令注释。
  • 分支名进载荷:解析 %D(HEAD -> main, origin/main, tag: v0.1.9)得到 refs,行内渲染成与列同色的胶囊,HEAD -> 剥成裸分支名,tag: 前缀保留(tag 不是分支)。
  • 超过 6 列折叠:右缘写 +N,数字按本行穿过的被折叠列统计,而不是 laneCount - 6(否则只穿越两条线的行会谎报)。<title> 里仍报真实总数。
  • 悬停一行:该行的线加粗到 2.8px、点放大 0.7px,它穿越的其它列淡到 0.3——在并排三条线时能一眼分清「这条是哪一行」。
  • 曲线用竖直中位控制点的三次贝塞尔,线与点在 6.5px 处留空(DOT_RADIUS + DOT_GAP),不再有线从点中间穿过去。

没有引入图库,理由记在计划文档 §2.1:@gitgraph/core 按「分支从哪个提交创建」分列,用 --all 反推会把主干塞进匿名列;而本插件的客户端构建链没有 bundler,引包只能 vendored 源码。

每个提交带着它碰过的文件,点文件就地看 diff

  • git log 现在多解析 %P(父提交)与 --numstat 的逐文件增删,每个提交带 changed: [{ path, insertions, deletions }],在解析处按 40 个封顶(COMMIT_FILE_LIMIT),超出的提交标 filesTruncated,面板写「仅列出前 40 个文件(共 N 个)」。
  • 点提交展开文件列表,再点某个文件,就地复用已有的 DiffView 渲染补丁——走的是 0.1.8 就有的 /api/gitnexus/file-diff 路由,没有新路由、没有新的写路径。宿主不认识这条路由时,面板明说「当前宿主没有文件改动路由;重启 DSH 后再试」,不伪装成空 diff。

「更多」不是「最多看到前几个」

四个文件列表各自记住翻到哪(基线 8、频繁 8、最近 5、缺失 8,每次 +25),提交时间线一次 15 条、每次 +50,尾部按钮写清还剩多少。翻页状态按列表分开存,切列表不会互相重置。

索引落后时会先说话(面板与三个工具)

一句话由 describeStaleness() 生成,面板与工具共用同一套规则:

  • 干净就一个字都不说:needsRefresh === false 且 certain === true 才返回 null。截断过的「干净」不算干净,会走第三类。
  • 落后就说清楚:「索引落后:自 99c1e78 起 16 个文件已改(14 改 / 2 增 / 0 删),以下结果可能过期;建议增量刷新。」
  • 无法确认单独措辞:「索引新鲜度无法确认…;以下结果可能过期。」unknown 不借用「落后」这句话——否则用户会去刷新一个本来没问题的索引。

gitnexus_impact / gitnexus_context / gitnexus_query 的返回顶部会带上这句(5 秒 TTL,失败静默;工具本身从不为测新鲜度而变慢);面板把它画成图卡片顶部的一条窄提示。老宿主根本不发这个字段,所以客户端把「缺席」当作 null:宁可安静,也不误报。

CI 能挡住「索引漏了文件」

gitnexus-coverage 新增两道门,与原有的 --fail-on-large 分工:

开关 命中 退出码
--fail-on-uncovered 扫描选中但索引里没有的文件 3
--fail-on-missing 没有索引、索引指向已删文件、目标分析不了 3
--fail-on-large 有文件因体积上限被跳过(原有) 2

2 说的是「索引有一个记录在案的洞」,3 说的是「索引和检出已经分叉」——两者的处置不同,所以不合并。原因行打到 stderr,--json 仍可被 JSON.parse 直接吃掉,退出码才是契约。裁决本身是纯函数 coverageGateVerdict(),因为一道不能被 import 的门禁就没法被测试。

提交前检查不再被「改动过的脚本文件」卡住

test/run.mjs 的顶层 await 收进 export async function main(),只在作为入口运行时执行。这不是风格问题:detect-changes 把改动行映射到符号,一个整体都是顶层语句的文件没有任何符号区间可落,于是整次检查回 PARTIAL。

修正

  • 「索引不收录这个文件」不再被说成「新增」:git diff --name-status 区分了「仓库刚得到这个文件」与「仓库一直有、索引从来没记过」。像 .gitignore 这类没有扩展名的小文件永远不会进索引,以前每次改动都会让门禁说「1 个新增」,现在归为 excluded 并写清「刷新也不会收录」,needsRefresh 不再被它触发。
  • 临时目录(.tmp-probe/、.tmp-npm-cache/、.tmp-gitnexus-home/)进了 .gitignore:它们会被 delta 引擎当成待索引文件,这正是新鲜度信号承受不起的噪音。

验证

  • npm run check 三套 tsc 全绿;npm test 1254 项(引擎 852 / 插件 81 / 客户端 321),0 failed。
  • 本版的五条提交各自单独 check 过:只 checkout 面板批时 815 / 81 / 307,只 checkout 工具批时 827 / 81 / 310,全绿。
  • 变异测试:把 file-diff 路由字符串改掉一个字并重建,恰好红一条(「opening a file asks the host for that commit and that path」),其余 320 条仍绿——证明点击链的测试真的会失败,而不是永远为真。
  • 索引刷新到 5,352 nodes | 12,420 edges | 115 clusters | 297 flows、121 个文件哈希;门禁 checked 0,detect-changes --scope all 输出 No changes detected,gitnexus-coverage . --fail-on-uncovered --fail-on-missing 退出 0。

已知限制

  • 交互链的自动化用的是自写的迷你渲染器(没有 react-dom,也不打算为测试装一个浏览器):它证明的是数据与状态流,不是像素。
  • 脚本形态的文件(src/bin/*.ts、测试入口)只要改动落在顶层,detect-changes 仍会回 PARTIAL,与索引是否新鲜无关;本版两次撞上都已在提交说明与计划文档 §13.5 里归因。
  • 观感(曲线手感、暗色对比度、窄侧边栏下的拥挤程度)只能靠离线栅格化加人眼,没有自动化。