fix(git): exit nested-repo states once resolution succeeds
NestedRepoResolutionStates had no success exit: on a non-repo root rootIsGitRepo stays false forever, so once repositories were found the pull-request and walkthrough tabs kept showing 'Checking repository' even after the selected repository probed as a repository. GitView never hit this because its call site sits inside its own isGitRepo === false branch. The component now takes the operating directory's probe and returns null when it resolves true. DiffView also still keyed its not-a-repository gate and every diff fetch off the raw project root, so opening a change from a nested repository showed 'This directory is not a Git repository'. It now resolves the nested repository for git data and diff operations while session-scoped lookups (session messages, review-flow directory) stay on the root.
This commit is contained in:
@@ -487,6 +487,7 @@ export const MobileChangesSurface: React.FC<MobileChangesSurfaceProps> = ({ onCl
|
||||
return renderListState(
|
||||
<NestedRepoResolutionStates
|
||||
rootIsGitRepo={rootIsGitRepo}
|
||||
resolvedIsGitRepo={isGitRepo}
|
||||
nestedRepos={nestedRepos}
|
||||
onRetryDiscovery={() => {
|
||||
if (rootDirectory) void ensureNestedRepos(rootDirectory, { force: true });
|
||||
|
||||
@@ -2,6 +2,7 @@ import React from 'react';
|
||||
|
||||
import { useUIStore } from '@/stores/useUIStore';
|
||||
import { useEffectiveDirectory } from '@/hooks/useEffectiveDirectory';
|
||||
import { useNestedGitDirectory } from '@/hooks/useNestedGitDirectory';
|
||||
import { useGitStore, useGitStatus, useIsGitRepo, useGitLoadingStatus } from '@/stores/useGitStore';
|
||||
import { useGitBaseBranchStore, gitBaseBranchEntryKey } from '@/stores/useGitBaseBranchStore';
|
||||
import { coerceDiffScope, branchRangeKey, isBranchScopeAvailable, isBranchScopeDefinitelyUnavailable, useRangeKeyedCache, useBoundedDirectoryRetry } from './branchDiffScope';
|
||||
@@ -997,7 +998,11 @@ export const DiffView: React.FC<DiffViewProps> = ({
|
||||
}) => {
|
||||
const { t } = useI18n();
|
||||
const { git, files } = useRuntimeAPIs();
|
||||
const effectiveDirectory = useEffectiveDirectory();
|
||||
const rootDirectory = useEffectiveDirectory();
|
||||
// Diffs belong to the repository being diffed: when the root is not
|
||||
// itself a repository, operate on the resolved nested repository instead.
|
||||
const { gitDirectory: nestedGitDirectory } = useNestedGitDirectory(rootDirectory ?? null);
|
||||
const effectiveDirectory = nestedGitDirectory ?? rootDirectory;
|
||||
const openContextSurface = useUIStore((state) => state.openContextSurface);
|
||||
const requestWalkthroughSource = useWalkthroughStore((state) => state.requestSource);
|
||||
const { screenWidth, isMobile } = useDeviceInfo();
|
||||
@@ -1038,7 +1043,7 @@ export const DiffView: React.FC<DiffViewProps> = ({
|
||||
const setDiffWrapLines = useUIStore((state) => state.setDiffWrapLines);
|
||||
const openContextFileAtLine = useUIStore((state) => state.openContextFileAtLine);
|
||||
const currentSessionId = useSessionUIStore((state) => state.currentSessionId);
|
||||
const sessionMessages = useSessionMessages(currentSessionId ?? '', effectiveDirectory ?? undefined);
|
||||
const sessionMessages = useSessionMessages(currentSessionId ?? '', rootDirectory ?? undefined);
|
||||
const diffWrapLines = diffWrapLinesStore;
|
||||
const forcedStaged = activeDiffScope === 'staged' ? true : activeDiffScope === 'working' ? false : null;
|
||||
const activeDiffStaged = forcedStaged ?? displayFileStaged;
|
||||
@@ -1645,7 +1650,7 @@ export const DiffView: React.FC<DiffViewProps> = ({
|
||||
|
||||
const handleStartReviewFlow = React.useCallback(async (execution: ReviewFlowExecution) => {
|
||||
if (!currentSessionId) return;
|
||||
const directory = useSessionUIStore.getState().getDirectoryForSession(currentSessionId) || effectiveDirectory || '';
|
||||
const directory = useSessionUIStore.getState().getDirectoryForSession(currentSessionId) || rootDirectory || '';
|
||||
if (!directory) {
|
||||
toast.error(t('diffView.reviewDialog.toast.noSessionDirectory'));
|
||||
return;
|
||||
|
||||
@@ -2343,6 +2343,7 @@ export const GitView: React.FC<GitViewProps> = ({ isActive }) => {
|
||||
return (
|
||||
<NestedRepoResolutionStates
|
||||
rootIsGitRepo={rootIsGitRepo}
|
||||
resolvedIsGitRepo={isGitRepo}
|
||||
nestedRepos={nestedRepos}
|
||||
onRetryDiscovery={() => {
|
||||
if (currentDirectory) {
|
||||
|
||||
@@ -265,6 +265,7 @@ export const PullRequestView: React.FC = () => {
|
||||
return (
|
||||
<NestedRepoResolutionStates
|
||||
rootIsGitRepo={rootIsGitRepo}
|
||||
resolvedIsGitRepo={isGitRepo}
|
||||
nestedRepos={nestedRepos}
|
||||
onRetryDiscovery={() => {
|
||||
void ensureNestedRepos(currentDirectory, { force: true });
|
||||
|
||||
@@ -8,6 +8,12 @@ import type { NestedRepoDiscovery } from '@/stores/useGitStore';
|
||||
type NestedRepoResolutionStatesProps = {
|
||||
/** Probe of the project root: `false` means nested resolution applies. */
|
||||
rootIsGitRepo: boolean | null;
|
||||
/**
|
||||
* Probe of the directory the consumer operates on (root or selected nested
|
||||
* repository). `true` means resolution succeeded and the consumer should
|
||||
* render its own content.
|
||||
*/
|
||||
resolvedIsGitRepo: boolean | null;
|
||||
/** Discovery outcome for the root (`undefined` = not run yet). */
|
||||
nestedRepos: NestedRepoDiscovery | undefined;
|
||||
onRetryDiscovery: () => void;
|
||||
@@ -17,8 +23,9 @@ type NestedRepoResolutionStatesProps = {
|
||||
|
||||
/**
|
||||
* Shared empty/loading states for git surfaces while nested-repository
|
||||
* resolution is pending, failed, or impossible. Renders null once
|
||||
* repositories are resolved so the consumer can proceed into its own content.
|
||||
* resolution is pending, failed, or impossible. Renders null once resolution
|
||||
* has finished — either the root is a repository or the operating directory
|
||||
* probed as one — so the consumer can proceed into its own content.
|
||||
*
|
||||
* A runtime without the discovery route (VS Code) reports "unsupported": the
|
||||
* honest state there is the plain not-a-repository empty state, without a
|
||||
@@ -26,6 +33,7 @@ type NestedRepoResolutionStatesProps = {
|
||||
*/
|
||||
export const NestedRepoResolutionStates: React.FC<NestedRepoResolutionStatesProps> = ({
|
||||
rootIsGitRepo,
|
||||
resolvedIsGitRepo,
|
||||
nestedRepos,
|
||||
onRetryDiscovery,
|
||||
emptyStateFooter,
|
||||
@@ -33,6 +41,7 @@ export const NestedRepoResolutionStates: React.FC<NestedRepoResolutionStatesProp
|
||||
const { t } = useI18n();
|
||||
|
||||
if (rootIsGitRepo !== false) return null;
|
||||
if (resolvedIsGitRepo === true) return null;
|
||||
|
||||
if (nestedRepos === undefined || nestedRepos === null) {
|
||||
return (
|
||||
|
||||
@@ -498,6 +498,7 @@ export const WalkthroughView = ({ directory: rootDirectory }: WalkthroughViewPro
|
||||
return (
|
||||
<NestedRepoResolutionStates
|
||||
rootIsGitRepo={rootIsGitRepo}
|
||||
resolvedIsGitRepo={isGitRepo}
|
||||
nestedRepos={nestedRepos}
|
||||
onRetryDiscovery={() => {
|
||||
if (rootDirectory) void ensureNestedRepos(rootDirectory, { force: true });
|
||||
|
||||
Reference in New Issue
Block a user