Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,40 @@

## [Unreleased]

### Fixed

- **Merge 编辑器「保存→拒绝强制保存→取消」路径失效**:webview 回调内重复调用 `acquireVsCodeApi()`(每个 webview 仅允许调用一次,第二次抛异常),改为脚本顶部获取后全程复用;交互式 Rebase 确认执行同理([issue #17](./docs/.agents/issue.md))。
- **Commit 草稿丢失**:视图隐藏销毁后 message/amend/signoff/skipHooks 全部丢失且模板重灌覆盖。webview state 升 v3 按仓库持久化草稿,输入即时落盘(消除 200ms 防抖尾丢),提交成功清空([issue #18](./docs/.agents/issue.md))。
- **切换深浅主题后 Graph 泳道色/引用胶囊停留旧主题**:泳道色原为启动期一次性快照,补 `MutationObserver` 监听 body 属性热重算并重渲(webview 不随主题切换重载)。
- **分支树文件夹节点出现分支级菜单**:11 处 `viewItem =~` 正则未锚定误匹配 `hyperGit.branchFolder`(含 `hyperGit.branch` 子串),全部补 `^…$` 锚定。
- **CLI 通道失败不可诊断**:`execFile` 丢弃 stderr,现透传挂到错误对象并记入 Console(与 vscode.git API 通道的 GitError.stderr 提取对齐)。
- **交互 Rebase 的 reword 可能拉起新 VS Code 窗口**:`GIT_EDITOR` 经 `process.execPath`(扩展宿主内为 Electron 二进制)运行 helper,补 `ELECTRON_RUN_AS_NODE=1`。
- **窗口 reload 后 Rebase / Merge 面板空白**:两个 `retainContextWhenHidden` 面板补 `registerWebviewPanelSerializer`(Rebase 按 webview state 恢复用户编辑后的 todo,Merge 按 filePath 重拉冲突三阶段)。
- **git 扩展不可用时 Branches/Stash/Shelf 视图报 "no tree view registered"**:补空 provider(viewsWelcome 正常触发),Commit/Graph 渲染静态占位说明页。
- **Blame 注解**:悬浮信息换行折叠(改 MarkdownString);split 编辑器无注解、已关闭文档条目泄漏(订阅可见编辑器变化统一挂载/清理)。

### Added

- **长时 git 操作进度反馈**:pull/push/fetch/merge/rebase/cherry-pick/reset/updateProject 等以 `withProgress` 呈现(默认标题栏非阻塞,Update Project 与交互 Rebase 用通知位);git 操作失败通知附 "Show Output" 按钮直达 Console。
- **入门导览与默认键位**:新增 `walkthroughs` 贡献点(Get Started with Hyper Git,5 步导览);默认键位 Alt+B 切换 Blame 注解、Alt+G 打开 Graph 过滤(Commit 输入框 Ctrl/Cmd+Enter 提交原有内建保留)。
- **Stash / Worktrees 批量操作**:两视图启用多选(批量 Drop 按 index 降序防位移、批量 Remove 跳过 main/当前打开项);新建 stash/worktree/shelf 后聚焦对应视图;provider 加载失败经 `TreeView.message` 内联呈现。
- **分支/标签名即时校验**:新增 `engine/ref/ref-name.validateRefName` 纯函数(git check-ref-format 的 UI 子集,9 组单测矩阵),挂接全部 8 处分支/标签名输入框。
- **QuickPick 体验**:提交选择器补 `matchOnDescription/matchOnDetail`(hash 前缀可搜);Rebase base 与标签目标选择插 `QuickPickItemKind.Separator` 分段;Commit 文件菜单补 `$(codicon)` 图标。
- **Commit 文件列表键盘导航**:容器级焦点 + ArrowUp/Down/Home/End/Enter/Escape(复刻 Graph 模式);Rebase 拖拽补 Alt+↑/↓ 键盘替代,确认层补 Escape/焦点圈禁/焦点还原。

### Changed

- **Webview 控件全面主题化**:滚动条走 `--vscode-scrollbarSlider-*`、checkbox `accent-color`、下拉统一 `--vscode-dropdown-*`(`.hg-select` 基类)、阴影 `--vscode-widget-shadow`;字号全线以 `--vscode-font-size` 为基准 calc 派生(随用户字号设置缩放);高对比度主题下 Graph 彩色胶囊改描边呈现;Graph 行高/泳道列宽常量单源化。
- **文件状态点改字母标记**:Commit 视图 `●` 色点改为 M/A/U/R/D/C 着色字母(色盲可辨,对齐官方 SCM 与 Graph 面板);8 处 Unicode 字符图标全部 SVG 化(折叠箭头/省略号/关闭/导航/空态/merge 标记)。
- **日志通道现代化**:两 OutputChannel 迁 `LogOutputChannel`(自动时间戳与级别、统一日志视图),懒创建并随扩展释放。
- **确认对话框多行正文迁 `MessageOptions.detail`**(本地/远程分支删除、Worktree 删除/prune);用户可见文案统一英文(分支删除确认、Conventional Commits 校验提示)。
- **能力声明与设置治理**:补 `extensionKind: workspace` 与 `untrustedWorkspaces: unsupported`;11 项设置补 `scope`;5 个预留设置(`ai.enabled` + `agent.*`)描述标注 Reserved 且默认值清除个人化内容(**默认值变更**:agent 偏好默认由内置模板改为空,即内置默认——此前内嵌个人签名等内容不再分发);palette 补 when 限定(Graph scope/List-Tree 切换、Accept Ours/Theirs 按冲突态显隐)。
- **同步 IO 清理**:Shelf 服务全量迁 `fs.promises`(原 `listShelves` 同步读阻塞 UI 线程);Worktree 路径归一 realpath 记忆化。

### Docs



- **Graph 视图工具栏整体上移 VS Code 标题栏(省一整行竖直空间)**:scope(All / Current / Checkpoints)改为 `$(layers)` 图标下拉子菜单(`toggled` 勾选、默认 All,置于 Refresh Graph 图标左侧);仓库路径常驻 `WebviewView.description` 副标题(标题「Graph」同行右侧);多仓库态「切换仓库」`$(repo)` 图标按钮与 CI「登录 GitHub」`$(sign-in)` 图标按钮(授权后自动隐藏)条件显隐;Changed Files 的 List ⇄ Tree 切换改为 `$(list-tree)`/`$(list-flat)` 互斥图标(交互同 Branches 分组切换,文案适配为 "Group Changed Files by Directory" / "Show Changed Files as Flat List")。scope 与 List/Tree 偏好随之移交 host `workspaceState` 按仓库持久化(`hyperGit.log.scope:<repo>` / `hyperGit.log.dmode:<repo>`)——**原 webview state 中的旧偏好一次性重置为默认**(All / flat;选中与目录折叠不受影响)。
- **提交详情三区分割线可拖拽**:图 ⇄ 面板(横向面板 ≥200px 且图区 ≥280px、纵向 18%–75%)与面板内 Changed Files ⇄ Commit 信息(15%–85%)两根 gutter,实时调比例、按仓库记忆、键盘可达(方向键 ±2%、Home/End 归边界)。
- **再次点击已选中的提交行 = 反向操作**:收起该提交的 Changed Files 与 Commit 详情面板(300ms 内双击第二击豁免,保留「双击即打开」语义;方向键/Home/End 边界防抖不误触)。
Expand Down
16 changes: 16 additions & 0 deletions docs/.agents/issue.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,3 +148,19 @@
- **处理方式**:落地全局活跃仓库切换(Git Graph 模式)——① 选取逻辑下沉纯函数 `engine/git-state/repo-selection.ts`(三级优先:持久化恢复 → folder0 匹配 → 首个仓库,路径归一化跨平台稳定),`GitRepositoryService` 新增 `selectRepository`/`listRepositories`/`onDidChangeRepository`,活跃仓库持久化 `hyperGit.activeRepoRoot`;② **三重顺序不变量**保证 rebind 先于刷新:`applyRepository` 内先 fire 切换事件(同步 rebind:registry/favorites/branchesTree.setRepoRoot + context key 同步 + blame 清理 + filter 清空)后 fire onDidChange(防抖刷新),且 rebind 订阅先于 `refreshAll` 注册;③ Shelf 目录随 `service.repoRoot` 动态求值(`shelves/<basename>.<sha1[:8]>/`)+ 旧平铺数据一次性安全迁移(仅 rename、目标存在即跳过、失败可重试);④ Graph 工具栏仓库名升级可点击按钮(单仓库退化纯文本)+ `hyperGit.selectRepository` palette 命令(带参=程序化切换接缝,`activate()` 导出 `{ service }` 供集成测试);⑤ webview 视图状态(scope/选中/勾选集等)v2 `byRepo` 分区 + 最近提交消息 per-repo key(旧 key 回落一次平滑迁移)。集成测试新增 multi-root 双仓库 fixture 套件(`tests/suite/multi-root.test.js`)。
- **后续防范**:① **新增组件若构造期快照 repoRoot(拼 memento key / 存储目录),必须订阅 `service.onDidChangeRepository` 重绑**——可用 `grep -rn 'repoRoot' src/adapter/ | grep -v 'service.repoRoot'` 扫描快照点;② 集成测试需 UI 交互时,优先给命令 handler 加可选参数(无参=QuickPick,带参=程序化)+ `activate()` 导出接缝,勿依赖无法自动化的原生弹窗;③ 顺带修复了既有激活竞态(repo 发现晚于 activate 时 memento key 落 workspaceRoot 占位),rebind 事件会纠正——但根治应在「窗口内无写入路径」前提下依赖该纠正,勿在激活早期引入持久化写入。
- **同类问题影响**:所有围绕「单一活跃仓库」装配的 VS Code Git 扩展;凡按 repoRoot 构造 workspaceState/globalStorage 键或存储目录、却不在仓库集合变化时重绑的实现;以及 macOS 上 VS Code ≥ 1.110 主二进制 `Electron`→`Code` 更名导致 `@vscode/test-electron` 旧版 ENOENT 的集成测试环境(升 3.1.0 解决,见 PR #102)。

## #17 Webview 内联脚本回调中重复调用 acquireVsCodeApi()

- **表因**:Merge 编辑器点击 Save → 拒绝「强制保存」确认 → 点击 Cancel 时按钮无响应;交互 Rebase 冲突失败后重试同理。控制台报 `An instance of the VS Code API has already been acquired`。
- **根因**:`acquireVsCodeApi()` 每个 webview 全局仅允许成功调用一次(VS Code API 设计约束),第二次调用抛异常。merge-editor 与 rebase-webview 在事件回调内现场调用(`document.getElementById('save').onclick = function(){ acquireVsCodeApi().postMessage(...) }`),首次执行某回调成功后,任何其他回调再调用即崩溃。
- **处理方式**:脚本顶部 `const vscode = acquireVsCodeApi();` 获取一次,全部回调复用(commit/log webview 本就是此写法)。落地见 `fix(Webview)` 批次。
- **后续防范**:webview 内联脚本一律顶部单次获取;review 时 `grep -n "acquireVsCodeApi" src/adapter/webview/` 应只命中每文件脚本顶部一处调用。
- **同类问题影响**:所有自绘 webview 的扩展;回调/异步分支中按需获取 API 的惰性写法均存在此雷。

## #18 Commit 视图草稿随视图销毁丢失(state 未覆盖 + 模板重灌覆盖)

- **表因**:Commit 视图切走再切回(或折叠 Panel 展开),已输入的提交信息与 amend/signoff/skipHooks 勾选全部丢失,模板重新灌入。
- **根因**:复合缺陷——① WebviewView 未设 `retainContextWhenHidden`,隐藏即销毁;② `vscode.getState()` 只持久化 checked/mode/collapsed,不含草稿;③ message 输入经 200ms debounce 才 postMessage 到 host,销毁前最后一段输入连 host 侧 `currentMessage` 都未到达;④ 重建时模板注入逻辑因 textarea 为空而重新灌模板。内置 SCM 输入框草稿跨销毁可恢复,对比形成 UX 回归。
- **处理方式**:webview state v3 在 `byRepo` 分区新增 `draft`(message + 三勾选);输入/勾选变更即时 `saveState()` 落盘(消除 debounce 尾丢);回灌仅限「重建首帧/切换仓库」两时机且先于 `reconcileChecked`(避免 state 推送往返覆盖当前编辑);提交成功清空草稿。未采用 `retainContextWhenHidden`(钉死整个 webview 内存,且不跨窗口 reload)。
- **后续防范**:webview 内用户编辑态一律显式入 `setState`(含 debounce 之外的即时落盘点);回灌逻辑必须有时机守卫(一次性/切换触发),并注意「先回灌 DOM、后执行任何从 DOM 取数回写 state」的顺序。
- **同类问题影响**:所有自绘 WebviewView 承载编辑器的扩展;凡输入经防抖上报宿主的模式都存在尾丢窗口。
2 changes: 1 addition & 1 deletion media/hyper-git-icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions media/walkthrough/branches.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
The **Branches** view covers ref management:

- Group branches **by `/` prefix** or keep them flat
- Multi-select to delete, favorite, or copy refs in bulk
- Right-click for checkout, merge, rebase, compare, and cleanup of merged branches

[Open the Branches view](command:hyperGit.branches.focus)
10 changes: 10 additions & 0 deletions media/walkthrough/commit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
The **Commit** view consolidates the whole commit flow:

- Group work into multiple **changelists** and commit them independently
- Pick files with checkboxes, browse **flat or directory-tree** layouts
- Write the message with live **Conventional Commits** validation
- Reuse recent messages, amend, sign off, or skip hooks under *Advanced Options*

Press `Ctrl/Cmd+Enter` in the message box to commit.

[Open the Commit view](command:hyperGit.commit.focus)
7 changes: 7 additions & 0 deletions media/walkthrough/graph.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
The **Graph** view renders the commit graph with lanes, ref chips and CI status:

- Switch scope between **All commits**, the **current branch**, and **checkpoints**
- Filter by author, path, message (text or regex), date, and merge mode
- Click a commit to open the resident details panel — changed files, message, and stats

[Open the Graph view](command:hyperGit.log.focus)
8 changes: 8 additions & 0 deletions media/walkthrough/panel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
All Hyper Git views live in the **Hyper Git** container in the bottom panel:

- **Commit** — the IntelliJ-style commit window
- **Graph** — commit graph with filters and CI status
- **Branches** — local / remote branches and tags
- **Worktrees**, **Stash**, **Shelf** — parallel work and shelving

[Open the Hyper Git panel](command:hyperGit.commit.focus)
6 changes: 6 additions & 0 deletions media/walkthrough/stash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Beyond stash, Hyper Git brings two IntelliJ favorites:

- **Shelf** — store patches per changelist independently of git stash
- **Worktrees** — check out multiple branches in parallel working directories

[Open the Worktrees view](command:hyperGit.worktrees.focus)
Loading