auto-claude: 154-fix-task-modal-conflict-check-status-refresh (#1462)
* auto-claude: subtask-1-1 - Add git update-index --refresh before git status * fix: add git update-index --refresh to release-service.ts Apply the same stale git index fix to release-service.ts that was added to worktree-handlers.ts. This prevents false-positive "uncommitted changes" errors that could incorrectly block releases. Affected methods: - runPreflightChecks: prevents blocking releases due to stale index - isWorktreeMerged: ensures accurate worktree merge detection - bumpVersion: prevents unnecessary stashing Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor: extract refreshGitIndex utility to eliminate code duplication Extract the repeated git update-index --refresh pattern into a reusable utility function in git-isolation.ts. This replaces 4 identical 9-line blocks across release-service.ts and worktree-handlers.ts with single function calls. Changes: - Add refreshGitIndex() to git-isolation.ts with full documentation - Update release-service.ts to use refreshGitIndex (3 locations) - Update worktree-handlers.ts to use refreshGitIndex (1 location) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: use static imports and isolated git env in refreshGitIndex - Replace dynamic require() with static imports at module level - Add getIsolatedGitEnv() to prevent git environment contamination - Remove misleading comment about non-existent circular dependency Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -19,7 +19,7 @@ import {
|
||||
findTaskWorktree,
|
||||
} from '../../worktree-paths';
|
||||
import { persistPlanStatus, updateTaskMetadataPrUrl } from './plan-file-utils';
|
||||
import { getIsolatedGitEnv } from '../../utils/git-isolation';
|
||||
import { getIsolatedGitEnv, refreshGitIndex } from '../../utils/git-isolation';
|
||||
import { killProcessGracefully } from '../../platform';
|
||||
|
||||
// Regex pattern for validating git branch names
|
||||
@@ -2402,6 +2402,8 @@ export function registerWorktreeHandlers(
|
||||
let uncommittedFiles: string[] = [];
|
||||
if (isGitWorkTree(project.path)) {
|
||||
try {
|
||||
refreshGitIndex(project.path);
|
||||
|
||||
const gitStatus = execFileSync(getToolPath('git'), ['status', '--porcelain'], {
|
||||
cwd: project.path,
|
||||
encoding: 'utf-8'
|
||||
|
||||
@@ -15,6 +15,7 @@ import type {
|
||||
} from '../shared/types';
|
||||
import { DEFAULT_CHANGELOG_PATH } from '../shared/constants';
|
||||
import { getToolPath } from './cli-tool-manager';
|
||||
import { refreshGitIndex } from './utils/git-isolation';
|
||||
|
||||
/**
|
||||
* Service for creating GitHub releases with worktree-aware pre-flight checks.
|
||||
@@ -198,6 +199,8 @@ export class ReleaseService extends EventEmitter {
|
||||
|
||||
// Check 1: Git working directory is clean
|
||||
try {
|
||||
refreshGitIndex(projectPath);
|
||||
|
||||
const gitStatus = execFileSync(getToolPath('git'), ['status', '--porcelain'], {
|
||||
cwd: projectPath,
|
||||
encoding: 'utf-8'
|
||||
@@ -445,6 +448,8 @@ export class ReleaseService extends EventEmitter {
|
||||
|
||||
// If empty or error checking, assume merged for safety
|
||||
if (unmergedCommits === 'error') {
|
||||
refreshGitIndex(worktreePath);
|
||||
|
||||
// Try alternative: check if worktree has any uncommitted changes
|
||||
const hasChanges = execFileSync(getToolPath('git'), ['status', '--porcelain'], {
|
||||
cwd: worktreePath,
|
||||
@@ -486,6 +491,8 @@ export class ReleaseService extends EventEmitter {
|
||||
}
|
||||
|
||||
// Check for uncommitted changes
|
||||
refreshGitIndex(projectPath);
|
||||
|
||||
const gitStatus = execFileSync(getToolPath('git'), ['status', '--porcelain'], {
|
||||
cwd: projectPath,
|
||||
encoding: 'utf-8'
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
* Backend equivalent: apps/backend/core/git_executable.py:get_isolated_git_env()
|
||||
*/
|
||||
|
||||
import { execFileSync } from 'child_process';
|
||||
import { getToolPath } from '../cli-tool-manager';
|
||||
|
||||
/**
|
||||
* Git environment variables that can cause cross-contamination between worktrees.
|
||||
*
|
||||
@@ -105,3 +108,38 @@ export function getIsolatedGitSpawnOptions(
|
||||
...additionalOptions,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Refreshes the git index to ensure accurate status after external commits.
|
||||
*
|
||||
* Git caches file stat information in its index. When files are modified
|
||||
* externally (e.g., by another process or IDE), the cached stat info can
|
||||
* become stale, causing `git status` to report false positives for
|
||||
* uncommitted changes.
|
||||
*
|
||||
* This function runs `git update-index --refresh` which updates the cached
|
||||
* stat information to match the actual file system state.
|
||||
*
|
||||
* @param cwd - Working directory where the git command should run
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* import { refreshGitIndex } from './git-isolation';
|
||||
*
|
||||
* // Call before git status to ensure accurate results
|
||||
* refreshGitIndex(projectPath);
|
||||
* const status = execFileSync('git', ['status', '--porcelain'], { cwd: projectPath });
|
||||
* ```
|
||||
*/
|
||||
export function refreshGitIndex(cwd: string): void {
|
||||
try {
|
||||
execFileSync(getToolPath('git'), ['update-index', '--refresh'], {
|
||||
cwd,
|
||||
encoding: 'utf-8',
|
||||
stdio: ['pipe', 'pipe', 'pipe'],
|
||||
env: getIsolatedGitEnv(),
|
||||
});
|
||||
} catch {
|
||||
// Ignore refresh errors - it's a best-effort optimization
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user