fetchSingleFileGitDiff function

Future<ToolUseDiff?> fetchSingleFileGitDiff(
  1. String absoluteFilePath
)

Fetch a structured diff for a single file against the merge base.

Implementation

Future<ToolUseDiff?> fetchSingleFileGitDiff(String absoluteFilePath) async {
  final gitRoot = findGitRoot(p.dirname(absoluteFilePath));
  if (gitRoot == null) return null;

  final gitPath = p
      .relative(absoluteFilePath, from: gitRoot)
      .replaceAll(p.separator, '/');
  final repository = getCachedRepository();

  // Check if tracked
  final lsFiles = await _runGit(
    ['--no-optional-locks', 'ls-files', '--error-unmatch', gitPath],
    cwd: gitRoot,
    timeoutMs: _singleFileDiffTimeoutMs,
  );

  if (lsFiles.code == 0) {
    final diffRef = await _getDiffRef(gitRoot);
    final diff = await _runGit(
      ['--no-optional-locks', 'diff', diffRef, '--', gitPath],
      cwd: gitRoot,
      timeoutMs: _singleFileDiffTimeoutMs,
    );
    if (diff.code != 0 || diff.stdout.isEmpty) return null;
    final parsed = _parseRawDiffToToolUseDiff(gitPath, diff.stdout, 'modified');
    return ToolUseDiff(
      filename: parsed.filename,
      status: parsed.status,
      additions: parsed.additions,
      deletions: parsed.deletions,
      changes: parsed.changes,
      patch: parsed.patch,
      repository: repository,
    );
  }

  // Untracked - synthetic diff
  final synthetic = await _generateSyntheticDiff(gitPath, absoluteFilePath);
  if (synthetic == null) return null;
  return ToolUseDiff(
    filename: synthetic.filename,
    status: synthetic.status,
    additions: synthetic.additions,
    deletions: synthetic.deletions,
    changes: synthetic.changes,
    patch: synthetic.patch,
    repository: repository,
  );
}