static int fetch_refs_via_pack(struct transport *transport, int nr_heads, struct ref **to_fetch) { int ret = 0; struct git_transport_data *data = transport->data; struct ref *refs; char *dest = xstrdup(transport->url); struct fetch_pack_args args; struct ref *refs_tmp = NULL; memset(&args, 0, sizeof(args)); args.uploadpack = data->options.uploadpack; args.keep_pack = data->options.keep; args.lock_pack = 1; args.use_thin_pack = data->options.thin; args.include_tag = data->options.followtags; args.verbose = (transport->verbose > 1); args.quiet = (transport->verbose < 0); args.no_progress = !transport->progress; args.depth = data->options.depth; args.deepen_since = data->options.deepen_since; args.deepen_not = data->options.deepen_not; args.deepen_relative = data->options.deepen_relative; args.check_self_contained_and_connected = data->options.check_self_contained_and_connected; args.cloning = transport->cloning; args.update_shallow = data->options.update_shallow; if (!data->got_remote_heads) { connect_setup(transport, 0); get_remote_heads(data->fd[0], NULL, 0, &refs_tmp, 0, NULL, &data->shallow); data->got_remote_heads = 1; } refs = fetch_pack(&args, data->fd, data->conn, refs_tmp ? refs_tmp : transport->remote_refs, dest, to_fetch, nr_heads, &data->shallow, &transport->pack_lockfile); close(data->fd[0]); close(data->fd[1]); if (finish_connect(data->conn)) ret = -1; data->conn = NULL; data->got_remote_heads = 0; data->options.self_contained_and_connected = args.self_contained_and_connected; if (refs == NULL) ret = -1; if (report_unmatched_refs(to_fetch, nr_heads)) ret = -1; free_refs(refs_tmp); free_refs(refs); free(dest); return ret; }
static int fetch_refs_via_pack(struct transport *transport, int nr_heads, struct ref **to_fetch) { int ret = 0; struct git_transport_data *data = transport->data; struct ref *refs = NULL; char *dest = xstrdup(transport->url); struct fetch_pack_args args; struct ref *refs_tmp = NULL; memset(&args, 0, sizeof(args)); args.uploadpack = data->options.uploadpack; args.keep_pack = data->options.keep; args.lock_pack = 1; args.use_thin_pack = data->options.thin; args.include_tag = data->options.followtags; args.verbose = (transport->verbose > 1); args.quiet = (transport->verbose < 0); args.no_progress = !transport->progress; args.depth = data->options.depth; args.deepen_since = data->options.deepen_since; args.deepen_not = data->options.deepen_not; args.deepen_relative = data->options.deepen_relative; args.check_self_contained_and_connected = data->options.check_self_contained_and_connected; args.cloning = transport->cloning; args.update_shallow = data->options.update_shallow; args.from_promisor = data->options.from_promisor; args.no_dependents = data->options.no_dependents; args.filter_options = data->options.filter_options; args.stateless_rpc = transport->stateless_rpc; args.server_options = transport->server_options; args.negotiation_tips = data->options.negotiation_tips; if (!data->got_remote_heads) { int i; int must_list_refs = 0; for (i = 0; i < nr_heads; i++) { if (!to_fetch[i]->exact_oid) { must_list_refs = 1; break; } } refs_tmp = handshake(transport, 0, NULL, must_list_refs); } switch (data->version) { case protocol_v2: refs = fetch_pack(&args, data->fd, data->conn, refs_tmp ? refs_tmp : transport->remote_refs, dest, to_fetch, nr_heads, &data->shallow, &transport->pack_lockfile, data->version); break; case protocol_v1: case protocol_v0: refs = fetch_pack(&args, data->fd, data->conn, refs_tmp ? refs_tmp : transport->remote_refs, dest, to_fetch, nr_heads, &data->shallow, &transport->pack_lockfile, data->version); break; case protocol_unknown_version: BUG("unknown protocol version"); } close(data->fd[0]); close(data->fd[1]); if (finish_connect(data->conn)) ret = -1; data->conn = NULL; data->got_remote_heads = 0; data->options.self_contained_and_connected = args.self_contained_and_connected; data->options.connectivity_checked = args.connectivity_checked; if (refs == NULL) ret = -1; if (report_unmatched_refs(to_fetch, nr_heads)) ret = -1; free_refs(refs_tmp); free_refs(refs); free(dest); return ret; }
int cmd_fetch_pack(int argc, const char **argv, const char *prefix) { int i, ret; struct ref *ref = NULL; const char *dest = NULL; struct ref **sought = NULL; int nr_sought = 0, alloc_sought = 0; int fd[2]; char *pack_lockfile = NULL; char **pack_lockfile_ptr = NULL; struct child_process *conn; struct fetch_pack_args args; struct oid_array shallow = OID_ARRAY_INIT; struct string_list deepen_not = STRING_LIST_INIT_DUP; struct packet_reader reader; enum protocol_version version; fetch_if_missing = 0; packet_trace_identity("fetch-pack"); memset(&args, 0, sizeof(args)); args.uploadpack = "git-upload-pack"; for (i = 1; i < argc && *argv[i] == '-'; i++) { const char *arg = argv[i]; if (skip_prefix(arg, "--upload-pack=", &arg)) { args.uploadpack = arg; continue; } if (skip_prefix(arg, "--exec=", &arg)) { args.uploadpack = arg; continue; } if (!strcmp("--quiet", arg) || !strcmp("-q", arg)) { args.quiet = 1; continue; } if (!strcmp("--keep", arg) || !strcmp("-k", arg)) { args.lock_pack = args.keep_pack; args.keep_pack = 1; continue; } if (!strcmp("--thin", arg)) { args.use_thin_pack = 1; continue; } if (!strcmp("--include-tag", arg)) { args.include_tag = 1; continue; } if (!strcmp("--all", arg)) { args.fetch_all = 1; continue; } if (!strcmp("--stdin", arg)) { args.stdin_refs = 1; continue; } if (!strcmp("--diag-url", arg)) { args.diag_url = 1; continue; } if (!strcmp("-v", arg)) { args.verbose = 1; continue; } if (skip_prefix(arg, "--depth=", &arg)) { args.depth = strtol(arg, NULL, 0); continue; } if (skip_prefix(arg, "--shallow-since=", &arg)) { args.deepen_since = xstrdup(arg); continue; } if (skip_prefix(arg, "--shallow-exclude=", &arg)) { string_list_append(&deepen_not, arg); continue; } if (!strcmp(arg, "--deepen-relative")) { args.deepen_relative = 1; continue; } if (!strcmp("--no-progress", arg)) { args.no_progress = 1; continue; } if (!strcmp("--stateless-rpc", arg)) { args.stateless_rpc = 1; continue; } if (!strcmp("--lock-pack", arg)) { args.lock_pack = 1; pack_lockfile_ptr = &pack_lockfile; continue; } if (!strcmp("--check-self-contained-and-connected", arg)) { args.check_self_contained_and_connected = 1; continue; } if (!strcmp("--cloning", arg)) { args.cloning = 1; continue; } if (!strcmp("--update-shallow", arg)) { args.update_shallow = 1; continue; } if (!strcmp("--from-promisor", arg)) { args.from_promisor = 1; continue; } if (!strcmp("--no-dependents", arg)) { args.no_dependents = 1; continue; } if (skip_prefix(arg, ("--" CL_ARG__FILTER "="), &arg)) { parse_list_objects_filter(&args.filter_options, arg); continue; } if (!strcmp(arg, ("--no-" CL_ARG__FILTER))) { list_objects_filter_set_no_filter(&args.filter_options); continue; } usage(fetch_pack_usage); } if (deepen_not.nr) args.deepen_not = &deepen_not; if (i < argc) dest = argv[i++]; else usage(fetch_pack_usage); /* * Copy refs from cmdline to growable list, then append any * refs from the standard input: */ for (; i < argc; i++) add_sought_entry(&sought, &nr_sought, &alloc_sought, argv[i]); if (args.stdin_refs) { if (args.stateless_rpc) { /* in stateless RPC mode we use pkt-line to read * from stdin, until we get a flush packet */ for (;;) { char *line = packet_read_line(0, NULL); if (!line) break; add_sought_entry(&sought, &nr_sought, &alloc_sought, line); } } else { /* read from stdin one ref per line, until EOF */ struct strbuf line = STRBUF_INIT; while (strbuf_getline_lf(&line, stdin) != EOF) add_sought_entry(&sought, &nr_sought, &alloc_sought, line.buf); strbuf_release(&line); } } if (args.stateless_rpc) { conn = NULL; fd[0] = 0; fd[1] = 1; } else { int flags = args.verbose ? CONNECT_VERBOSE : 0; if (args.diag_url) flags |= CONNECT_DIAG_URL; conn = git_connect(fd, dest, args.uploadpack, flags); if (!conn) return args.diag_url ? 0 : 1; } packet_reader_init(&reader, fd[0], NULL, 0, PACKET_READ_CHOMP_NEWLINE | PACKET_READ_GENTLE_ON_EOF | PACKET_READ_DIE_ON_ERR_PACKET); version = discover_version(&reader); switch (version) { case protocol_v2: get_remote_refs(fd[1], &reader, &ref, 0, NULL, NULL); break; case protocol_v1: case protocol_v0: get_remote_heads(&reader, &ref, 0, NULL, &shallow); break; case protocol_unknown_version: BUG("unknown protocol version"); } ref = fetch_pack(&args, fd, conn, ref, dest, sought, nr_sought, &shallow, pack_lockfile_ptr, version); if (pack_lockfile) { printf("lock %s\n", pack_lockfile); fflush(stdout); } if (args.check_self_contained_and_connected && args.self_contained_and_connected) { printf("connectivity-ok\n"); fflush(stdout); } close(fd[0]); close(fd[1]); if (finish_connect(conn)) return 1; ret = !ref; /* * If the heads to pull were given, we should have consumed * all of them by matching the remote. Otherwise, 'git fetch * remote no-such-ref' would silently succeed without issuing * an error. */ ret |= report_unmatched_refs(sought, nr_sought); while (ref) { printf("%s %s\n", oid_to_hex(&ref->old_oid), ref->name); ref = ref->next; } return ret; }