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 <[email protected]> * 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 <[email protected]> * 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 <[email protected]> --------- Co-authored-by: Claude Opus 4.5 <[email protected]>
This commit is contained in:
committed by
StillKnotKnown
co-authored by
Claude Opus 4.5
parent
529a2ddb8e
commit
c306fc89a8
@@ -21,7 +21,6 @@ import {
|
||||
} from '../../worktree-paths';
|
||||
import { persistPlanStatus, updateTaskMetadataPrUrl } from './plan-file-utils';
|
||||
import { getIsolatedGitEnv, refreshGitIndex } from '../../utils/git-isolation';
|
||||
import { cleanupWorktree } from '../../utils/worktree-cleanup';
|
||||
import { killProcessGracefully } from '../../platform';
|
||||
import { stripAnsiCodes } from '../../../shared/utils/ansi-sanitizer';
|
||||
import { taskStateManager } from '../../task-state-manager';
|
||||
|
||||
@@ -109,79 +109,6 @@ export function getIsolatedGitSpawnOptions(
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Result type for detectWorktreeBranch function.
|
||||
*/
|
||||
export interface WorktreeBranchDetectionResult {
|
||||
/** The branch name to use for deletion */
|
||||
branch: string;
|
||||
/** Whether the fallback branch pattern was used */
|
||||
usingFallback: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detects the branch name in a worktree with safety validation.
|
||||
*
|
||||
* This function prevents a critical bug where git rev-parse in a corrupted/orphaned
|
||||
* worktree can return the main project's current branch instead of the worktree's branch.
|
||||
* It validates the detected branch matches the expected pattern before using it.
|
||||
*
|
||||
* @param worktreePath - Path to the worktree directory
|
||||
* @param specId - The spec ID used to generate the expected branch name
|
||||
* @param options - Optional configuration
|
||||
* @param options.timeout - Timeout in milliseconds for git commands (default: 30000)
|
||||
* @param options.logPrefix - Prefix for log messages (e.g., "[TASK_UPDATE_STATUS]")
|
||||
* @returns Object containing the branch name and whether fallback was used
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* import { detectWorktreeBranch } from './utils/git-isolation';
|
||||
* import { getToolPath } from './cli-tool-manager';
|
||||
*
|
||||
* const { branch, usingFallback } = detectWorktreeBranch(
|
||||
* worktreePath,
|
||||
* task.specId,
|
||||
* { timeout: 30000, logPrefix: '[TASK_WORKTREE_DISCARD]' }
|
||||
* );
|
||||
* ```
|
||||
*/
|
||||
export function detectWorktreeBranch(
|
||||
worktreePath: string,
|
||||
specId: string,
|
||||
options: { timeout?: number; logPrefix?: string } = {}
|
||||
): WorktreeBranchDetectionResult {
|
||||
const { timeout = 30000, logPrefix = '[WORKTREE_BRANCH_DETECTION]' } = options;
|
||||
const expectedBranch = `auto-claude/${specId}`;
|
||||
let branch = expectedBranch;
|
||||
let usingFallback = false;
|
||||
|
||||
try {
|
||||
const detectedBranch = execFileSync(getToolPath('git'), ['rev-parse', '--abbrev-ref', 'HEAD'], {
|
||||
cwd: worktreePath,
|
||||
encoding: 'utf-8',
|
||||
timeout,
|
||||
env: getIsolatedGitEnv()
|
||||
}).trim();
|
||||
|
||||
// SECURITY: Use strict exact-match validation (not prefix matching) to prevent
|
||||
// accidentally deleting a different task's auto-claude branch. When git rev-parse
|
||||
// returns an unexpected branch, we MUST fall back to the expected pattern rather
|
||||
// than risking deletion of the wrong branch. This is critical for data safety.
|
||||
if (detectedBranch === expectedBranch) {
|
||||
branch = detectedBranch;
|
||||
} else {
|
||||
console.warn(`${logPrefix} Detected branch '${detectedBranch}' doesn't match expected branch '${expectedBranch}', using fallback: ${expectedBranch}`);
|
||||
usingFallback = true;
|
||||
}
|
||||
} catch (branchError) {
|
||||
// If we can't get branch name, use the default pattern
|
||||
usingFallback = true;
|
||||
console.warn(`${logPrefix} Could not get branch name, using fallback pattern: ${branch}`, branchError);
|
||||
}
|
||||
|
||||
return { branch, usingFallback };
|
||||
}
|
||||
|
||||
/**
|
||||
* Refreshes the git index to ensure accurate status after external commits.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user