fix(git): resolve blank nested-repo surfaces; add repository pickers

The resolution gate on the pull-request, walkthrough, and mobile changes
surfaces stayed on forever (rootIsGitRepo stays false on a non-repo
root) while NestedRepoResolutionStates exits once the selected
repository probes as a repository, so those surfaces rendered nothing.
The gate now shows resolution states only while the operating directory
has not proven to be a repository, matching GitView.

Extract GitHeader's repository switcher into git/NestedRepoPicker and
mount it in the diff toolbar, a new slim header in the pull-request
view, the walkthrough header, and the mobile changes header. The pick
is shared per root, so every surface follows.

The walkthrough tab mounts keep-alive and hidden; it now receives a
visible prop so discovery waits until the tab is actually opened. Add
component tests for the shared resolution states.
This commit is contained in:
jaygupta17
2026-08-25 20:47:02 +05:30
parent e26b55e067
commit 11a48958e8
9 changed files with 241 additions and 67 deletions
+16 -3
View File
@@ -23,6 +23,7 @@ import {
useGitLoadingStatus,
} from '@/stores/useGitStore';
import { NestedRepoResolutionStates } from '@/components/views/git/NestedRepoResolutionStates';
import { NestedRepoPicker } from '@/components/views/git/NestedRepoPicker';
import { getRuntimeKey } from '@/lib/runtime-switch';
type SyncAction = 'fetch' | 'pull' | 'push' | 'sync' | null;
@@ -69,6 +70,7 @@ export const MobileChangesSurface: React.FC<MobileChangesSurfaceProps> = ({ onCl
const setActiveDirectory = useGitStore((state) => state.setActiveDirectory);
const ensureAll = useGitStore((state) => state.ensureAll);
const ensureNestedRepos = useGitStore((state) => state.ensureNestedRepos);
const selectNestedRepo = useGitStore((state) => state.selectNestedRepo);
const fetchStatus = useGitStore((state) => state.fetchStatus);
const fetchBranches = useGitStore((state) => state.fetchBranches);
const prefetchDiffs = useGitStore((state) => state.prefetchDiffs);
@@ -472,6 +474,16 @@ export const MobileChangesSurface: React.FC<MobileChangesSurfaceProps> = ({ onCl
{status?.current || currentDirectory || ''}
</p>
</div>
{rootIsGitRepo === false && Array.isArray(nestedRepos) && nestedRepos.length > 0 ? (
<NestedRepoPicker
repositories={nestedRepos}
selectedRepository={gitDirectory ?? null}
onSelectRepository={(repository) => {
if (rootDirectory) selectNestedRepo(rootDirectory, repository);
}}
repositoryRoot={rootDirectory ?? undefined}
/>
) : null}
</header>
<div className="min-h-0 flex-1">{state}</div>
</div>
@@ -481,9 +493,10 @@ export const MobileChangesSurface: React.FC<MobileChangesSurfaceProps> = ({ onCl
return renderListState(<MobileChangesState message={t('gitView.empty.selectSessionOrDirectory')} />);
}
// Non-repo root: surface nested-repository resolution (discovering, failed,
// unsupported, none found, or settling on the auto-selected repository).
if (rootIsGitRepo === false || isGitRepo === false) {
// Non-repo root: surface nested-repository resolution while the operating
// directory has not proven to be a repository (discovering, failed,
// unsupported, none found, or settling on the auto-selected one).
if (rootIsGitRepo === false && isGitRepo !== true) {
return renderListState(
<NestedRepoResolutionStates
rootIsGitRepo={rootIsGitRepo}