From 9d7005516a85b2bbc2675cf19b8aaac08fe45cda Mon Sep 17 00:00:00 2001 From: ThreeFish Date: Sat, 4 Jul 2026 00:59:04 +0800 Subject: [PATCH] =?UTF-8?q?refactor(CommitLog):=20=E7=A7=BB=E9=99=A4=20CHA?= =?UTF-8?q?NGES=20=E8=A7=86=E5=9B=BE=EF=BC=8C=E6=95=B4=E5=90=88=E6=8F=90?= =?UTF-8?q?=E4=BA=A4/=E6=97=A5=E5=BF=97=E8=83=BD=E5=8A=9B=E5=B9=B6?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E7=9B=AE=E5=BD=95=E6=A0=91=E5=88=87=E6=8D=A2?= =?UTF-8?q?=E4=B8=8E=E6=82=AC=E6=B5=AE=E8=AF=A6=E6=83=85;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 视图整合:删除 CHANGES 树(changes-tree.ts),文件列表/单文件右键菜单/changelist 切换与管理/标题栏 Git 操作/未提交角标全量平移入 Commit webview;commands.ts 命令实参统一为 ChangeItem|path,由 resolveChange 回落 service.getChanges() 解析(单一事实源);package.json 视图与菜单迁移至 view==hyperGit.commit,移除 hyperGit.changes。 - 目录树切换:新增 engine/tree/file-tree.ts(compact 折叠、目录优先+数字感知稳定排序、叶子 fileIndex 回指扁平 files[]),Commit 与 Log 文件列表支持平铺↔树形切换,切换/折叠零 host 往返,偏好按视图各自记忆;新增 file-tree.test.ts(15 用例)。 - 提交悬浮详情:Log 行悬停展示本地/远程分支、标签、HEAD、完整消息(subject+body)、作者、(异于作者时的)提交者、绝对+相对时间、完整 SHA;LOG_GRAPH_FORMAT 扩展 %cn/%cI/%b(%b 置末字段,RS/NUL 边界),host 侧 capBody 截断控 1000 行 payload;与 CI 浮层互斥,滚动/重绘自动消隐,i 键开 Esc 关。 - 评审修复:提交浮层 mouseleave 复位 overCtRow,避免「行→浮层→空白」后浮层卡死;capBody 改用 Array.from 按码点截断,避免劈开 Unicode 代理对产生孤立代理位。 - 文档:新增三份特性文档(commit-view-consolidation / file-list-group-by-directory / log-commit-tooltip),更新 CHANGELOG、issue、knowledge-map。 🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist) Co-Authored-By: Aurelius Huang --- CHANGELOG.md | 11 + docs/.agents/issue.md | 2 +- docs/.agents/knowledge-map.md | 3 + docs/features/commit-view-consolidation.md | 37 ++ docs/features/file-list-group-by-directory.md | 42 ++ docs/features/log-commit-tooltip.md | 41 ++ package.json | 87 +--- src/adapter/commands.ts | 82 ++-- src/adapter/tree/changes-tree.ts | 120 ------ src/adapter/webview/commit-webview.ts | 385 +++++++++++++++--- src/adapter/webview/log-webview.ts | 221 +++++++++- src/engine/log/log-line.ts | 22 +- src/engine/scm-mapping/status-decoration.ts | 3 +- src/engine/tree/file-tree.ts | 106 +++++ src/extension.ts | 34 +- src/shared/protocol.ts | 56 ++- tests/unit/file-tree.test.ts | 128 ++++++ tests/unit/log-line.test.ts | 54 ++- tests/unit/log-query.test.ts | 2 +- 19 files changed, 1094 insertions(+), 342 deletions(-) create mode 100644 docs/features/commit-view-consolidation.md create mode 100644 docs/features/file-list-group-by-directory.md create mode 100644 docs/features/log-commit-tooltip.md delete mode 100644 src/adapter/tree/changes-tree.ts create mode 100644 src/engine/tree/file-tree.ts create mode 100644 tests/unit/file-tree.test.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 2bc88f3..6e987bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,17 @@ ## [0.0.7] - 未发布 +### Added +- **变更文件目录树切换**:Commit 视图活动 Changelist 文件列表、Log 视图选中提交的变更文件列表均支持「平铺 / 按目录分组(Group by Directory)」两态切换(工具栏 List/Tree 段控),偏好按视图 `webview.setState` 记忆。目录树由纯逻辑 [`engine/tree/file-tree.buildFileTree`](./src/engine/tree/file-tree.ts) host 侧构建随 payload 下发(复用 graph-layout「host 算、webview 渲」范式,规避内联脚本无法 import engine 的 Split-Brain),叶子以 `fileIndex` 回指扁平列表;支持单目录子链折叠(对齐 VS Code `explorer.compactFolders`);Commit 树形附目录级三态复选框。详见 [变更文件目录树](./docs/features/file-list-group-by-directory.md)。 +- **Log 提交悬浮详情**:鼠标悬停 Log 提交行以浮层展示完整信息——所在本地/远程分支、标签、HEAD、完整提交消息(subject + body)、作者 `name `、(与作者不同时)提交者、作者/提交时间(绝对 + 相对)、完整 SHA;复用 CI 状态浮层范式(置于虚拟滚动容器外、与 CI 浮层互斥),`i` 键开、`Esc` 关,滚动/刷新自动消隐。`git log` 取数扩展 `%cn/%cI/%b`(body 置末,NUL/RS 分隔容多行),正文上限截断以控 payload。详见 [Log 提交悬浮详情](./docs/features/log-commit-tooltip.md)。 + +### Changed +- **Commit 视图承接全部变更管理能力**(原 Changes 视图平移):活动 Changelist 文件单击看 Diff、右键(原生 QuickPick)执行 移动到 Changelist / 查看历史 / 暂存·撤销 Hunks / 加入 `.gitignore` / 丢弃改动;头部提供 Changelist 切换下拉 + ⋯ 管理菜单(新建 / 重命名 / 删除)。 +- **Git 操作工具栏与未提交数角标迁至 Commit 视图**:原挂在 Changes 视图标题栏的 refresh / push / pull / fetch / patch 等动作迁到 Commit 视图标题栏(去掉与 webview 内按钮重复的 commit / commitAndPush);活动栏未提交数角标改由 Commit `WebviewView.badge` 承载,首帧未 resolve 以 `pendingBadge` 兜底。详见 [Commit 视图整合](./docs/features/commit-view-consolidation.md)。 + +### Removed +- **移除 CHANGES 树视图**:其展示的活动 Changelist 与 Commit 视图的 Active Changelist 完全重复(同源 `getChanges()` + `getGroups()`);全部独有能力已零回归平移入 Commit 视图(见 Changed),视图数由 7 降为 6。 + ### Fixed - 修复 `vsce package` 打包因 ESLint `no-useless-assignment` 阻断:`engine/ci/remote-parser.ts` 中 `host`/`path` 的空串初值为 dead store(`hasScheme` 真假两分支均无条件重赋、解析失败处先 `return null`),改为带类型标注的纯声明消除,由 TS 确定赋值分析接管,运行时行为不变。 diff --git a/docs/.agents/issue.md b/docs/.agents/issue.md index 4cadad8..3f04e62 100644 --- a/docs/.agents/issue.md +++ b/docs/.agents/issue.md @@ -67,7 +67,7 @@ - **表因**:用户截图反馈 Branches 视图中一组功能/工作分支无法框选多个、无法批量删除。 - **根因**:`hyperGit.branches` 经 `vscode.window.registerTreeDataProvider` 注册——该 API **不支持** `canSelectMany`,故视图天然单选;所有分支命令处理器亦只接收单个 `BranchNode`。多选能力(`canSelectMany: true`)仅 `createTreeView` 的 `TreeViewOptions` 支持。 - **处理方式**:改用 `createTreeView('hyperGit.branches', { treeDataProvider, canSelectMany: true })`(句柄入 subscriptions)。批量命令处理器签名扩展为 `(clickedNode, selectedNodes[])`——VS Code 多选树的 `view/item/context` 命令第 2 实参即完整选区数组。新增纯逻辑 `engine/ref/selection.collectBranchRefs`(谓词过滤 + shortName 去重 + 「点击在选区之外则以点击项为准」)与 `engine/ref/cleanup.partitionByMerged`/`formatBranchDeleteConfirm`,使 `branchDelete`/`tagDelete`/`copyBranchRef`/`toggleFavorite` 批量化(删除仅一次 `git branch --merged` 分类、汇总成功/失败、末尾单次刷新)。`package.json` 对仅单目标命令(检出/合并/变基/重命名/比较等)追加 `&& !listMultiSelection` 在多选时隐藏。 -- **后续防范**:① 需要承载 `.badge` 或 `canSelectMany` 等 `TreeViewOptions` 能力的视图,一律用 `createTreeView` 而非 `registerTreeDataProvider`(本仓 `hyperGit.changes` 已有先例)。② 多选命令正确性**只依赖处理器读取实参**(`clickedNode` + `selectedNodes[]`),不得依赖 `listMultiSelection` 上下文键——其对**自定义贡献视图**的可靠性无法确证,仅作菜单整洁的视觉优化;单目标命令因只读 `clickedNode` 即便该键失效仍安全。③ 「右键点击选区之外」须以点击项为准(手势目标优先),由归一化助手统一兜底。 +- **后续防范**:① 需要承载 `canSelectMany` 等 `TreeViewOptions` 能力的 **TreeView**,一律用 `createTreeView` 而非 `registerTreeDataProvider`(本仓 `hyperGit.branches` 即此);`.badge` 则 `TreeView` 与 `WebviewView` **均支持**——`hyperGit.changes` 视图移除后(其活动 Changelist 与 Commit 视图重复),未提交数角标已迁至 Commit `WebviewView.badge`,注意 `WebviewView` 仅在 `resolveWebviewView` 后可置 badge,需 `pendingBadge` 兜底首帧未 resolve 的时序。② 多选命令正确性**只依赖处理器读取实参**(`clickedNode` + `selectedNodes[]`),不得依赖 `listMultiSelection` 上下文键——其对**自定义贡献视图**的可靠性无法确证,仅作菜单整洁的视觉优化;单目标命令因只读 `clickedNode` 即便该键失效仍安全。③ 「右键点击选区之外」须以点击项为准(手势目标优先),由归一化助手统一兜底。 - **同类问题影响**:所有以 `registerTreeDataProvider` 注册却后续需要多选/角标的自定义 TreeView;以及误把单目标命令在多选下直接作用于「点击项」造成的隐性误操作。 ## #9 LOG 视图残留「已删分支」提交(实为工具注入的内部引用污染 `git log --all`) diff --git a/docs/.agents/knowledge-map.md b/docs/.agents/knowledge-map.md index dff7a5c..17f6384 100644 --- a/docs/.agents/knowledge-map.md +++ b/docs/.agents/knowledge-map.md @@ -17,6 +17,9 @@ ## 项目文档(docs/) - [文档中心](../docs/README.md) — 文档与调研资产总索引。 - [Log 视图 CI 状态](../docs/features/log-ci-status.md) — 按提交显示 GitHub CI 最终状态(绿勾/红叉 + Tooltip 明细):认证、限流、懒加载、边界与配置。 +- [Commit 视图整合](../docs/features/commit-view-consolidation.md) — 移除 CHANGES 视图,其文件操作/changelist 管理/Git 工具栏/未提交角标零回归平移入 Commit 视图。 +- [变更文件目录树](../docs/features/file-list-group-by-directory.md) — Commit / Log 文件列表「平铺 ⇄ 按目录分组」切换:host 侧 `buildFileTree` 构树下发、compact 折叠、目录三态。 +- [Log 提交悬浮详情](../docs/features/log-commit-tooltip.md) — 悬停提交行浮层展示 分支/标签/HEAD/完整消息/作者·提交者/时间/SHA;复用 CI 浮层范式、与其互斥。 - [实施状态总览](../docs/milestones/implementation-status.md) — M0-M5 交付记录 + API 限制 + M5 AI 设计 + 验证/发布(**实施看板**)。 - [工程实施方案](../docs/architecture/engineering-plan.md) — 路径 B 架构 + M0-M5 里程碑(**开发蓝图**)。 - [Git 功能矩阵](../docs/requirements/idea-feature-matrix.md) — 56 功能点 / 8 组(**验收基线**,参考 IDEA 等成熟实现)。 diff --git a/docs/features/commit-view-consolidation.md b/docs/features/commit-view-consolidation.md new file mode 100644 index 0000000..e3ec225 --- /dev/null +++ b/docs/features/commit-view-consolidation.md @@ -0,0 +1,37 @@ +# Commit 视图整合(移除 CHANGES,能力全量平移) + +> CHANGES 树视图与 Commit 视图顶部的「Active Changelist」展示同一份数据(同源 `service.getChanges()` + `registry.getGroups()`),属冗余。现移除 CHANGES 视图,其**全部独有能力零回归**平移入 Commit 视图,侧边栏视图数由 7 降为 6。 + +## 平移清单(零功能回归) + +| 原 CHANGES 能力 | 迁入 Commit 视图后的形态 | +|---|---| +| 文件单击看 Diff | 文件行单击(勾选框除外)→ `commit/openFile` → 复用 `hyperGit.openDiff` | +| 单文件右键菜单 | 文件行右键 → `commit/fileMenu` → 原生 `showQuickPick`:Open Diff / Move to Changelist… / Show History / Stage·Unstage Hunks… / Add to .gitignore / Discard Changes(复用既有命令,含 discard 确认框) | +| Changelist 管理 | 头部 `