diff --git a/src/App.svelte b/src/App.svelte index c615e64..ff19478 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -288,6 +288,7 @@ let fileHistoryLoading = false; let fileHistoryRequestId = 0; let activeFileHistoryRequestId = ""; + let repoOpenRequestId = 0; let lastFileHistoryHeadHash = ""; let commitMessage = ""; let amendMode = false; @@ -2031,6 +2032,7 @@ async function openRepo(pathOverride?: string) { const path = (pathOverride ?? repoPath).trim(); if (!path) { errorMessage = "Enter a repository path."; return; } + const requestId = ++repoOpenRequestId; repoPath = path; await runOperation("Opening repository", async () => { @@ -2042,6 +2044,7 @@ // Single backend round-trip: resolves the repo and reads status, branches, // commits and files in one pass instead of four sequential git calls. const bundle = await openRepositoryBundle(path, 100); + if (requestId !== repoOpenRequestId) return; resetRepositoryState(false); applyStatus(bundle.status); if (globalSearchBusy) void cancelGlobalSearch(); @@ -2235,8 +2238,18 @@ if (!wasActive) return; if (next) { + // Switch identity immediately. Otherwise a status/fetch request for the + // just-closed repository can still finish while it remains active and + // reinsert its tab through applyStatus(). + repoOpenRequestId += 1; + activeRepoPath = next.path; + repoPath = next.path; + status = null; + lastStatusFingerprint = ""; + resetRepositoryState(false); await openRepo(next.path); } else { + repoOpenRequestId += 1; resetRepositoryState(true); activeView = "management"; }