Keep managed status warnings out of desktop gitignore writes (#26671)

Co-authored-by: m4air <m4air@m4airs-MacBook-Air.local>
This commit is contained in:
Neil
2026-10-09 02:03:04 -07:00
committed by GitHub
co-authored by m4air
parent 3ca1d81458
commit fd6bc7e96f
2 changed files with 93 additions and 3 deletions
@@ -0,0 +1,86 @@
/** @vitest-environment happy-dom */
import { act } from 'react'
import { createRoot, type Root } from 'react-dom/client'
import { afterEach, beforeEach, expect, it, vi } from 'vitest'
import { clearHugeRepoWarningDismissalsForTests } from '@/lib/source-control-huge-repo-warning-dismissals'
import { useSourceControlStatusRefresh } from './use-status-refresh'
globalThis.IS_REACT_ACT_ENVIRONMENT = true
const actions = vi.hoisted(() => ({
setGitStatus: vi.fn(),
updateWorktreeGitIdentity: vi.fn(),
setUpstreamStatus: vi.fn(),
fetchUpstreamStatus: vi.fn()
}))
const warning = vi.hoisted(() => vi.fn())
vi.mock('@/store', () => ({
useAppStore: (select: (state: typeof actions) => unknown) => select(actions)
}))
vi.mock('sonner', () => ({ toast: { warning } }))
vi.mock('@/lib/connection-context', () => ({ getConnectionId: () => null }))
vi.mock('../../git-status-refresh', () => ({ refreshGitStatusForWorktree: vi.fn() }))
vi.mock('@/i18n/i18n', () => ({ translate: (_key: string, fallback: string) => fallback }))
const findHugeFoldersToIgnore = vi.fn()
const appendGitignore = vi.fn()
let root: Root | null = null
let container: HTMLDivElement | null = null
beforeEach(() => {
findHugeFoldersToIgnore.mockReset().mockResolvedValue(['dist'])
appendGitignore.mockReset().mockResolvedValue(true)
warning.mockReset()
vi.stubGlobal('window', {
...window,
api: { git: { findHugeFoldersToIgnore, appendGitignore } }
})
container = document.createElement('div')
root = createRoot(container)
})
afterEach(() => {
act(() => root?.unmount())
root = null
container = null
vi.unstubAllGlobals()
clearHugeRepoWarningDismissalsForTests()
})
async function renderOwner(
runtimeEnvironmentId: string | null,
connectionId: string | null = null
) {
function Probe() {
useSourceControlStatusRefresh({
activeRepoSettings: { activeRuntimeEnvironmentId: runtimeEnvironmentId },
activeWorktreeId: 'repo::/same/path',
worktreePath: '/same/path',
isFolder: false,
repositoryHuge: { limit: 1000 },
activeConnectionId: connectionId,
worktreeMap: new Map()
})
return null
}
await act(async () => root?.render(<Probe />))
}
it('does not probe or offer a desktop ignore action for a managed owner without a legacy SSH ID', async () => {
await renderOwner('managed-owner')
expect(findHugeFoldersToIgnore).not.toHaveBeenCalled()
expect(warning).not.toHaveBeenCalled()
expect(appendGitignore).not.toHaveBeenCalled()
})
it('keeps the existing local suggestion', async () => {
await renderOwner(null)
expect(findHugeFoldersToIgnore).toHaveBeenCalledExactlyOnceWith({ worktreePath: '/same/path' })
expect(warning).toHaveBeenCalledTimes(1)
})
it('keeps direct SSH targets out of the desktop helper', async () => {
await renderOwner(null, 'ssh-owner')
expect(findHugeFoldersToIgnore).not.toHaveBeenCalled()
expect(warning).not.toHaveBeenCalled()
})
@@ -1,6 +1,7 @@
import { useCallback, useEffect } from 'react'
import { toast } from 'sonner'
import { getConnectionId } from '@/lib/connection-context'
import { isLocalPathOpenBlocked } from '@/lib/local-path-open-guard'
import {
beginHugeRepoWarningProbe,
hasDismissedHugeRepoWarning,
@@ -46,6 +47,9 @@ export function useSourceControlStatusRefresh({
const updateWorktreeGitIdentity = useAppStore((s) => s.updateWorktreeGitIdentity)
const setUpstreamStatus = useAppStore((s) => s.setUpstreamStatus)
const fetchUpstreamStatus = useAppStore((s) => s.fetchUpstreamStatus)
const localIgnoreBlocked = isLocalPathOpenBlocked(activeRepoSettings, {
connectionId: activeConnectionId
})
const refreshActiveGitStatus = useCallback(
async (signal?: AbortSignal): Promise<void> => {
if (!activeWorktreeId || !worktreePath || isFolder) {
@@ -88,9 +92,9 @@ export function useSourceControlStatusRefresh({
}
}, [refreshActiveGitStatus])
// Why: when status is truncated, offer once per worktree to .gitignore the flooding folder; local-only since the SSH huge-folder write path isn't wired.
// Why: when status is truncated, offer once per worktree to .gitignore the flooding folder; desktop-only since the probe and write run on this machine, and managed repos have no connectionId.
useEffect(() => {
if (!repositoryHuge || !activeWorktreeId || !worktreePath || activeConnectionId) {
if (!repositoryHuge || !activeWorktreeId || !worktreePath || localIgnoreBlocked) {
return
}
const warningProbe = beginHugeRepoWarningProbe({
@@ -146,7 +150,7 @@ export function useSourceControlStatusRefresh({
activeWorktreeId,
activeWorktreeInstanceId,
worktreePath,
activeConnectionId,
localIgnoreBlocked,
refreshActiveGitStatus
])