(filePath: string)
| 690 | * For deleted files, returns the size of the deleted content. |
| 691 | */ |
| 692 | export async function getGitDiffSize(filePath: string): Promise<number> { |
| 693 | const cwd = getAttributionRepoRoot() |
| 694 | |
| 695 | try { |
| 696 | // Use git diff --stat to get a summary of changes |
| 697 | const result = await execFileNoThrowWithCwd( |
| 698 | gitExe(), |
| 699 | ['diff', '--cached', '--stat', '--', filePath], |
| 700 | { cwd, timeout: 5000 }, |
| 701 | ) |
| 702 | |
| 703 | if (result.code !== 0 || !result.stdout) { |
| 704 | return 0 |
| 705 | } |
| 706 | |
| 707 | // Parse the stat output to extract additions and deletions |
| 708 | // Format: " file | 5 ++---" or " file | 10 +" |
| 709 | const lines = result.stdout.split('\n').filter(Boolean) |
| 710 | let totalChanges = 0 |
| 711 | |
| 712 | for (const line of lines) { |
| 713 | // Skip the summary line (e.g., "1 file changed, 3 insertions(+), 2 deletions(-)") |
| 714 | if (line.includes('file changed') || line.includes('files changed')) { |
| 715 | const insertMatch = line.match(/(\d+) insertions?/) |
| 716 | const deleteMatch = line.match(/(\d+) deletions?/) |
| 717 | |
| 718 | // Use line-based changes and approximate chars per line (~40 chars average) |
| 719 | const insertions = insertMatch ? parseInt(insertMatch[1]!, 10) : 0 |
| 720 | const deletions = deleteMatch ? parseInt(deleteMatch[1]!, 10) : 0 |
| 721 | totalChanges += (insertions + deletions) * 40 |
| 722 | } |
| 723 | } |
| 724 | |
| 725 | return totalChanges |
| 726 | } catch { |
| 727 | return 0 |
| 728 | } |
| 729 | } |
| 730 | |
| 731 | /** |
| 732 | * Check if a file was deleted in the staged changes. |
no test coverage detected