Skip to content

fix(git): Windows Git Log 提交详情显示完整提交信息 (#771) - #1014

Merged
1lck merged 4 commits into
previewfrom
fix/771-commit-full-message
Oct 1, 2026
Merged

1lck merged 4 commits into
previewfrom
fix/771-commit-full-message

Conversation

@1lck

@1lck 1lck commented Oct 1, 2026 •

Copy link
Copy Markdown
Owner

Closes #771

问题

Windows 的 Git Log 工具窗口选中一个提交后,右侧详情只显示 commit 标题,看不到正文;IDEA 能显示完整的多行提交信息。

根因

Rust Core 读取历史时 --pretty=format: 只取 %s(标题),见 rust/lithe-core/src/git/history.rs 的分页与 cursor 两条路径。Windows 详情面板 git-commit-inspector.tsx 会渲染 commit.description,GitCommit 类型也有这个字段,但它从未被填充,因此正文永远是空的。macOS 详情面板同样只显示 subject,Core 里也没有现成返回正文的能力可以复用。

方案

选中提交时按需读取正文,历史分页保持不变:

  • 历史分页如果带正文,每页 300 条、最多 5000 条,体积会跟着正文成倍增长;而且正文是自由文本,可以包含 %x1f,也可以换行,会破坏现在按行、按 %x1f 解析的流式读取。
  • 已有的 git.commit(单提交查找)本来就有 Windows 分发路由,只需要多返回一个 body 字段,属于增量兼容,现有消费者(macOS GitCommitPayload)会忽略未知字段。

改动

Rust Core

  • rust/lithe-core/src/protocol/contracts.rs:GitCommitLookupResponse 新增 body: String(Git %b:标题段之后的正文,保留内部换行和缩进,去掉末尾空白;只有标题时为空串),并补充 Rustdoc。
  • rust/lithe-core/src/git/mod.rs:
    • commit() 的格式改为 …%s%x1f%D%x00%b。正文放在 NUL 之后,Git 不会在头部字段输出 NUL,所以正文里的 %x1f、CRLF 不会影响头部解析。
    • 新增 --no-show-signature,避免用户开启 log.showSignature 时签名验证输出混入要解析的格式。
    • 新增 parse_commit_lookup(),只按第一个 NUL 切分;改为解析 stdout 而不是 stdout+stderr 合并后的 output,防止 stderr 警告混进正文。
    • 单元测试:fixture 序列化一致性,以及正文中含 \u{1f}/CRLF/只有标题/缺少分隔符时的解析。
  • rust/lithe-core/src/tests/git.rs:新增真实 git 仓库回归测试 git_commit_returns_the_multi_line_body_separately_from_history_pages,用 commit.cleanup=verbatim 构造含缩进、\u{1f}、空行、中文、末尾空行的多行信息,断言 git.commit 返回完整正文、只有标题的提交返回空正文且 decorations 正常,并断言 git.historyPage 仍只返回标题。

共享契约

  • shared/contracts/rust-core-api.md:命令表和 git.commit 说明补充 body 语义,并说明历史分页只带 subject、详情按需读取。
  • shared/fixtures/git/commit-lookup-response-v1.json:新增响应 fixture,Rust 测试会校验它。

Windows 前端

  • windows/tauri/src/features/git/api/git-commits-api.ts:
    • 新增 getCommitDescription(),通过 git.commit 读取正文,走 runGitRead 去重;按 [仓库, hash] 做 200 条 LRU 缓存(commit 对象不可变,正文不会过期);失败时返回 null、记录错误、不写缓存,下次会重试。
    • 新增 withCommitDescription(),补上 description,失败时原样返回只有标题的提交。
  • windows/tauri/src/features/git/components/log/git-commit-details.tsx(新增):把详情区抽成 GitCommitDetails 组件,选中提交时按需加载正文;切换提交后迟到的旧响应会被丢弃;正文使用 whitespace-pre-wrap break-words,保留空行与缩进,长行也能换行。
  • windows/tauri/src/features/git/components/log/git-commit-inspector.tsx:详情面板改为使用 GitCommitDetails,渲染结构和样式不变(只给正文加了 break-words)。
  • windows/tauri/src/features/git/components/log/git-log-tool-window.tsx:右键“复制提交信息”先补正文再复制。之前它也拼了 description,但该字段一直为空,所以只复制了标题。
  • windows/tauri/src/features/git/hooks/use-git-diff-actions.ts:打开提交 Diff 时补正文;Diff 顶部显示 commitDescription。两次异步读取后都检查请求归属,重新选择提交、切换仓库(含 A → B → A)或卸载后忽略旧结果;旧请求也不能清除新请求的加载状态。

测试与矩阵

  • windows/tauri/src/features/git/api/git-commits-api.test.ts:直接读取共享 fixture 作为 git.commit 返回值;覆盖 git.commit 路由与缓存复用、只有标题时为空、失败回退并可重试、已知正文不重复读取。
  • windows/tauri/src/features/git/components/log/git-commit-details.test.tsx(新增,happy-dom):多行正文渲染、切换提交时丢弃迟到的旧正文、读取失败时保留标题。每个查找都由测试显式 resolve,不依赖真实时间。
  • shared/platform-feature-matrix.json 的 git-history 行:补充 Windows 证据路径和“多行正文 / 复制 / Diff 头部”的验证步骤,状态保持 implemented / pending;重新生成 docs/development/platform-parity-matrix.{md,csv}。

与最新 preview 的合并验证(def3e33e)

已合并 preview@18efd31b,解决 Core 提交读取、详情组件及功能矩阵的冲突:保留时区偏移、完整正文、文件预览及双方 CI 测试入口;同步正文 fixture 的 dateUtcOffsetMinutes。合并后 46 个前端相关测试、4 个 Rust 提交读取/时区测试、TypeScript 类型检查、注释/契约/架构/发行目录只读边界与功能矩阵门禁通过。已推送,GitHub 确认 mergeable: true;新提交 CI 另行运行。

Review 修复与验证(49de4c6c,Linux)

本次补齐两个 P2 问题:正文读取增加了等待窗口,需要在打开 Diff 前检查请求是否仍有效;新增 API/详情测试未进入 Windows CI 的显式测试列表。

  • 新增 use-git-diff-actions.test.tsx,覆盖正常正文展示、旧响应晚到、多仓库往返切换与卸载;详情组件测试的 teardown 释放所有未完成请求。
  • Windows CI 增加提交消息测试步骤,运行正文 API、详情组件及 Diff 请求归属测试,生成逐例计时报告。
  • 17 个相关测试通过,新增用例最慢 30ms,HTML/JUnit 已生成。原实现对照:3 个过期请求用例失败,恢复修复后通过。
  • 扩大验证:整个 Git 前端测试集 418 通过、5 失败。原 head a658cd90 同环境对照为 414 通过、同样 5 失败(4 个 Pull dialog 用例及 1 个 workspace commit review 用例),不是本次修复引入。
  • TypeScript 类型检查、Rust Core 注释、共享契约、Windows 架构边界、测试稳定性、发行目录只读边界、功能矩阵与 PR base/head 门禁通过。
  • 本次未启动应用、未重跑完整 Rust/Swift 测试,也未做 Windows/WebView2 手动验收;原 head 的 CI 全部通过,新提交由 CI 再验证。

原实现验证(macOS 本机实际运行)

  • cargo test --manifest-path rust/Cargo.toml -p lithe-core:通过(lib 749 个,以及集成测试)。
  • run-rust-tests-with-timing.mjs --package lithe-core:765 个用例全部通过,3 个新用例分别为 3ms / 3ms / 124ms。
  • ./scripts/verify-rust-core.sh 去掉第一个 node 子测试 scripts/test-rust-core-comments.mjs 后完整跑通(fmt、Rust 测试、Swift bridge、链接符号、Git 执行集成、git-console bridge)。这个子测试会把 PATH 限制到一个临时目录,系统 Ruby 2.6 在那里找不到 uname,属于本机环境问题;preview 上同样失败,脚本本身未改动。
  • ./scripts/verify-rust-core-comments.sh、verify-rust-core-layout.sh、cargo fmt --check:通过。
  • ./scripts/verify-shared-contracts.sh:通过。
  • ./scripts/verify-windows-boundaries.sh:通过。
  • ./scripts/verify-git-graph.sh:通过。
  • ./scripts/verify-runtime-bundle-immutability.sh:通过。
  • ./.agents/skills/write-stable-tests/scripts/verify-test-stability.sh(macos 与 --platform windows):通过。
  • bun run typecheck:通过。
  • bun test ./src/features/git:419 个通过,0 失败;bun test ./src/platform:93 个通过。
  • run-bun-tests-with-timing.mjs -- commit-details commits-api:13 个通过,已生成计时报告。
  • 回归确认:把 GitCommitDetails 临时改回直接读 commit.description 后,3 个新组件测试全部失败;恢复后通过。
  • ./scripts/verify-platform-feature-matrix-change.sh origin/preview HEAD 与 ./scripts/verify-platform-feature-matrix.sh:通过。
  • ./scripts/verify-service-boundaries.sh:因 AppModel+RunConfiguration.swift 616 行超过 600 行阈值而失败。这是 preview 上已有的问题,本 PR 没有改动任何 macOS 文件。

未覆盖

  • 没有在 Windows 真机或 WebView2 上手动验证 Git Log 详情面板、复制和 Diff 头部;矩阵保持 pending。也没有在 Windows 上跑 build-windows.ps1 和 cargo test(windows/tauri/src-tauri 本次没有改动)。
  • macOS 详情面板仍然只显示标题(与修复前一致)。Core 已经能提供 body,macOS 是否跟进显示由维护者决定,本 PR 没有改动 macOS。
  • 选中提交后会多一次 git show -s 读取(有缓存),该读取不在 Git 控制台显示。

🤖 Generated with Claude Code

历史分页只读取 `%s`(标题),Windows 详情面板虽然会渲染
`commit.description`,但该字段从未被填充,导致只能看到标题。

- Rust Core `git.commit` 额外返回 `body`(Git `%b`)。正文放在 NUL
  之后,不会和 `%x1f` 分隔的头部字段冲突;同时加 `--no-show-signature`
  防止签名输出混入。历史分页契约保持不变。
- 共享契约和新增 fixture `commit-lookup-response-v1.json` 记录 `body`。
- Windows 选中提交时按需读取正文(缓存 200 条),并忽略过期的响应;
  复制提交信息、打开提交 Diff 时同样带上正文。
- 详情区抽成 `GitCommitDetails` 组件,补充 Rust 与 bun 回归测试,并
  更新平台功能矩阵。

Co-Authored-By: Claude <noreply@anthropic.com>
@ghfind-review ghfind-review Bot added the review: high ghfind author score; see https://ghfind.com label Oct 1, 2026
1lck and others added 3 commits October 1, 2026 16:54
Windows 消费者测试直接读取 commit-lookup-response-v1.json,确保两端
对 git.commit 的 body 字段使用同一份契约样例。

Co-Authored-By: Claude <noreply@anthropic.com>
Guard both asynchronous reads against replaced requests, repository changes and unmount. Preserve the current loading state, settle test continuations, and run the commit API, details and diff ownership regressions in Windows CI.
@1lck
1lck merged commit 006449b into preview Oct 1, 2026
14 of 17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

review: high ghfind author score; see https://ghfind.com

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant