( client: GitClient, args: string[], input: GitCliInput, )
| 212 | // --------------------------------------------------------------- |
| 213 | |
| 214 | async function runClone( |
| 215 | client: GitClient, |
| 216 | args: string[], |
| 217 | input: GitCliInput, |
| 218 | ): Promise<GitCliResult> { |
| 219 | // `git clone [--depth N] [--branch B] [--single-branch | --no-single-branch] |
| 220 | // [--no-tags] [--bare? rejected] <url> [<dir>]` |
| 221 | const parsed = parseFlags(args, { |
| 222 | depth: { kind: "value" }, |
| 223 | branch: { kind: "value", alias: ["b"] }, |
| 224 | "single-branch": { kind: "bool" }, |
| 225 | "no-single-branch": { kind: "bool" }, |
| 226 | "no-tags": { kind: "bool" }, |
| 227 | tags: { kind: "bool" }, |
| 228 | }); |
| 229 | if ("error" in parsed) { |
| 230 | return { stdout: "", stderr: `git clone: ${parsed.error}\n`, exitCode: 129 }; |
| 231 | } |
| 232 | const positional = parsed.positional; |
| 233 | if (positional.length === 0) { |
| 234 | return { stdout: "", stderr: "git clone: missing <repository>\n", exitCode: 129 }; |
| 235 | } |
| 236 | if (positional.length > 2) { |
| 237 | return { |
| 238 | stdout: "", |
| 239 | stderr: `git clone: unexpected argument '${positional[2]}'\n`, |
| 240 | exitCode: 129, |
| 241 | }; |
| 242 | } |
| 243 | const [url, dirArg] = positional; |
| 244 | if (!isSupportedRemoteUrl(url)) { |
| 245 | return { |
| 246 | stdout: "", |
| 247 | stderr: `git clone: unsupported transport for '${url}'. Only https://, http://, and file:// are supported.\n`, |
| 248 | exitCode: 1, |
| 249 | }; |
| 250 | } |
| 251 | let dir: string; |
| 252 | if (dirArg !== undefined && dirArg !== "") { |
| 253 | dir = resolveDir(dirArg, input.cwd); |
| 254 | } else { |
| 255 | // Real git derives the destination from the last path segment |
| 256 | // of the URL when no positional <dir> is given, so `git clone |
| 257 | // https://host/owner/repo.git` lands in `./repo` rather than |
| 258 | // splattering the working tree into cwd. |
| 259 | const name = repoNameFromUrl(url); |
| 260 | if (name === undefined) { |
| 261 | return { |
| 262 | stdout: "", |
| 263 | stderr: `git clone: could not derive a directory name from '${url}'. Pass an explicit destination.\n`, |
| 264 | exitCode: 129, |
| 265 | }; |
| 266 | } |
| 267 | dir = resolveDir(name, input.cwd); |
| 268 | } |
| 269 | |
| 270 | let depth: number | undefined; |
| 271 | if (parsed.flags.depth !== undefined) { |
no test coverage detected