( client: GitClient, args: string[], input: GitCliInput, )
| 1356 | // --------------------------------------------------------------- |
| 1357 | |
| 1358 | async function runFetch( |
| 1359 | client: GitClient, |
| 1360 | args: string[], |
| 1361 | input: GitCliInput, |
| 1362 | ): Promise<GitCliResult> { |
| 1363 | // `git fetch [<remote>] [<ref>] [--depth N] [--no-tags] [--prune]` |
| 1364 | const parsed = parseFlags(args, { |
| 1365 | depth: { kind: "value" }, |
| 1366 | "single-branch": { kind: "bool" }, |
| 1367 | "no-single-branch": { kind: "bool" }, |
| 1368 | tags: { kind: "bool" }, |
| 1369 | "no-tags": { kind: "bool" }, |
| 1370 | prune: { kind: "bool" }, |
| 1371 | }); |
| 1372 | if ("error" in parsed) { |
| 1373 | return { stdout: "", stderr: `git fetch: ${parsed.error}\n`, exitCode: 129 }; |
| 1374 | } |
| 1375 | if (parsed.positional.length > 2) { |
| 1376 | return { |
| 1377 | stdout: "", |
| 1378 | stderr: `git fetch: unexpected argument '${parsed.positional[2]}'\n`, |
| 1379 | exitCode: 129, |
| 1380 | }; |
| 1381 | } |
| 1382 | const [first, second] = parsed.positional; |
| 1383 | // Heuristic mirroring real git: if the first positional looks |
| 1384 | // like a URL, treat it as the remote URL and the second as a |
| 1385 | // ref. Otherwise the first is a remote name. |
| 1386 | const looksLikeUrl = first !== undefined && /^[a-z][a-z0-9+.-]*:\/\//.test(first); |
| 1387 | const url = looksLikeUrl ? first : undefined; |
| 1388 | const remote = looksLikeUrl ? undefined : first; |
| 1389 | const ref = looksLikeUrl ? second : (second ?? undefined); |
| 1390 | |
| 1391 | let depth: number | undefined; |
| 1392 | if (parsed.flags.depth !== undefined) { |
| 1393 | const n = Number.parseInt(parsed.flags.depth as string, 10); |
| 1394 | if (!Number.isFinite(n) || n < 1) { |
| 1395 | return { |
| 1396 | stdout: "", |
| 1397 | stderr: `git fetch: --depth requires a positive integer (got ${JSON.stringify(parsed.flags.depth)})\n`, |
| 1398 | exitCode: 129, |
| 1399 | }; |
| 1400 | } |
| 1401 | depth = n; |
| 1402 | } |
| 1403 | |
| 1404 | if (url !== undefined && !isSupportedRemoteUrl(url)) { |
| 1405 | return { |
| 1406 | stdout: "", |
| 1407 | stderr: `git fetch: unsupported transport for '${url}'. Only https://, http://, and file:// are supported.\n`, |
| 1408 | exitCode: 1, |
| 1409 | }; |
| 1410 | } |
| 1411 | |
| 1412 | let singleBranch: boolean | undefined; |
| 1413 | if (parsed.flags["single-branch"]) singleBranch = true; |
| 1414 | if (parsed.flags["no-single-branch"]) singleBranch = false; |
| 1415 | let tags: boolean | undefined; |
no test coverage detected