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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
### Changed

- **CI 发布渠道重启双市场**:`publish` job 增回 Open VSX 发布步骤(`pnpm exec ovsx publish --packagePath ./*.vsix`,由仓库变量 `ENABLE_OVSX_PUBLISH` 门控 + `OVSX_PAT` 凭证,复用 `package` job 的同一枚 VSIX、共享 production 审批门),覆盖 Cursor / Windsurf / VSCodium 等 Open VSX 系编辑器;README 安装渠道同步加回 Open VSX。发布决策沿革见 [发布策略调研](./docs/research/04-publishing-cicd.md)。
- **Commit 视图头部两行 UI 上移 VS Code 标题栏(省两行竖直空间)**:① 「Active Changelist」下拉与 `⋯` 管理菜单合并为标题栏 Refresh 图标左侧的 `$(checklist)` 图标按钮——点击弹出 QuickPick:各列表带文件计数、当前活动项预选,分隔线后并入 New / Rename / Delete Changelist… 操作(默认列表不可改名/删除);活动 changelist 名常驻视图副标题(标题「Commit」同行右侧)。② 文件列表 List ⇄ Tree 段控改为标题栏 `$(list-tree)`/`$(list-flat)` 互斥图标(交互同 Graph/Branches 切换范式),偏好移交 host `workspaceState` 按仓库持久化(`hyperGit.commit.dmode:<repo>`)——**原 webview state 中的旧 List/Tree 偏好一次性重置为默认 flat**(勾选集、目录折叠与提交草稿不受影响)。③ Select All 复选框吸顶于文件列表容器内首行(列表为空时随空态隐藏),原 `.cl-bar` 与 files-header 两行整体移除。

## [0.0.17] - 2026-09-09 — Log 提交详情常驻面板 · VS Code 1.136 最佳实践对齐 · 稳定性与体验修复

Expand Down
12 changes: 6 additions & 6 deletions docs/features/commit-view-consolidation.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
|---|---|
| 文件单击看 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 管理 | 头部 `<select>` 切换活动列表(`commit/setActive`)+ `⋯` 菜单(`commit/changelistMenu` → 新建 / 重命名 / 删除) |
| Changelist 管理 | 标题栏 `$(checklist)` 图标(Refresh 左侧)→ `hyperGit.setActiveChangelist` QuickPick:各列表带文件计数、当前活动项 `picked` 预选,分隔线后并入 New / Rename / Delete…(默认列表不可改名删除);活动列表名常驻 `view.description` 副标题(原头部 `<select>` + `⋯` 菜单行已上移,省一行竖直空间) |
| Git 操作工具栏 | 标题栏(`view/title`)承接 refresh / push / pull / fetch / pushDialog / updateProject / createPatch / applyPatch;去掉与 webview 内 Commit·Commit&Push 按钮重复的两项 |
| 活动栏未提交数角标 | 迁至 Commit `WebviewView.badge`(容器图标角标 = 各视图 badge 之和,总数不变) |

Expand All @@ -22,16 +22,16 @@

## 交互范围取舍

Commit 视图文件区以**活动 Changelist** 为提交目标(勾选集即提交范围);非活动 Changelist 通过头部下拉切换查看。相较旧树「同屏并列多 changelist」少了一处低频便利,换取窄侧栏下更聚焦的提交工作流。
Commit 视图文件区以**活动 Changelist** 为提交目标(勾选集即提交范围);非活动 Changelist 通过标题栏 `$(checklist)` 图标弹 QuickPick 切换,活动列表名常驻 `view.description` 副标题。相较旧树「同屏并列多 changelist」少了一处低频便利,换取窄侧栏下更聚焦的提交工作流。

## 实现

- 视图与菜单:[`package.json`](../../package.json)(删 `hyperGit.changes` 视图 / viewsWelcome / 全部 `view == hyperGit.changes` 菜单;`view/title` 迁至 `view == hyperGit.commit`)。
- 视图主体:[`adapter/webview/commit-webview.ts`](../../src/adapter/webview/commit-webview.ts)(groups/switcher/文件交互/菜单/角标/目录树)。
- 命令:[`adapter/commands.ts`](../../src/adapter/commands.ts)(`resolveChange` + 签名重构)。
- 视图主体:[`adapter/webview/commit-webview.ts`](../../src/adapter/webview/commit-webview.ts)(groups/文件交互/菜单/角标/目录树;changelist 切换与管理、List/Tree 切换已上移标题栏,mode 以 host 为事实源按仓库持久化)。
- 命令:[`adapter/commands.ts`](../../src/adapter/commands.ts)(`resolveChange` + 签名重构;`setActiveChangelist` QuickPick 承载切换与管理)。
- 装配:[`extension.ts`](../../src/extension.ts)(移除 tree/changesView,角标改由 `commitView.updateBadge`)。
- 协议:[`shared/protocol.ts`](../../src/shared/protocol.ts)(`CommitChangelistItem`、`commit/openFile|fileMenu|setActive|changelistMenu`)。
- 协议:[`shared/protocol.ts`](../../src/shared/protocol.ts)(`commit/openFile|fileMenu`;changelist 操作消息已随标题栏上移移除)。

## 验证

`pnpm run check-types && pnpm run lint && pnpm run test:unit` 全绿;Extension Development Host(F5):无 CHANGES 视图;Commit 顶部可切换/管理 changelist;文件单击开 Diff、右键出菜单(含 discard 确认);标题栏 Git 动作可用;活动栏角标随未提交数增减;无 Git 仓库时降级不崩溃。
`pnpm run check-types && pnpm run lint && pnpm run test:unit` 全绿;Extension Development Host(F5):无 CHANGES 视图;标题栏 `$(checklist)` 图标可切换/管理 changelist、副标题显示活动列表名;文件单击开 Diff、右键出菜单(含 discard 确认);标题栏 Git 动作可用;活动栏角标随未提交数增减;无 Git 仓库时降级不崩溃。
6 changes: 3 additions & 3 deletions docs/features/file-list-group-by-directory.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@ flowchart LR
| 建树路径 | 条目 `path`(仓库相对) | `CommitFileChange.path`(干净新路径,重命名归位到新目录) |
| 复选框 | 有:叶子勾选 + **目录三态**级联;Select All 基于全量文件 | 无(只读浏览) |
| 叶子单击 | 打开 Diff(`commit/openFile`) | 打开单文件 Diff(`log/openFile`,`data-path` 保持展示串不变) |
| 偏好持久化 | `setState({mode, collapsed, checked})` | host `workspaceState`(`hyperGit.log.dmode:<repo>`)+ webview `dcollapsed` 按仓库记忆 |
| 切换控件 | webview 内 List/Tree 段控 | Graph 标题栏 `$(list-tree)`/`$(list-flat)` 互斥图标(同 Branches 分组切换范式) |
| 偏好持久化 | host `workspaceState`(`hyperGit.commit.dmode:<repo>`)+ webview `setState` 按仓库记 `collapsed`/`checked` | host `workspaceState`(`hyperGit.log.dmode:<repo>`)+ webview `dcollapsed` 按仓库记忆 |
| 切换控件 | Commit 标题栏 `$(list-tree)`/`$(list-flat)` 互斥图标(context key `hyperGit.commit.tree`) | Graph 标题栏 `$(list-tree)`/`$(list-flat)` 互斥图标(同 Branches 分组切换范式) |

## 实现

- 引擎:[`engine/tree/file-tree.ts`](../../src/engine/tree/file-tree.ts)(+ [`tests/unit/file-tree.test.ts`](../../tests/unit/file-tree.test.ts),15 用例)。
- 协议:[`shared/protocol.ts`](../../src/shared/protocol.ts)(`FileTreeNode`;`CommitViewState.tree`;`log/commitFiles` payload `tree`)。
- 渲染:[`commit-webview.ts`](../../src/adapter/webview/commit-webview.ts)(List/Tree 段控、`renderFlat`/`renderTree`、`makeLeafRow`、目录三态 `updateDirStates`)、[`log-webview.ts`](../../src/adapter/webview/log-webview.ts)(`renderDetails` 分派、`renderDetailNode`;Log 侧切换控件为 Graph 标题栏 `hyperGit.log.detailTree/detailFlat` 命令图标,模式经 `log/detailMode` 定向下发免整图重拉)。
- 渲染:[`commit-webview.ts`](../../src/adapter/webview/commit-webview.ts)(`renderFlat`/`renderTree`、`makeLeafRow`、目录三态 `updateDirStates`;切换控件为 Commit 标题栏 `hyperGit.commit.detailTree/detailFlat` 命令图标,mode 以 host 为事实源随 `state` 整态下发)、[`log-webview.ts`](../../src/adapter/webview/log-webview.ts)(`renderDetails` 分派、`renderDetailNode`;Log 侧切换控件为 Graph 标题栏 `hyperGit.log.detailTree/detailFlat` 命令图标,模式经 `log/detailMode` 定向下发免整图重拉)。

## 验证

Expand Down
42 changes: 39 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -204,8 +204,9 @@
},
{
"command": "hyperGit.setActiveChangelist",
"title": "Set Active Changelist",
"category": "Hyper Git"
"title": "Set Active Changelist…",
"category": "Hyper Git",
"icon": "$(checklist)"
},
{
"command": "hyperGit.renameChangelist",
Expand Down Expand Up @@ -272,6 +273,18 @@
"category": "Hyper Git",
"icon": "$(list-flat)"
},
{
"command": "hyperGit.commit.detailTree",
"title": "Group Changed Files by Directory",
"category": "Hyper Git",
"icon": "$(list-tree)"
},
{
"command": "hyperGit.commit.detailFlat",
"title": "Show Changed Files as Flat List",
"category": "Hyper Git",
"icon": "$(list-flat)"
},
{
"command": "hyperGit.selectRepository",
"title": "Select Repository…",
Expand Down Expand Up @@ -816,6 +829,21 @@
}
],
"view/title": [
{
"command": "hyperGit.setActiveChangelist",
"when": "view == hyperGit.commit",
"group": "navigation@0.5"
},
{
"command": "hyperGit.commit.detailTree",
"when": "view == hyperGit.commit && !hyperGit.commit.tree",
"group": "navigation@0.75"
},
{
"command": "hyperGit.commit.detailFlat",
"when": "view == hyperGit.commit && hyperGit.commit.tree",
"group": "navigation@0.75"
},
{
"command": "hyperGit.refresh",
"when": "view == hyperGit.commit",
Expand Down Expand Up @@ -1153,7 +1181,7 @@
},
{
"command": "hyperGit.setActiveChangelist",
"when": "false"
"when": "view == hyperGit.commit"
},
{
"command": "hyperGit.renameChangelist",
Expand Down Expand Up @@ -1375,6 +1403,14 @@
"command": "hyperGit.log.detailFlat",
"when": "view == hyperGit.log"
},
{
"command": "hyperGit.commit.detailTree",
"when": "view == hyperGit.commit"
},
{
"command": "hyperGit.commit.detailFlat",
"when": "view == hyperGit.commit"
},
{
"command": "hyperGit.acceptOurs",
"when": "hyperGit.hasConflicts"
Expand Down
43 changes: 41 additions & 2 deletions src/adapter/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ function asId(arg: unknown): string | undefined {
* 注册 Changes / Commit 相关命令(M1;原 Changes 树移除后由 Commit webview 复用)。
*
* 文件级命令统一接受 `ChangeItem | 路径字符串`:webview 传路径,host 经 {@link resolveChange}
* 回落到 `service.getChanges()` 解析为 ChangeItem(单一事实源)。视图刷新由 registry/service
* 回落到 `service.getChanges()` 解析为 ChangeItem(单一事实源)。changelist 切换与管理由
* 标题栏 $(checklist) 图标进入 setActiveChangelist QuickPick 承载。视图刷新由 registry/service
* 的 onDidChange → extension.refreshAll → commitView.refresh() 驱动,命令内不再直接刷新视图。
*/
export function registerChangesCommands(
Expand Down Expand Up @@ -57,10 +58,48 @@ export function registerChangesCommands(
);

subs.push(
vscode.commands.registerCommand('hyperGit.setActiveChangelist', (arg: unknown) => {
vscode.commands.registerCommand('hyperGit.setActiveChangelist', async (arg?: unknown) => {
// 带参 = 程序化切换;无参 = QuickPick(标题栏 $(checklist) 图标与命令面板共用入口)。
const id = asId(arg);
if (id) {
registry.setActive(id);
return;
}
const active = registry.activeChangelistId;
// 计数取 getGroups(含空列表,未显式分配项归活动列表——见 engine/changelist/grouper)。
const groups = registry.getGroups(service.getChanges(), (c) => c.relativePath);
type SetActiveItem =
| { label: string; description: string; picked: boolean; setId: string }
| { label: string; kind: vscode.QuickPickItemKind }
| { label: string; op: 'new' | 'rename' | 'delete'; targetId?: string };
const items: SetActiveItem[] = groups.map((g) => ({
label: g.name,
description: `${g.items.length} file${g.items.length === 1 ? '' : 's'}`,
picked: g.id === active, // 预选当前活动项(对齐 selectRepository 的 picked 范式)
setId: g.id,
}));
// 分隔线后并入原 webview「⋯」菜单管理操作(default 不可改名/删除,镜像原 handleChangelistMenu 语义)。
items.push({ label: 'Actions', kind: vscode.QuickPickItemKind.Separator });
items.push({ label: '$(add) New Changelist…', op: 'new' });
const def = active !== 'default' ? registry.getDef(active) : undefined;
if (def) {
items.push({ label: `$(edit) Rename "${def.name}"…`, op: 'rename', targetId: active });
items.push({ label: `$(trash) Delete "${def.name}"…`, op: 'delete', targetId: active });
}
const pick = await vscode.window.showQuickPick(items, { placeHolder: 'Select Active Changelist' });
if (!pick) {
return;
}
if ('setId' in pick) {
registry.setActive(pick.setId); // 视图刷新经 registry.onDidChange → refreshAll 驱动
} else if ('op' in pick) {
if (pick.op === 'new') {
await vscode.commands.executeCommand('hyperGit.newChangelist');
} else if (pick.op === 'rename') {
await vscode.commands.executeCommand('hyperGit.renameChangelist', pick.targetId);
} else {
await vscode.commands.executeCommand('hyperGit.deleteChangelist', pick.targetId);
}
}
}),
);
Expand Down
Loading