(filePath: string)
| 750 | * For deleted files, returns the size of the deleted content. |
| 751 | */ |
| 752 | export async function getGitDiffSize(filePath: string): Promise<number> { |
| 753 | const cwd = getAttributionRepoRoot() |
| 754 | |
| 755 | try { |
| 756 | // Use git diff --stat to get a summary of changes |
| 757 | const result = await execFileNoThrowWithCwd( |
| 758 | gitExe(), |
| 759 | ['diff', '--cached', '--stat', '--', filePath], |
| 760 | { cwd, timeout: 5000 }, |
| 761 | ) |
| 762 | |
| 763 | if (result.code !== 0 || !result.stdout) { |
| 764 | return 0 |
| 765 | } |
| 766 | |
| 767 | // Parse the stat output to extract additions and deletions |
| 768 | // Format: " file | 5 ++---" or " file | 10 +" |
| 769 | const lines = result.stdout.split('\n').filter(Boolean) |
| 770 | let totalChanges = 0 |
| 771 | |
| 772 | for (const line of lines) { |
| 773 | // Skip the summary line (e.g., "1 file changed, 3 insertions(+), 2 deletions(-)") |
| 774 | if (line.includes('file changed') || line.includes('files changed')) { |
| 775 | const insertMatch = line.match(/(\d+) insertions?/) |
| 776 | const deleteMatch = line.match(/(\d+) deletions?/) |
| 777 | |
| 778 | // Use line-based changes and approximate chars per line (~40 chars average) |
| 779 | const insertions = insertMatch ? parseInt(insertMatch[1]!, 10) : 0 |
| 780 | const deletions = deleteMatch ? parseInt(deleteMatch[1]!, 10) : 0 |
| 781 | totalChanges += (insertions + deletions) * 40 |
| 782 | } |
| 783 | } |
| 784 | |
| 785 | return totalChanges |
| 786 | } catch { |
| 787 | return 0 |
| 788 | } |
| 789 | } |
| 790 | |
| 791 | /** |
| 792 | * Check if a file was deleted in the staged changes. |
no test coverage detected