( git: ReturnType<typeof simpleGit>, defaultBranch: string, )
| 193 | } |
| 194 | |
| 195 | async function getBranchComparison( |
| 196 | git: ReturnType<typeof simpleGit>, |
| 197 | defaultBranch: string, |
| 198 | ): Promise<BranchComparison> { |
| 199 | let commits: GitChangesStatus["commits"] = []; |
| 200 | let againstBase: ChangedFile[] = []; |
| 201 | let ahead = 0; |
| 202 | let behind = 0; |
| 203 | |
| 204 | try { |
| 205 | const tracking = await git.raw([ |
| 206 | "rev-list", |
| 207 | "--left-right", |
| 208 | "--count", |
| 209 | `origin/${defaultBranch}...HEAD`, |
| 210 | ]); |
| 211 | const [behindStr, aheadStr] = tracking.trim().split(/\s+/); |
| 212 | behind = Number.parseInt(behindStr || "0", 10); |
| 213 | ahead = Number.parseInt(aheadStr || "0", 10); |
| 214 | |
| 215 | const logOutput = await git.raw([ |
| 216 | "log", |
| 217 | `origin/${defaultBranch}..HEAD`, |
| 218 | "--format=%H|%h|%s|%b|%an|%aI", |
| 219 | ]); |
| 220 | commits = parseGitLog(logOutput); |
| 221 | |
| 222 | if (ahead > 0) { |
| 223 | const nameStatus = await git.raw([ |
| 224 | "diff", |
| 225 | "--name-status", |
| 226 | `origin/${defaultBranch}...HEAD`, |
| 227 | ]); |
| 228 | againstBase = parseNameStatus(nameStatus); |
| 229 | |
| 230 | await applyNumstatToFiles(git, againstBase, [ |
| 231 | "diff", |
| 232 | "--numstat", |
| 233 | `origin/${defaultBranch}...HEAD`, |
| 234 | ]); |
| 235 | } |
| 236 | } catch {} |
| 237 | |
| 238 | return { commits, againstBase, ahead, behind }; |
| 239 | } |
| 240 | |
| 241 | /** Max file size for line counting (1 MiB) - skip larger files to avoid OOM */ |
| 242 | const MAX_LINE_COUNT_SIZE = 1 * 1024 * 1024; |
no test coverage detected