| ... | ... | @@ -312,7 +312,40 @@ export class GitCoreService { |
| 312 | 312 | return value.length > 0 ? value : null; |
| 313 | 313 | } |
| 314 | 314 | |
| 315 | private async readBranchRecency(cwd: string): Promise<Map<string, number>> { |
| 316 | const branchRecency = await executeGit( |
| 317 | cwd, |
| 318 | ["for-each-ref", "--format=%(refname:short)%09%(committerdate:unix)", "refs/heads"], |
| 319 | { |
| 320 | timeoutMs: 15_000, |
| 321 | allowNonZeroExit: true, |
| 322 | }, |
| 323 | ); |
| 324 | |
| 325 | const branchLastCommit = new Map<string, number>(); |
| 326 | if (branchRecency.code !== 0) { |
| 327 | return branchLastCommit; |
| 328 | } |
| 329 | |
| 330 | for (const line of branchRecency.stdout.split("\n")) { |
| 331 | if (line.length === 0) { |
| 332 | continue; |
| 333 | } |
| 334 | const [name, lastCommitRaw] = line.split("\t"); |
| 335 | if (!name) { |
| 336 | continue; |
| 337 | } |
| 338 | const lastCommit = Number.parseInt(lastCommitRaw ?? "0", 10); |
| 339 | branchLastCommit.set(name, Number.isFinite(lastCommit) ? lastCommit : 0); |
| 340 | } |
| 341 | |
| 342 | return branchLastCommit; |
| 343 | } |
| 344 | |
| 315 | 345 | async listBranches(input: GitListBranchesInput): Promise<GitListBranchesResult> { |
| 346 | const branchRecencyPromise = this.readBranchRecency(input.cwd).catch( |
| 347 | () => new Map<string, number>(), |
| 348 | ); |
| 316 | 349 | const result = await executeGit(input.cwd, ["branch", "--no-color"], { |
| 317 | 350 | timeoutMs: 10_000, |
| 318 | 351 | allowNonZeroExit: true, |
| ... | ... | @@ -326,7 +359,7 @@ export class GitCoreService { |
| 326 | 359 | throw new Error(stderr || "git branch failed"); |
| 327 | 360 | } |
| 328 | 361 | |
| 329 | | const [defaultRef, worktreeList, branchRecency] = await Promise.all([ |
| 362 | const [defaultRef, worktreeList, branchLastCommit] = await Promise.all([ |
| 330 | 363 | executeGit(input.cwd, ["symbolic-ref", "refs/remotes/origin/HEAD"], { |
| 331 | 364 | timeoutMs: 5_000, |
| 332 | 365 | allowNonZeroExit: true, |
| ... | ... | @@ -335,14 +368,7 @@ export class GitCoreService { |
| 335 | 368 | timeoutMs: 5_000, |
| 336 | 369 | allowNonZeroExit: true, |
| 337 | 370 | }), |
| 338 | | executeGit( |
| 339 | | input.cwd, |
| 340 | | ["for-each-ref", "--format=%(refname:short)%09%(committerdate:unix)", "refs/heads"], |
| 341 | | { |
| 342 | | timeoutMs: 5_000, |
| 343 | | allowNonZeroExit: true, |
| 344 | | }, |
| 345 | | ), |
| 371 | branchRecencyPromise, |
| 346 | 372 | ]); |
| 347 | 373 | const defaultBranch = |
| 348 | 374 | defaultRef.code === 0 |
| ... | ... | @@ -364,21 +390,6 @@ export class GitCoreService { |
| 364 | 390 | } |
| 365 | 391 | } |
| 366 | 392 | |
| 367 | | const branchLastCommit = new Map<string, number>(); |
| 368 | | if (branchRecency.code === 0) { |
| 369 | | for (const line of branchRecency.stdout.split("\n")) { |
| 370 | | if (line.length === 0) { |
| 371 | | continue; |
| 372 | | } |
| 373 | | const [name, lastCommitRaw] = line.split("\t"); |
| 374 | | if (!name) { |
| 375 | | continue; |
| 376 | | } |
| 377 | | const lastCommit = Number.parseInt(lastCommitRaw ?? "0", 10); |
| 378 | | branchLastCommit.set(name, Number.isFinite(lastCommit) ? lastCommit : 0); |
| 379 | | } |
| 380 | | } |
| 381 | | |
| 382 | 393 | const branches = result.stdout |
| 383 | 394 | .split("\n") |
| 384 | 395 | .map((line) => line.trim()) |