Merge branch 'jt/clone-server-option'
authorJunio C Hamano <gitster@pobox.com>
Thu, 30 May 2019 17:50:46 +0000 (10:50 -0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 30 May 2019 17:50:46 +0000 (10:50 -0700)
A brown-paper-bag bugfix to a change already in 'master'.

* jt/clone-server-option:
fetch-pack: send server options after command

1  2 
fetch-pack.c
diff --combined fetch-pack.c
index 3f24d0c8a69f5d105f796b8102cb37e4213a0e86,46651b16bca86928b317cffef1bc9cfa5e20007c..1c10f54e788ca53b548a226a66dd1eec96a8cb22
@@@ -191,10 -191,8 +191,10 @@@ static void send_request(struct fetch_p
        if (args->stateless_rpc) {
                send_sideband(fd, -1, buf->buf, buf->len, LARGE_PACKET_MAX);
                packet_flush(fd);
 -      } else
 -              write_or_die(fd, buf->buf, buf->len);
 +      } else {
 +              if (write_in_full(fd, buf->buf, buf->len) < 0)
 +                      die_errno(_("unable to write to remote"));
 +      }
  }
  
  static void insert_one_alternate_object(struct fetch_negotiator *negotiator,
@@@ -573,14 -571,9 +573,14 @@@ static void filter_refs(struct fetch_pa
                next = ref->next;
  
                if (starts_with(ref->name, "refs/") &&
 -                  check_refname_format(ref->name, 0))
 -                      ; /* trash */
 -              else {
 +                  check_refname_format(ref->name, 0)) {
 +                      /*
 +                       * trash or a peeled value; do not even add it to
 +                       * unmatched list
 +                       */
 +                      free_one_ref(ref);
 +                      continue;
 +              } else {
                        while (i < nr_sought) {
                                int cmp = strcmp(ref->name, sought[i]->name);
                                if (cmp < 0)
        }
  
        oidset_clear(&tip_oids);
 -      for (ref = unmatched; ref; ref = next) {
 -              next = ref->next;
 -              free(ref);
 -      }
 +      free_refs(unmatched);
  
        *refs = newlist;
  }
@@@ -1115,7 -1111,7 +1115,7 @@@ static int send_fetch_request(struct fe
            server_supports_v2("server-option", 1)) {
                int i;
                for (i = 0; i < args->server_options->nr; i++)
-                       packet_write_fmt(fd_out, "server-option=%s",
+                       packet_buf_write(&req_buf, "server-option=%s",
                                         args->server_options->items[i].string);
        }
  
  
        /* Send request */
        packet_buf_flush(&req_buf);
 -      write_or_die(fd_out, req_buf.buf, req_buf.len);
 +      if (write_in_full(fd_out, req_buf.buf, req_buf.len) < 0)
 +              die_errno(_("unable to write request to remote"));
  
        strbuf_release(&req_buf);
        return ret;
@@@ -1255,11 -1250,9 +1255,11 @@@ static int process_acks(struct fetch_ne
  }
  
  static void receive_shallow_info(struct fetch_pack_args *args,
 -                               struct packet_reader *reader)
 +                               struct packet_reader *reader,
 +                               struct oid_array *shallows,
 +                               struct shallow_info *si)
  {
 -      int line_received = 0;
 +      int unshallow_received = 0;
  
        process_section_header(reader, "shallow-info", 0);
        while (packet_reader_read(reader) == PACKET_READ_NORMAL) {
                if (skip_prefix(reader->line, "shallow ", &arg)) {
                        if (get_oid_hex(arg, &oid))
                                die(_("invalid shallow line: %s"), reader->line);
 -                      register_shallow(the_repository, &oid);
 -                      line_received = 1;
 +                      oid_array_append(shallows, &oid);
                        continue;
                }
                if (skip_prefix(reader->line, "unshallow ", &arg)) {
                                die(_("error in object: %s"), reader->line);
                        if (unregister_shallow(&oid))
                                die(_("no shallow found: %s"), reader->line);
 -                      line_received = 1;
 +                      unshallow_received = 1;
                        continue;
                }
                die(_("expected shallow/unshallow, got %s"), reader->line);
            reader->status != PACKET_READ_DELIM)
                die(_("error processing shallow info: %d"), reader->status);
  
 -      if (line_received) {
 +      if (args->deepen || unshallow_received) {
 +              /*
 +               * Treat these as shallow lines caused by our depth settings.
 +               * In v0, these lines cannot cause refs to be rejected; do the
 +               * same.
 +               */
 +              int i;
 +
 +              for (i = 0; i < shallows->nr; i++)
 +                      register_shallow(the_repository, &shallows->oid[i]);
                setup_alternate_shallow(&shallow_lock, &alternate_shallow_file,
                                        NULL);
                args->deepen = 1;
 +      } else if (shallows->nr) {
 +              /*
 +               * Treat these as shallow lines caused by the remote being
 +               * shallow. In v0, remote refs that reach these objects are
 +               * rejected (unless --update-shallow is set); do the same.
 +               */
 +              prepare_shallow_info(si, shallows);
 +              if (si->nr_ours || si->nr_theirs)
 +                      alternate_shallow_file =
 +                              setup_temporary_shallow(si->shallow);
 +              else
 +                      alternate_shallow_file = NULL;
        } else {
                alternate_shallow_file = NULL;
        }
  }
  
 +static int cmp_name_ref(const void *name, const void *ref)
 +{
 +      return strcmp(name, (*(struct ref **)ref)->name);
 +}
 +
  static void receive_wanted_refs(struct packet_reader *reader,
                                struct ref **sought, int nr_sought)
  {
        while (packet_reader_read(reader) == PACKET_READ_NORMAL) {
                struct object_id oid;
                const char *end;
 -              int i;
 +              struct ref **found;
  
                if (parse_oid_hex(reader->line, &oid, &end) || *end++ != ' ')
                        die(_("expected wanted-ref, got '%s'"), reader->line);
  
 -              for (i = 0; i < nr_sought; i++) {
 -                      if (!strcmp(end, sought[i]->name)) {
 -                              oidcpy(&sought[i]->old_oid, &oid);
 -                              break;
 -                      }
 -              }
 -
 -              if (i == nr_sought)
 +              found = bsearch(end, sought, nr_sought, sizeof(*sought),
 +                              cmp_name_ref);
 +              if (!found)
                        die(_("unexpected wanted-ref: '%s'"), reader->line);
 +              oidcpy(&(*found)->old_oid, &oid);
        }
  
        if (reader->status != PACKET_READ_DELIM)
@@@ -1362,8 -1334,6 +1362,8 @@@ static struct ref *do_fetch_pack_v2(str
                                    int fd[2],
                                    const struct ref *orig_ref,
                                    struct ref **sought, int nr_sought,
 +                                  struct oid_array *shallows,
 +                                  struct shallow_info *si,
                                    char **pack_lockfile)
  {
        struct ref *ref = copy_ref_list(orig_ref);
                case FETCH_GET_PACK:
                        /* Check for shallow-info section */
                        if (process_section_header(&reader, "shallow-info", 1))
 -                              receive_shallow_info(args, &reader);
 +                              receive_shallow_info(args, &reader, shallows, si);
  
                        if (process_section_header(&reader, "wanted-refs", 1))
                                receive_wanted_refs(&reader, sought, nr_sought);
@@@ -1642,8 -1612,9 +1642,8 @@@ static int iterate_ref_map(void *cb_dat
  }
  
  struct ref *fetch_pack(struct fetch_pack_args *args,
 -                     int fd[], struct child_process *conn,
 +                     int fd[],
                       const struct ref *ref,
 -                     const char *dest,
                       struct ref **sought, int nr_sought,
                       struct oid_array *shallow,
                       char **pack_lockfile,
  {
        struct ref *ref_cpy;
        struct shallow_info si;
 +      struct oid_array shallows_scratch = OID_ARRAY_INIT;
  
        fetch_pack_setup();
        if (nr_sought)
                packet_flush(fd[1]);
                die(_("no matching remote head"));
        }
 -      prepare_shallow_info(&si, shallow);
 -      if (version == protocol_v2)
 +      if (version == protocol_v2) {
 +              if (shallow->nr)
 +                      BUG("Protocol V2 does not provide shallows at this point in the fetch");
 +              memset(&si, 0, sizeof(si));
                ref_cpy = do_fetch_pack_v2(args, fd, ref, sought, nr_sought,
 +                                         &shallows_scratch, &si,
                                           pack_lockfile);
 -      else
 +      } else {
 +              prepare_shallow_info(&si, shallow);
                ref_cpy = do_fetch_pack(args, fd, ref, sought, nr_sought,
                                        &si, pack_lockfile);
 +      }
        reprepare_packed_git(the_repository);
  
        if (!args->cloning && args->deepen) {
        update_shallow(args, sought, nr_sought, &si);
  cleanup:
        clear_shallow_info(&si);
 +      oid_array_clear(&shallows_scratch);
        return ref_cpy;
  }