diff --git a/src/git.ts b/src/git.ts index 27e9399..5d732f4 100644 --- a/src/git.ts +++ b/src/git.ts @@ -22,8 +22,6 @@ export class GitOperations { */ async getConflictedFiles(): Promise { try { - await this.git.status(); - const diffOutput = await this.git.diff(['--name-only', '--diff-filter=U']); const files = diffOutput .split('\n') @@ -156,14 +154,57 @@ export class GitOperations { merging?: string; mergeMessage?: string; }> { - const files = await this.getConflictedFiles(); - const info = await this.getMergeInfo(); + // Reuse a single status call instead of 3 separate git invocations + const status = await this.git.status(); + const current = status.current || 'HEAD'; + + const diffOutput = await this.git.diff(['--name-only', '--diff-filter=U']); + const files = diffOutput + .split('\n') + .map((f: string) => f.trim()) + .filter((f: string) => f.length > 0); + + // Get merge info (branches) using shared context + let merging: string | undefined; + let mergeMessage: string | undefined; + const gitDir = (await this.git.revparse(['--git-dir'])).trim(); + const absGitDir = resolve(this.workingDir, gitDir); + + // Try MERGE_MSG for merge context + try { + const mergeMsgPath = resolve(absGitDir, 'MERGE_MSG'); + if (existsSync(mergeMsgPath)) { + const msg = await readFile(mergeMsgPath, 'utf-8'); + const match = msg.match(/Merge branch ['"]([^'"]+)['"]/); + if (match) { + merging = match[1]; + } + mergeMessage = msg.split('\n')[0].trim(); + } + } catch { /* ignore */ } + + // Try MERGE_HEAD if no merging branch found + if (!merging) { + try { + const mergeHeadPath = resolve(absGitDir, 'MERGE_HEAD'); + if (existsSync(mergeHeadPath)) { + const sha = (await readFile(mergeHeadPath, 'utf-8')).trim(); + try { + const name = await this.git.raw(['name-rev', '--name-only', sha]); + merging = name.trim() || sha.substring(0, 7); + } catch { + merging = sha.substring(0, 7); + } + } + } catch { /* ignore */ } + } + return { hasConflicts: files.length > 0, files, - branch: info.current, - merging: info.merging, - mergeMessage: info.mergeMessage, + branch: current, + merging, + mergeMessage, }; } } \ No newline at end of file diff --git a/src/resolver.ts b/src/resolver.ts index 273adef..265a9a5 100644 --- a/src/resolver.ts +++ b/src/resolver.ts @@ -5,9 +5,11 @@ import { GitOperations } from './git'; export class ConflictResolver { private gitOps: GitOperations; + private workingDir: string; - constructor() { - this.gitOps = new GitOperations(); + constructor(cwd?: string) { + this.workingDir = cwd ? resolve(cwd) : process.cwd(); + this.gitOps = new GitOperations(cwd); } /** @@ -15,7 +17,7 @@ export class ConflictResolver { */ async openInEditor(filePath: string): Promise { const editor = process.env.EDITOR || process.env.VISUAL || this.getDefaultEditor(); - const fullPath = resolve(filePath); + const fullPath = resolve(this.workingDir, filePath); console.log(` Opening in ${editor}...`); @@ -56,7 +58,7 @@ export class ConflictResolver { */ async validateResolution(filePath: string): Promise<{ valid: boolean; reason?: string }> { try { - const content = await readFile(resolve(filePath), 'utf-8'); + const content = await readFile(resolve(this.workingDir, filePath), 'utf-8'); if (this.gitOps.hasConflictMarkers(content)) { return { @@ -79,7 +81,7 @@ export class ConflictResolver { */ async getConflictCount(filePath: string): Promise { try { - const content = await readFile(resolve(filePath), 'utf-8'); + const content = await readFile(resolve(this.workingDir, filePath), 'utf-8'); return this.gitOps.countConflicts(content); } catch { return 0;