fix(git): stop auto-select re-picking a repository that failed its probe
A corrupt nested repository can be discovered (its .git entry exists) but fail its status probe. The stale-selection recovery cleared the pick and forced a re-scan, and auto-select immediately re-picked the same path, looping discovery walk + probe for as long as the surface stayed visible. clearNestedRepoSelection now remembers the dropped repository per root (session-only set, cleared on runtime switch), and auto-select skips remembered paths. When every candidate has failed, no selection is made and surfaces settle into their unresolved state instead of churning requests. A manual picker pick remains possible and is probed like any other.
This commit is contained in:
@@ -90,6 +90,13 @@ interface GitStore {
|
||||
// route, and absent when discovery has not run yet.
|
||||
nestedReposByRoot: Map<string, NestedRepoDiscovery>;
|
||||
nestedRepoSelection: Map<string, string>;
|
||||
/**
|
||||
* Repositories whose selection was dropped because their probe reported
|
||||
* them as no longer a repository (corrupt or missing gitdir). Session-only
|
||||
* memory so auto-select does not immediately re-pick the same broken path
|
||||
* and loop walk+probe. Not persisted: the next launch re-probes honestly.
|
||||
*/
|
||||
staleClearedSelections: Map<string, Set<string>>;
|
||||
ensureNestedRepos: (root: string, options?: { force?: boolean }) => Promise<void>;
|
||||
selectNestedRepo: (root: string, repository: string) => void;
|
||||
clearNestedRepoSelection: (root: string) => void;
|
||||
@@ -622,6 +629,7 @@ export const useGitStore = create<GitStore>()(
|
||||
activeDirectory: null,
|
||||
nestedReposByRoot: new Map(),
|
||||
nestedRepoSelection: seedNestedRepoSelection(initialGitRuntimeKey),
|
||||
staleClearedSelections: new Map(),
|
||||
|
||||
resetForRuntimeSwitch: (runtimeKey) => {
|
||||
gitRuntimeGeneration += 1;
|
||||
@@ -639,6 +647,7 @@ export const useGitStore = create<GitStore>()(
|
||||
activeDirectory: null,
|
||||
nestedReposByRoot: new Map(),
|
||||
nestedRepoSelection: seedNestedRepoSelection(runtimeKey),
|
||||
staleClearedSelections: new Map(),
|
||||
});
|
||||
},
|
||||
|
||||
@@ -1273,10 +1282,19 @@ export const useGitStore = create<GitStore>()(
|
||||
|
||||
clearNestedRepoSelection: (root) => {
|
||||
if (!root) return;
|
||||
if (!get().nestedRepoSelection.has(root)) return;
|
||||
const cleared = get().nestedRepoSelection.get(root);
|
||||
if (cleared === undefined) return;
|
||||
const next = new Map(get().nestedRepoSelection);
|
||||
next.delete(root);
|
||||
set({ nestedRepoSelection: next });
|
||||
// Remember the drop so auto-select does not re-pick the same path
|
||||
// before its probe can tell the difference. Only stale-probe
|
||||
// recovery clears, so every clear here is a failed selection.
|
||||
const nextStale = new Map(get().staleClearedSelections);
|
||||
const forRoot = new Set(nextStale.get(root));
|
||||
forRoot.add(cleared);
|
||||
nextStale.set(root, forRoot);
|
||||
set({ staleClearedSelections: nextStale });
|
||||
writeCachedNestedRepoSelection(getRuntimeKey(), Object.fromEntries(next));
|
||||
},
|
||||
|
||||
@@ -1406,6 +1424,16 @@ export const useNestedRepoSelection = (root: string | null) => {
|
||||
});
|
||||
};
|
||||
|
||||
// Repositories of this root whose selection already failed its probe. Auto-
|
||||
// select skips them; the picker does not (a manual re-pick is a user decision
|
||||
// and gets probed like any other).
|
||||
export const useStaleClearedSelections = (root: string | null) => {
|
||||
return useGitStore((state) => {
|
||||
if (!root) return null;
|
||||
return state.staleClearedSelections.get(root) ?? null;
|
||||
});
|
||||
};
|
||||
|
||||
export const useGitBranchLabel = (directory: string | null) => {
|
||||
return useGitStore((state) => {
|
||||
if (!directory) return null;
|
||||
|
||||
Reference in New Issue
Block a user