diff --git a/src/features/vcs/GitLog.tsx b/src/features/vcs/GitLog.tsx index 440a9b03..6d87bee3 100644 --- a/src/features/vcs/GitLog.tsx +++ b/src/features/vcs/GitLog.tsx @@ -18,6 +18,7 @@ import clsx from "clsx"; import { useVirtualizer } from "@tanstack/react-virtual"; import type { Branch, ChangedFile, Commit, RevisionChange } from "@/bindings"; import { call, commands } from "@/platform/ipc"; +import { executeAction } from "@/platform/actions"; import { maybeEditorService, type EditorInput } from "@/workbench/contributions"; import { EmptyState, @@ -464,7 +465,9 @@ export function BranchesPanel() { ? branchMenu(n.branch, n.repo ? (useVcs.getState().heads[n.repo]?.head ?? null) : current) : n?.kind === "tag" ? tagMenu(n.ref!) - : []; + : n?.kind === "remote" || (n?.kind === "group" && n.key.endsWith("g:remote")) + ? REMOTES_MENU + : []; const items = n?.repo ? inRepo(n.repo, menu) : menu; if (!items.length) return; e.preventDefault(); @@ -485,6 +488,9 @@ export function BranchesPanel() { ); } +/** IDEA: the Remote node and each remote of the Branches pane offer Manage Remotes…. */ +const REMOTES_MENU: MenuItem[] = [{ label: "Manage Remotes…", run: () => void executeAction("vcs.manageRemotes") }]; + // --- filters ---------------------------------------------------------------- const DAY = 86_400_000; diff --git a/src/features/vcs/__tests__/logBranches.test.tsx b/src/features/vcs/__tests__/logBranches.test.tsx index 95ea1ac0..1136d809 100644 --- a/src/features/vcs/__tests__/logBranches.test.tsx +++ b/src/features/vcs/__tests__/logBranches.test.tsx @@ -15,6 +15,13 @@ vi.mock("@/platform/ipc", async (importOriginal) => { }; }); +const execute = vi.hoisted(() => vi.fn()); +vi.mock("@/platform/actions", async (importOriginal) => ({ + ...(await importOriginal()), + executeAction: execute, +})); + +import { ContextMenuHost } from "@/ui"; import { BranchesPanel } from "../GitLog"; import { emptyFilters, useGitLog } from "../logStore"; import { useVcs } from "../store"; @@ -54,6 +61,26 @@ beforeEach(() => { }); describe("Git Log branches pane", () => { + it("offers Manage Remotes… on the Remote node and on each remote, like IDEA", async () => { + useVcs.setState({ branches: [...branches, b("origin/main", { remote: true, commit: "1" })] }); + render( + <> + + + , + ); + fireEvent.contextMenu(screen.getByText("Remote")); + fireEvent.click(await screen.findByRole("menuitem", { name: "Manage Remotes…" })); + await waitFor(() => expect(execute).toHaveBeenCalledWith("vcs.manageRemotes")); + execute.mockClear(); + // Expand Remote, then the remote itself. + fireEvent.mouseDown(screen.getByText("Remote")); + fireEvent.keyDown(screen.getByRole("tree", { name: "Branches" }), { key: "ArrowRight" }); + fireEvent.contextMenu(await screen.findByText("origin")); + fireEvent.click(await screen.findByRole("menuitem", { name: "Manage Remotes…" })); + await waitFor(() => expect(execute).toHaveBeenCalledWith("vcs.manageRemotes")); + }); + it("one click only selects the branch", () => { render(); fireEvent.mouseDown(screen.getByText("feature"));