( gitUrl: string, targetPath: string, ref?: string, sha?: string, )
| 532 | * @param sha - Optional specific commit SHA to checkout |
| 533 | */ |
| 534 | export async function gitClone( |
| 535 | gitUrl: string, |
| 536 | targetPath: string, |
| 537 | ref?: string, |
| 538 | sha?: string, |
| 539 | ): Promise<void> { |
| 540 | // Use --recurse-submodules to initialize submodules |
| 541 | // Always start with shallow clone for efficiency |
| 542 | const args = [ |
| 543 | 'clone', |
| 544 | '--depth', |
| 545 | '1', |
| 546 | '--recurse-submodules', |
| 547 | '--shallow-submodules', |
| 548 | ] |
| 549 | |
| 550 | // Add --branch flag for specific ref (works for both branches and tags) |
| 551 | if (ref) { |
| 552 | args.push('--branch', ref) |
| 553 | } |
| 554 | |
| 555 | // If sha is specified, use --no-checkout since we'll checkout the SHA separately |
| 556 | if (sha) { |
| 557 | args.push('--no-checkout') |
| 558 | } |
| 559 | |
| 560 | args.push(gitUrl, targetPath) |
| 561 | |
| 562 | const cloneStarted = performance.now() |
| 563 | const cloneResult = await execFileNoThrow(gitExe(), args) |
| 564 | |
| 565 | if (cloneResult.code !== 0) { |
| 566 | logPluginFetch( |
| 567 | 'plugin_clone', |
| 568 | gitUrl, |
| 569 | 'failure', |
| 570 | performance.now() - cloneStarted, |
| 571 | classifyFetchError(cloneResult.stderr), |
| 572 | ) |
| 573 | throw new Error(`Failed to clone repository: ${cloneResult.stderr}`) |
| 574 | } |
| 575 | |
| 576 | // If sha is specified, fetch and checkout that specific commit |
| 577 | if (sha) { |
| 578 | // Try shallow fetch of the specific SHA first (most efficient) |
| 579 | const shallowFetchResult = await execFileNoThrowWithCwd( |
| 580 | gitExe(), |
| 581 | ['fetch', '--depth', '1', 'origin', sha], |
| 582 | { cwd: targetPath }, |
| 583 | ) |
| 584 | |
| 585 | if (shallowFetchResult.code !== 0) { |
| 586 | // Some servers don't support fetching arbitrary SHAs |
| 587 | // Fall back to unshallow fetch to get full history |
| 588 | logForDebugging( |
| 589 | `Shallow fetch of SHA ${sha} failed, falling back to unshallow fetch`, |
| 590 | ) |
| 591 | const unshallowResult = await execFileNoThrowWithCwd( |
no test coverage detected