On 02/27, Stefan Beller wrote:
> > +
> > + /* Add initial haves */
> > + ret = add_haves(&req_buf, in_vain);
>
> I like the shortness and conciseness of this send_fetch_request
> function as it makes clear what is happening over the wire, however
> I wonder if we can improve on that, still.
I'm sure there is more that can be micro optimized but I don't really
want to get distracted by redesigning this logic another time right now.
>
> The functions 'add_common' and 'add_haves' seem like they do the
> same (sending haves), except for different sets of oids.
>
> So I would imagine that a structure like
>
> {
> struct set haves = compute_haves_from(in_vain, common, ...);
> struct set wants = compute_wants&wants);
>
> request_capabilities(args)
> send_haves(&haves);
> send_wants(&wants);
> flush();
> }
>
> That way we would have an even more concise way of writing
> one request, and factoring out the business logic. (Coming up
> with the "right" haves is a heuristic that we plan on changing in
> the future, so we'd want to have that encapsulated into one function
> that computes all the haves?
>
> > +
> > +/*
> > + * Processes a section header in a server's response and checks if it
> > matches
> > + * `section`. If the value of `peek` is 1, the header line will be peeked
> > (and
> > + * not consumed); if 0, the line will be consumed and the function will
> > die if
> > + * the section header doesn't match what was expected.
> > + */
> > +static int process_section_header(struct packet_reader *reader,
> > + const char *section, int peek)
> > +{
> > + int ret;
> > +
> > + if (packet_reader_peek(reader) != PACKET_READ_NORMAL)
> > + die("error reading packet");
> > +
> > + ret = !strcmp(reader->line, section);
> > +
> > + if (!peek) {
> > + if (!ret)
> > + die("expected '%s', received '%s'",
> > + section, reader->line);
> > + packet_reader_read(reader);
> > + }
> > +
> > + return ret;
> > +}
> > +
> > +static int process_acks(struct packet_reader *reader, struct oidset
> > *common)
> > +{
> > + /* received */
> > + int received_ready = 0;
> > + int received_ack = 0;
> > +
> > + process_section_header(reader, "acknowledgments", 0);
> > + while (packet_reader_read(reader) == PACKET_READ_NORMAL) {
> > + const char *arg;
> > +
> > + if (!strcmp(reader->line, "NAK"))
> > + continue;
> > +
> > + if (skip_prefix(reader->line, "ACK ", &arg)) {
> > + struct object_id oid;
> > + if (!get_oid_hex(arg, &oid)) {
> > + struct commit *commit;
> > + oidset_insert(common, &oid);
> > + commit = lookup_commit(&oid);
> > + mark_common(commit, 0, 1);
> > + }
> > + continue;
> > + }
> > +
> > + if (!strcmp(reader->line, "ready")) {
> > + clear_prio_queue(&rev_list);
> > + received_ready = 1;
> > + continue;
> > + }
> > +
> > + die(_("git fetch-pack: expected ACK/NAK, got '%s'"),
> > reader->line);
>
> This is slightly misleading, it could also expect "ready" ?
I'll update this.
>
>
> > + }
> > +
> > + if (reader->status != PACKET_READ_FLUSH &&
> > + reader->status != PACKET_READ_DELIM)
> > + die("Error during processing acks: %d", reader->status);
>
> Why is this not translated unlike the one 5 lines prior to this?
> Do we expect these conditions to come up due to different
> root causes?
>
> > +static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
> > + int fd[2],
> > + const struct ref *orig_ref,
> > + struct ref **sought, int nr_sought,
> > + char **pack_lockfile)
> > +{
> > + struct ref *ref = copy_ref_list(orig_ref);
> > + enum fetch_state state = FETCH_CHECK_LOCAL;
> > + struct oidset common = OIDSET_INIT;
> > + struct packet_reader reader;
> > + int in_vain = 0;
> > + packet_reader_init(&reader, fd[0], NULL, 0,
> > + PACKET_READ_CHOMP_NEWLINE);
> > +
> > + while (state != FETCH_DONE) {
> > + switch (state) {
> > + case FETCH_CHECK_LOCAL:
> > + sort_ref_list(&ref, ref_compare_name);
> > + QSORT(sought, nr_sought, cmp_ref_by_name);
> > +
> > + /* v2 supports these by default */
>
> Is there a doc that says what is all on by default?
Yeah protocol-v2.txt should say all of that.
>
> Thanks,
> Stefan
--
Brandon Williams