fix(vcs): surface stage/unstage failures instead of swallowing them (#1893)

* fix(vcs): surface stage/unstage failures instead of swallowing them

The Commit tab's Stage/Unstage items ran the IPC call and only attached a
.finally(refreshNow) handler. call() rejects with IpcError on any backend
failure (require_trust, git add failure, path routing), so the rejection
went unhandled: no notification, no console line, and the UI silently
showed the file still unstaged — reported as 'Stage/Unstage doesn't
work' (#1890).

Route the four handlers through runOp(), the same helper every other
mutating VCS op uses: it logs the command to the Git console, shows an
error balloon with the backend's message on failure, and refreshes the
status afterwards (so the manual .finally is dropped).

This doesn't change the success path; it makes the failure visible, which
is what the reporter needed to diagnose the real backend error.

* fix(vcs): add text catalog entries for the stage/unstage op titles
This commit is contained in:
arookieofc authored and GitHub committed 2026-11-07 08:26:57 +08:00
1 parent 2d34bc956d
commit 39dc5db079
2 files changed
+8 -5

No files matched your search

+5 -4
View File
@@ -76,6 +76,7 @@ import { KIND_COLOR, KIND_LABEL, fileCount, formatTime, stashLabel, stripSlash }
import { call, commands } from "@/platform/ipc";
import type { FileStatus } from "@/bindings";
import { OperationBanner } from "./operations";
import { runOp } from "./ops";
import { ShelfPanel, loadShelves, useShelf } from "./shelf";
import { refreshNow, repoName, selectRepo, useVcs } from "./store";
import styles from "./CommitView.module.css";
@@ -220,13 +221,13 @@ export function listMenu(id: string, active: boolean, files: readonly FileStatus
label: "Stage",
icon: "plus",
disabled: !files.some((f) => f.unstaged),
run: () => void call(commands.vcsStage(paths)).finally(() => void refreshNow()),
run: () => void runOp(tx`Stage ${count} files`, () => call(commands.vcsStage(paths))),
},
{
label: "Unstage",
icon: "minus",
disabled: !files.some((f) => f.staged),
run: () => void call(commands.vcsUnstage(paths)).finally(() => void refreshNow()),
run: () => void runOp(tx`Unstage ${count} files`, () => call(commands.vcsUnstage(paths))),
},
{ kind: "separator" },
...(count
@@ -335,13 +336,13 @@ export function nodeMenu(
label: "Stage",
icon: "plus",
disabled: !files.some((f) => f.unstaged),
run: () => void call(commands.vcsStage(paths)).finally(() => void refreshNow()),
run: () => void runOp(tx`Stage ${paths.length} files`, () => call(commands.vcsStage(paths))),
},
{
label: "Unstage",
icon: "minus",
disabled: !files.some((f) => f.staged),
run: () => void call(commands.vcsUnstage(paths)).finally(() => void refreshNow()),
run: () => void runOp(tx`Unstage ${paths.length} files`, () => call(commands.vcsUnstage(paths))),
},
{ kind: "separator" },
...(nodes.some((n) => n.changelist)
+3 -1
View File
@@ -6421,5 +6421,7 @@
"Recommended": "推荐",
"No preview": "无预览",
"Running in the background": "后台运行中",
"Couldn't stop the background task": "无法停止后台任务"
"Couldn't stop the background task": "无法停止后台任务",
"Stage {count} files": "暂存 {count} 个文件",
"Unstage {count} files": "取消暂存 {count} 个文件"
}