feat(vcs): Manage Remotes from the Remote node of the Git Log branches pane (#1081)

Manage Remotes… was only in the Git menu. The Remote node of the Git Log branches pane and each remote under it now offer it in their context menu.

Refs #800
This commit is contained in:
l0ng-ai
2026-11-04 02:07:42 +08:00
committed by GitHub
parent 8bb6dfddc2
commit 8efa7f8ece
2 changed files with 34 additions and 1 deletions
+7 -1
View File
@@ -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;
@@ -15,6 +15,13 @@ vi.mock("@/platform/ipc", async (importOriginal) => {
};
});
const execute = vi.hoisted(() => vi.fn());
vi.mock("@/platform/actions", async (importOriginal) => ({
...(await importOriginal<typeof import("@/platform/actions")>()),
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(
<>
<BranchesPanel />
<ContextMenuHost />
</>,
);
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(<BranchesPanel />);
fireEvent.mouseDown(screen.getByText("feature"));