(stdout: string)
| 418 | } |
| 419 | |
| 420 | function parseNameStatusOutput(stdout: string): ChangedFileInfo[] { |
| 421 | const files: ChangedFileInfo[] = [] |
| 422 | const lines = stdout.trim().split("\n").filter(Boolean) |
| 423 | |
| 424 | for (const line of lines) { |
| 425 | // Format: STATUS\tPATH or STATUS\tOLDPATH\tNEWPATH (for renames) |
| 426 | const parts = line.split("\t") |
| 427 | const statusCode = parts[0] ?? "" |
| 428 | |
| 429 | if (statusCode.startsWith("R")) { |
| 430 | const oldPath = parts[1] |
| 431 | const newPath = parts[2] |
| 432 | if (!oldPath || !newPath) continue |
| 433 | files.push({ |
| 434 | path: newPath, |
| 435 | oldPath, |
| 436 | status: "renamed", |
| 437 | }) |
| 438 | continue |
| 439 | } |
| 440 | |
| 441 | const filePath = parts[1] |
| 442 | if (!filePath) continue |
| 443 | |
| 444 | if (statusCode === "A") { |
| 445 | files.push({ path: filePath, status: "added" }) |
| 446 | } else if (statusCode === "D") { |
| 447 | files.push({ path: filePath, status: "deleted" }) |
| 448 | } else { |
| 449 | files.push({ path: filePath, status: "modified" }) |
| 450 | } |
| 451 | } |
| 452 | |
| 453 | return files |
| 454 | } |
| 455 | |
| 456 | /** |
| 457 | * Parse git worktree list --porcelain output |
no test coverage detected