From 6f9819fee7f22d894cbf24478f5809f88745f61e Mon Sep 17 00:00:00 2001 From: l0ng-ai <24760907+l0ng-ai@users.noreply.github.com> Date: Wed, 4 Nov 2026 23:29:44 +0800 Subject: [PATCH] fix(vcs): Show History on a submodule folder shows the submodule's history (#1312) Show History picked its repository with repoOf, which routes a nested repository's own root to the enclosing repository (right for the commit view's submodule pointer), so a submodule folder listed its gitlink history in the parent repository. A repository's own root now opens that repository's history, as in IDEA; other paths still use the innermost repository. --- src/features/vcs/__tests__/multiRoot.test.ts | 8 ++++++++ src/features/vcs/logStore.ts | 14 +++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/features/vcs/__tests__/multiRoot.test.ts b/src/features/vcs/__tests__/multiRoot.test.ts index 0064e42d9..06a9ced86 100644 --- a/src/features/vcs/__tests__/multiRoot.test.ts +++ b/src/features/vcs/__tests__/multiRoot.test.ts @@ -132,6 +132,14 @@ describe("multi-root Git log", () => { off(); }); + it("shows a submodule folder's own history, not the folder's history in the enclosing repository", () => { + useVcs.setState({ roots: ["/r", "/r/libs/core"] }); + openLogTab("history", "/r/libs/core"); + openLogTab("history", "/r/libs/core/src/Lib.kt"); + openLogTab("history", "/r/libs"); + expect(useGitLog.getState().logTabs.map((t) => t.repo)).toEqual(["/r/libs/core", "/r/libs/core", "/r"]); + }); + it("shows several repositories chosen one click at a time in the Repository filter", async () => { log.mockImplementation(async (repo: string) => ({ status: "ok", data: [commit(repo)] })); let repositories = toggleRepository(undefined, "/project/front"); diff --git a/src/features/vcs/logStore.ts b/src/features/vcs/logStore.ts index 59ed9425f..b226fa808 100644 --- a/src/features/vcs/logStore.ts +++ b/src/features/vcs/logStore.ts @@ -8,6 +8,7 @@ import { collapseLinear, computeGraph, emptyGraphState, type GraphRow, type Grap import { logOptions, setLogOptions, type LogOptions } from "./logOptions"; import { clearConsole, errorMessage } from "./ops"; import { currentRepo, currentRepoRoot, repoName, repoOf, useVcs } from "./store"; +import { stripSlash } from "./model"; /** Date filter: commits made (committer time) after / before the given times (epoch ms). */ export interface LogDateFilter { @@ -262,12 +263,23 @@ export function selectGitTab(id: string) { let tabSeq = 0; +/** + * The repository whose history Show History lists: a repository's own root (a submodule + * folder included) is its own history, as in IDEA, not the folder's history in the + * enclosing repository; any other path belongs to the innermost repository containing it. + */ +function historyRepo(target: string): string | null { + const roots = useVcs.getState().roots; + const path = stripSlash(target); + return roots.includes(path) ? path : repoOf(target); +} + /** * Opens (or selects) a log tab of its own, leaving the main Log and its filters as * they are: Show History for a file, Show Git Log for a branch. */ export function openLogTab(kind: LogTab["kind"], target: string): string { - const repo = kind === "history" ? repoOf(target) : currentRepoRoot(); + const repo = kind === "history" ? historyRepo(target) : currentRepoRoot(); const existing = useGitLog.getState().logTabs.find((t) => t.kind === kind && t.target === target && t.repo === repo); if (existing) { selectGitTab(existing.id);