GetCommitFileStats returns statistics (additions/deletions) for files in a specific commit Returns a map from absolute file paths to their FileStats
(repoPath, commitID string)
| 116 | // GetCommitFileStats returns statistics (additions/deletions) for files in a specific commit |
| 117 | // Returns a map from absolute file paths to their FileStats |
| 118 | func GetCommitFileStats(repoPath, commitID string) (map[string]vcs.FileStats, error) { |
| 119 | // Validate the repository path exists |
| 120 | if _, err := os.Stat(repoPath); os.IsNotExist(err) { |
| 121 | return nil, fmt.Errorf("repository path does not exist: %s", repoPath) |
| 122 | } |
| 123 | |
| 124 | // Verify it's a git repository |
| 125 | if !isGitRepository(repoPath) { |
| 126 | return nil, fmt.Errorf("%s is not a git repository", repoPath) |
| 127 | } |
| 128 | |
| 129 | // Validate the commit exists |
| 130 | if err := validateCommit(repoPath, commitID); err != nil { |
| 131 | return nil, err |
| 132 | } |
| 133 | |
| 134 | // Get the repository root |
| 135 | repoRoot, err := GetRepositoryRoot(repoPath) |
| 136 | if err != nil { |
| 137 | return nil, fmt.Errorf("failed to get repository root: %w", err) |
| 138 | } |
| 139 | |
| 140 | // Run git show --numstat to get stats for the commit |
| 141 | // Use --root flag to handle root commits |
| 142 | stdout, stderr, err := runGitCommand(repoPath, "show", "--numstat", "--format=", commitID) |
| 143 | if err != nil { |
| 144 | return nil, gitCommandError(err, stderr) |
| 145 | } |
| 146 | |
| 147 | statusMap, err := getCommitFileStatuses(repoPath, commitID) |
| 148 | if err != nil { |
| 149 | return nil, err |
| 150 | } |
| 151 | |
| 152 | // Parse the numstat output |
| 153 | stats := make(map[string]vcs.FileStats) |
| 154 | lines := strings.Split(string(stdout), "\n") |
| 155 | for _, line := range lines { |
| 156 | line = strings.TrimSpace(line) |
| 157 | if line == "" { |
| 158 | continue |
| 159 | } |
| 160 | |
| 161 | // Format: additions deletions filename |
| 162 | parts := strings.Fields(line) |
| 163 | if len(parts) < 3 { |
| 164 | continue |
| 165 | } |
| 166 | |
| 167 | additions := 0 |
| 168 | deletions := 0 |
| 169 | |
| 170 | // Parse additions (may be "-" for binary files) |
| 171 | if parts[0] != "-" { |
| 172 | additions, _ = strconv.Atoi(parts[0]) |
| 173 | } |
| 174 | |
| 175 | // Parse deletions (may be "-" for binary files) |