diff --git a/src/features/vcs/common.module.css b/src/features/vcs/common.module.css index da45e600..05065dc6 100644 --- a/src/features/vcs/common.module.css +++ b/src/features/vcs/common.module.css @@ -305,6 +305,18 @@ .manageRowSelected:hover { background: var(--bg-list-selected); } +/* A fixed slot, so the names line up whether or not a row is marked. */ +.worktreeMark { + display: flex; + flex: none; + width: 14px; + margin-right: -4px; +} +/* The branch keeps its width; the path is what gets cut short. */ +.worktreeName { + flex: none; + max-width: 40%; +} .comparisonDialog > [data-dialog-body] { display: flex; diff --git a/src/features/vcs/gitMenuDialogs.tsx b/src/features/vcs/gitMenuDialogs.tsx index cc19fb22..5fd455c1 100644 --- a/src/features/vcs/gitMenuDialogs.tsx +++ b/src/features/vcs/gitMenuDialogs.tsx @@ -5,12 +5,13 @@ import type { Branch, MergeOptions, Remote, Worktree } from "@/bindings"; import { executeAction } from "@/platform/actions"; import { call, commands } from "@/platform/ipc"; import { notifications } from "@/workbench/contributions"; -import { Checkbox, Dialog, IconButton, Input, Select, T, type SelectOption } from "@/ui"; +import { Checkbox, Dialog, Icon, IconButton, Input, Select, T, type SelectOption } from "@/ui"; import { sortLocal, sortRemote } from "./branches"; import { conflictActions, openConflictsInstead, validateBranchName } from "./branchOps"; import { confirmDialog, openDialog } from "./dialogs"; import { errorMessage, runOp, runRemote, saveAll } from "./ops"; import { currentRepo, loadBranches, refreshNow, repoName, selectRepo, useVcs } from "./store"; +import { isCurrentWorktree } from "./worktrees"; import styles from "./common.module.css"; import { tx } from "@/platform/i18n"; @@ -660,7 +661,13 @@ export function WorktreesPanel({ className, listClassName }: { className?: strin onClick={() => setSelected(w.path)} onDoubleClick={() => void executeAction("file.openProjectPath", w.path)} > - {w.branch ?? (w.head ? w.head.slice(0, 8) : (bare))} + {/* The worktree this window works in, as IDEA marks it. */} + + {isCurrentWorktree(w.path, repo) && } + + + {w.branch ?? (w.head ? w.head.slice(0, 8) : (bare))} + {w.path} {(w.main || w.locked || w.prunable) && ( {w.main ? "main" : w.locked ? tx("locked") : tx("prunable")} diff --git a/src/features/vcs/worktrees.test.ts b/src/features/vcs/worktrees.test.ts new file mode 100644 index 00000000..61ea6e47 --- /dev/null +++ b/src/features/vcs/worktrees.test.ts @@ -0,0 +1,18 @@ +import { describe, expect, it } from "vitest"; +import { isCurrentWorktree } from "./worktrees"; + +describe("isCurrentWorktree", () => { + it("matches the repository root this window works in", () => { + expect(isCurrentWorktree("/work/app", "/work/app")).toBe(true); + expect(isCurrentWorktree("/work/app-wt", "/work/app")).toBe(false); + expect(isCurrentWorktree("/work/app/", "/work/app")).toBe(true); + expect(isCurrentWorktree("/work/app", null)).toBe(false); + }); + + it("ignores the drive letter's case and separators on Windows", () => { + expect(isCurrentWorktree("c:/Work/app", "C:/Work/app")).toBe(true); + expect(isCurrentWorktree("C:\\Work\\app", "C:/Work/app")).toBe(true); + // Only drive paths: elsewhere the case is part of the name. + expect(isCurrentWorktree("/Work/App", "/work/app")).toBe(false); + }); +}); diff --git a/src/features/vcs/worktrees.ts b/src/features/vcs/worktrees.ts new file mode 100644 index 00000000..24139c02 --- /dev/null +++ b/src/features/vcs/worktrees.ts @@ -0,0 +1,13 @@ +/** + * Whether worktree `path` (as `git worktree list` prints it) is the repository root `root` + * this window works in. Git prints `C:/…` with the drive in either case, so drive paths + * compare case-insensitively; a trailing slash doesn't count. + */ +export function isCurrentWorktree(path: string, root: string | null | undefined): boolean { + if (!root) return false; + const norm = (p: string) => { + const s = p.replace(/\\/g, "/").replace(/(.)\/+$/, "$1"); + return /^[A-Za-z]:\//.test(s) ? s.toLowerCase() : s; + }; + return norm(path) === norm(root); +} diff --git a/src/platform/locales/text/zh.json b/src/platform/locales/text/zh.json index 0936780f..963b3034 100644 --- a/src/platform/locales/text/zh.json +++ b/src/platform/locales/text/zh.json @@ -2707,6 +2707,7 @@ "New Worktree…": "新建工作树…", "Worktrees…": "工作树…", "Worktrees": "工作树", + "Current worktree": "当前工作树", "New Worktree": "新建工作树", "Git Remotes": "Git 远程", "Define Remote": "定义远程",