upload-pack.con commit Merge branch 'jt/fetch-pack-wanted-refs-optim' (abd7ccd)
   1#include "cache.h"
   2#include "config.h"
   3#include "refs.h"
   4#include "pkt-line.h"
   5#include "sideband.h"
   6#include "repository.h"
   7#include "object-store.h"
   8#include "tag.h"
   9#include "object.h"
  10#include "commit.h"
  11#include "diff.h"
  12#include "revision.h"
  13#include "list-objects.h"
  14#include "list-objects-filter.h"
  15#include "list-objects-filter-options.h"
  16#include "run-command.h"
  17#include "connect.h"
  18#include "sigchain.h"
  19#include "version.h"
  20#include "string-list.h"
  21#include "argv-array.h"
  22#include "prio-queue.h"
  23#include "protocol.h"
  24#include "quote.h"
  25#include "upload-pack.h"
  26#include "serve.h"
  27#include "commit-graph.h"
  28#include "commit-reach.h"
  29
  30/* Remember to update object flag allocation in object.h */
  31#define THEY_HAVE       (1u << 11)
  32#define OUR_REF         (1u << 12)
  33#define WANTED          (1u << 13)
  34#define COMMON_KNOWN    (1u << 14)
  35
  36#define SHALLOW         (1u << 16)
  37#define NOT_SHALLOW     (1u << 17)
  38#define CLIENT_SHALLOW  (1u << 18)
  39#define HIDDEN_REF      (1u << 19)
  40
  41#define ALL_FLAGS (THEY_HAVE | OUR_REF | WANTED | COMMON_KNOWN | SHALLOW | \
  42                NOT_SHALLOW | CLIENT_SHALLOW | HIDDEN_REF)
  43
  44static timestamp_t oldest_have;
  45
  46static int multi_ack;
  47static int no_done;
  48static int use_thin_pack, use_ofs_delta, use_include_tag;
  49static int no_progress, daemon_mode;
  50/* Allow specifying sha1 if it is a ref tip. */
  51#define ALLOW_TIP_SHA1  01
  52/* Allow request of a sha1 if it is reachable from a ref (possibly hidden ref). */
  53#define ALLOW_REACHABLE_SHA1    02
  54/* Allow request of any sha1. Implies ALLOW_TIP_SHA1 and ALLOW_REACHABLE_SHA1. */
  55#define ALLOW_ANY_SHA1  07
  56static unsigned int allow_unadvertised_object_request;
  57static int shallow_nr;
  58static struct object_array extra_edge_obj;
  59static unsigned int timeout;
  60static int keepalive = 5;
  61/* 0 for no sideband,
  62 * otherwise maximum packet size (up to 65520 bytes).
  63 */
  64static int use_sideband;
  65static int stateless_rpc;
  66static const char *pack_objects_hook;
  67
  68static int filter_capability_requested;
  69static int allow_filter;
  70static int allow_ref_in_want;
  71static struct list_objects_filter_options filter_options;
  72
  73static int allow_sideband_all;
  74
  75static void reset_timeout(void)
  76{
  77        alarm(timeout);
  78}
  79
  80static void send_client_data(int fd, const char *data, ssize_t sz)
  81{
  82        if (use_sideband) {
  83                send_sideband(1, fd, data, sz, use_sideband);
  84                return;
  85        }
  86        if (fd == 3)
  87                /* emergency quit */
  88                fd = 2;
  89        if (fd == 2) {
  90                /* XXX: are we happy to lose stuff here? */
  91                xwrite(fd, data, sz);
  92                return;
  93        }
  94        write_or_die(fd, data, sz);
  95}
  96
  97static int write_one_shallow(const struct commit_graft *graft, void *cb_data)
  98{
  99        FILE *fp = cb_data;
 100        if (graft->nr_parent == -1)
 101                fprintf(fp, "--shallow %s\n", oid_to_hex(&graft->oid));
 102        return 0;
 103}
 104
 105static void create_pack_file(const struct object_array *have_obj,
 106                             const struct object_array *want_obj)
 107{
 108        struct child_process pack_objects = CHILD_PROCESS_INIT;
 109        char data[8193], progress[128];
 110        char abort_msg[] = "aborting due to possible repository "
 111                "corruption on the remote side.";
 112        int buffered = -1;
 113        ssize_t sz;
 114        int i;
 115        FILE *pipe_fd;
 116
 117        if (!pack_objects_hook)
 118                pack_objects.git_cmd = 1;
 119        else {
 120                argv_array_push(&pack_objects.args, pack_objects_hook);
 121                argv_array_push(&pack_objects.args, "git");
 122                pack_objects.use_shell = 1;
 123        }
 124
 125        if (shallow_nr) {
 126                argv_array_push(&pack_objects.args, "--shallow-file");
 127                argv_array_push(&pack_objects.args, "");
 128        }
 129        argv_array_push(&pack_objects.args, "pack-objects");
 130        argv_array_push(&pack_objects.args, "--revs");
 131        if (use_thin_pack)
 132                argv_array_push(&pack_objects.args, "--thin");
 133
 134        argv_array_push(&pack_objects.args, "--stdout");
 135        if (shallow_nr)
 136                argv_array_push(&pack_objects.args, "--shallow");
 137        if (!no_progress)
 138                argv_array_push(&pack_objects.args, "--progress");
 139        if (use_ofs_delta)
 140                argv_array_push(&pack_objects.args, "--delta-base-offset");
 141        if (use_include_tag)
 142                argv_array_push(&pack_objects.args, "--include-tag");
 143        if (filter_options.filter_spec) {
 144                struct strbuf expanded_filter_spec = STRBUF_INIT;
 145                expand_list_objects_filter_spec(&filter_options,
 146                                                &expanded_filter_spec);
 147                if (pack_objects.use_shell) {
 148                        struct strbuf buf = STRBUF_INIT;
 149                        sq_quote_buf(&buf, expanded_filter_spec.buf);
 150                        argv_array_pushf(&pack_objects.args, "--filter=%s", buf.buf);
 151                        strbuf_release(&buf);
 152                } else {
 153                        argv_array_pushf(&pack_objects.args, "--filter=%s",
 154                                         expanded_filter_spec.buf);
 155                }
 156        }
 157
 158        pack_objects.in = -1;
 159        pack_objects.out = -1;
 160        pack_objects.err = -1;
 161
 162        if (start_command(&pack_objects))
 163                die("git upload-pack: unable to fork git-pack-objects");
 164
 165        pipe_fd = xfdopen(pack_objects.in, "w");
 166
 167        if (shallow_nr)
 168                for_each_commit_graft(write_one_shallow, pipe_fd);
 169
 170        for (i = 0; i < want_obj->nr; i++)
 171                fprintf(pipe_fd, "%s\n",
 172                        oid_to_hex(&want_obj->objects[i].item->oid));
 173        fprintf(pipe_fd, "--not\n");
 174        for (i = 0; i < have_obj->nr; i++)
 175                fprintf(pipe_fd, "%s\n",
 176                        oid_to_hex(&have_obj->objects[i].item->oid));
 177        for (i = 0; i < extra_edge_obj.nr; i++)
 178                fprintf(pipe_fd, "%s\n",
 179                        oid_to_hex(&extra_edge_obj.objects[i].item->oid));
 180        fprintf(pipe_fd, "\n");
 181        fflush(pipe_fd);
 182        fclose(pipe_fd);
 183
 184        /* We read from pack_objects.err to capture stderr output for
 185         * progress bar, and pack_objects.out to capture the pack data.
 186         */
 187
 188        while (1) {
 189                struct pollfd pfd[2];
 190                int pe, pu, pollsize;
 191                int ret;
 192
 193                reset_timeout();
 194
 195                pollsize = 0;
 196                pe = pu = -1;
 197
 198                if (0 <= pack_objects.out) {
 199                        pfd[pollsize].fd = pack_objects.out;
 200                        pfd[pollsize].events = POLLIN;
 201                        pu = pollsize;
 202                        pollsize++;
 203                }
 204                if (0 <= pack_objects.err) {
 205                        pfd[pollsize].fd = pack_objects.err;
 206                        pfd[pollsize].events = POLLIN;
 207                        pe = pollsize;
 208                        pollsize++;
 209                }
 210
 211                if (!pollsize)
 212                        break;
 213
 214                ret = poll(pfd, pollsize,
 215                        keepalive < 0 ? -1 : 1000 * keepalive);
 216
 217                if (ret < 0) {
 218                        if (errno != EINTR) {
 219                                error_errno("poll failed, resuming");
 220                                sleep(1);
 221                        }
 222                        continue;
 223                }
 224                if (0 <= pe && (pfd[pe].revents & (POLLIN|POLLHUP))) {
 225                        /* Status ready; we ship that in the side-band
 226                         * or dump to the standard error.
 227                         */
 228                        sz = xread(pack_objects.err, progress,
 229                                  sizeof(progress));
 230                        if (0 < sz)
 231                                send_client_data(2, progress, sz);
 232                        else if (sz == 0) {
 233                                close(pack_objects.err);
 234                                pack_objects.err = -1;
 235                        }
 236                        else
 237                                goto fail;
 238                        /* give priority to status messages */
 239                        continue;
 240                }
 241                if (0 <= pu && (pfd[pu].revents & (POLLIN|POLLHUP))) {
 242                        /* Data ready; we keep the last byte to ourselves
 243                         * in case we detect broken rev-list, so that we
 244                         * can leave the stream corrupted.  This is
 245                         * unfortunate -- unpack-objects would happily
 246                         * accept a valid packdata with trailing garbage,
 247                         * so appending garbage after we pass all the
 248                         * pack data is not good enough to signal
 249                         * breakage to downstream.
 250                         */
 251                        char *cp = data;
 252                        ssize_t outsz = 0;
 253                        if (0 <= buffered) {
 254                                *cp++ = buffered;
 255                                outsz++;
 256                        }
 257                        sz = xread(pack_objects.out, cp,
 258                                  sizeof(data) - outsz);
 259                        if (0 < sz)
 260                                ;
 261                        else if (sz == 0) {
 262                                close(pack_objects.out);
 263                                pack_objects.out = -1;
 264                        }
 265                        else
 266                                goto fail;
 267                        sz += outsz;
 268                        if (1 < sz) {
 269                                buffered = data[sz-1] & 0xFF;
 270                                sz--;
 271                        }
 272                        else
 273                                buffered = -1;
 274                        send_client_data(1, data, sz);
 275                }
 276
 277                /*
 278                 * We hit the keepalive timeout without saying anything; send
 279                 * an empty message on the data sideband just to let the other
 280                 * side know we're still working on it, but don't have any data
 281                 * yet.
 282                 *
 283                 * If we don't have a sideband channel, there's no room in the
 284                 * protocol to say anything, so those clients are just out of
 285                 * luck.
 286                 */
 287                if (!ret && use_sideband) {
 288                        static const char buf[] = "0005\1";
 289                        write_or_die(1, buf, 5);
 290                }
 291        }
 292
 293        if (finish_command(&pack_objects)) {
 294                error("git upload-pack: git-pack-objects died with error.");
 295                goto fail;
 296        }
 297
 298        /* flush the data */
 299        if (0 <= buffered) {
 300                data[0] = buffered;
 301                send_client_data(1, data, 1);
 302                fprintf(stderr, "flushed.\n");
 303        }
 304        if (use_sideband)
 305                packet_flush(1);
 306        return;
 307
 308 fail:
 309        send_client_data(3, abort_msg, sizeof(abort_msg));
 310        die("git upload-pack: %s", abort_msg);
 311}
 312
 313static int got_oid(const char *hex, struct object_id *oid,
 314                   struct object_array *have_obj)
 315{
 316        struct object *o;
 317        int we_knew_they_have = 0;
 318
 319        if (get_oid_hex(hex, oid))
 320                die("git upload-pack: expected SHA1 object, got '%s'", hex);
 321        if (!has_object_file(oid))
 322                return -1;
 323
 324        o = parse_object(the_repository, oid);
 325        if (!o)
 326                die("oops (%s)", oid_to_hex(oid));
 327        if (o->type == OBJ_COMMIT) {
 328                struct commit_list *parents;
 329                struct commit *commit = (struct commit *)o;
 330                if (o->flags & THEY_HAVE)
 331                        we_knew_they_have = 1;
 332                else
 333                        o->flags |= THEY_HAVE;
 334                if (!oldest_have || (commit->date < oldest_have))
 335                        oldest_have = commit->date;
 336                for (parents = commit->parents;
 337                     parents;
 338                     parents = parents->next)
 339                        parents->item->object.flags |= THEY_HAVE;
 340        }
 341        if (!we_knew_they_have) {
 342                add_object_array(o, NULL, have_obj);
 343                return 1;
 344        }
 345        return 0;
 346}
 347
 348static int ok_to_give_up(const struct object_array *have_obj,
 349                         struct object_array *want_obj)
 350{
 351        uint32_t min_generation = GENERATION_NUMBER_ZERO;
 352
 353        if (!have_obj->nr)
 354                return 0;
 355
 356        return can_all_from_reach_with_flag(want_obj, THEY_HAVE,
 357                                            COMMON_KNOWN, oldest_have,
 358                                            min_generation);
 359}
 360
 361static int get_common_commits(struct packet_reader *reader,
 362                              struct object_array *have_obj,
 363                              struct object_array *want_obj)
 364{
 365        struct object_id oid;
 366        char last_hex[GIT_MAX_HEXSZ + 1];
 367        int got_common = 0;
 368        int got_other = 0;
 369        int sent_ready = 0;
 370
 371        save_commit_buffer = 0;
 372
 373        for (;;) {
 374                const char *arg;
 375
 376                reset_timeout();
 377
 378                if (packet_reader_read(reader) != PACKET_READ_NORMAL) {
 379                        if (multi_ack == 2 && got_common
 380                            && !got_other && ok_to_give_up(have_obj, want_obj)) {
 381                                sent_ready = 1;
 382                                packet_write_fmt(1, "ACK %s ready\n", last_hex);
 383                        }
 384                        if (have_obj->nr == 0 || multi_ack)
 385                                packet_write_fmt(1, "NAK\n");
 386
 387                        if (no_done && sent_ready) {
 388                                packet_write_fmt(1, "ACK %s\n", last_hex);
 389                                return 0;
 390                        }
 391                        if (stateless_rpc)
 392                                exit(0);
 393                        got_common = 0;
 394                        got_other = 0;
 395                        continue;
 396                }
 397                if (skip_prefix(reader->line, "have ", &arg)) {
 398                        switch (got_oid(arg, &oid, have_obj)) {
 399                        case -1: /* they have what we do not */
 400                                got_other = 1;
 401                                if (multi_ack && ok_to_give_up(have_obj, want_obj)) {
 402                                        const char *hex = oid_to_hex(&oid);
 403                                        if (multi_ack == 2) {
 404                                                sent_ready = 1;
 405                                                packet_write_fmt(1, "ACK %s ready\n", hex);
 406                                        } else
 407                                                packet_write_fmt(1, "ACK %s continue\n", hex);
 408                                }
 409                                break;
 410                        default:
 411                                got_common = 1;
 412                                oid_to_hex_r(last_hex, &oid);
 413                                if (multi_ack == 2)
 414                                        packet_write_fmt(1, "ACK %s common\n", last_hex);
 415                                else if (multi_ack)
 416                                        packet_write_fmt(1, "ACK %s continue\n", last_hex);
 417                                else if (have_obj->nr == 1)
 418                                        packet_write_fmt(1, "ACK %s\n", last_hex);
 419                                break;
 420                        }
 421                        continue;
 422                }
 423                if (!strcmp(reader->line, "done")) {
 424                        if (have_obj->nr > 0) {
 425                                if (multi_ack)
 426                                        packet_write_fmt(1, "ACK %s\n", last_hex);
 427                                return 0;
 428                        }
 429                        packet_write_fmt(1, "NAK\n");
 430                        return -1;
 431                }
 432                die("git upload-pack: expected SHA1 list, got '%s'", reader->line);
 433        }
 434}
 435
 436static int is_our_ref(struct object *o)
 437{
 438        int allow_hidden_ref = (allow_unadvertised_object_request &
 439                        (ALLOW_TIP_SHA1 | ALLOW_REACHABLE_SHA1));
 440        return o->flags & ((allow_hidden_ref ? HIDDEN_REF : 0) | OUR_REF);
 441}
 442
 443/*
 444 * on successful case, it's up to the caller to close cmd->out
 445 */
 446static int do_reachable_revlist(struct child_process *cmd,
 447                                struct object_array *src,
 448                                struct object_array *reachable)
 449{
 450        static const char *argv[] = {
 451                "rev-list", "--stdin", NULL,
 452        };
 453        struct object *o;
 454        char namebuf[GIT_MAX_HEXSZ + 2]; /* ^ + hash + LF */
 455        int i;
 456        const unsigned hexsz = the_hash_algo->hexsz;
 457
 458        cmd->argv = argv;
 459        cmd->git_cmd = 1;
 460        cmd->no_stderr = 1;
 461        cmd->in = -1;
 462        cmd->out = -1;
 463
 464        /*
 465         * If the next rev-list --stdin encounters an unknown commit,
 466         * it terminates, which will cause SIGPIPE in the write loop
 467         * below.
 468         */
 469        sigchain_push(SIGPIPE, SIG_IGN);
 470
 471        if (start_command(cmd))
 472                goto error;
 473
 474        namebuf[0] = '^';
 475        namebuf[hexsz + 1] = '\n';
 476        for (i = get_max_object_index(); 0 < i; ) {
 477                o = get_indexed_object(--i);
 478                if (!o)
 479                        continue;
 480                if (reachable && o->type == OBJ_COMMIT)
 481                        o->flags &= ~TMP_MARK;
 482                if (!is_our_ref(o))
 483                        continue;
 484                memcpy(namebuf + 1, oid_to_hex(&o->oid), hexsz);
 485                if (write_in_full(cmd->in, namebuf, hexsz + 2) < 0)
 486                        goto error;
 487        }
 488        namebuf[hexsz] = '\n';
 489        for (i = 0; i < src->nr; i++) {
 490                o = src->objects[i].item;
 491                if (is_our_ref(o)) {
 492                        if (reachable)
 493                                add_object_array(o, NULL, reachable);
 494                        continue;
 495                }
 496                if (reachable && o->type == OBJ_COMMIT)
 497                        o->flags |= TMP_MARK;
 498                memcpy(namebuf, oid_to_hex(&o->oid), hexsz);
 499                if (write_in_full(cmd->in, namebuf, hexsz + 1) < 0)
 500                        goto error;
 501        }
 502        close(cmd->in);
 503        cmd->in = -1;
 504        sigchain_pop(SIGPIPE);
 505
 506        return 0;
 507
 508error:
 509        sigchain_pop(SIGPIPE);
 510
 511        if (cmd->in >= 0)
 512                close(cmd->in);
 513        if (cmd->out >= 0)
 514                close(cmd->out);
 515        return -1;
 516}
 517
 518static int get_reachable_list(struct object_array *src,
 519                              struct object_array *reachable)
 520{
 521        struct child_process cmd = CHILD_PROCESS_INIT;
 522        int i;
 523        struct object *o;
 524        char namebuf[GIT_MAX_HEXSZ + 2]; /* ^ + hash + LF */
 525        const unsigned hexsz = the_hash_algo->hexsz;
 526
 527        if (do_reachable_revlist(&cmd, src, reachable) < 0)
 528                return -1;
 529
 530        while ((i = read_in_full(cmd.out, namebuf, hexsz + 1)) == hexsz + 1) {
 531                struct object_id sha1;
 532                const char *p;
 533
 534                if (parse_oid_hex(namebuf, &sha1, &p) || *p != '\n')
 535                        break;
 536
 537                o = lookup_object(the_repository, sha1.hash);
 538                if (o && o->type == OBJ_COMMIT) {
 539                        o->flags &= ~TMP_MARK;
 540                }
 541        }
 542        for (i = get_max_object_index(); 0 < i; i--) {
 543                o = get_indexed_object(i - 1);
 544                if (o && o->type == OBJ_COMMIT &&
 545                    (o->flags & TMP_MARK)) {
 546                        add_object_array(o, NULL, reachable);
 547                                o->flags &= ~TMP_MARK;
 548                }
 549        }
 550        close(cmd.out);
 551
 552        if (finish_command(&cmd))
 553                return -1;
 554
 555        return 0;
 556}
 557
 558static int has_unreachable(struct object_array *src)
 559{
 560        struct child_process cmd = CHILD_PROCESS_INIT;
 561        char buf[1];
 562        int i;
 563
 564        if (do_reachable_revlist(&cmd, src, NULL) < 0)
 565                return 1;
 566
 567        /*
 568         * The commits out of the rev-list are not ancestors of
 569         * our ref.
 570         */
 571        i = read_in_full(cmd.out, buf, 1);
 572        if (i)
 573                goto error;
 574        close(cmd.out);
 575        cmd.out = -1;
 576
 577        /*
 578         * rev-list may have died by encountering a bad commit
 579         * in the history, in which case we do want to bail out
 580         * even when it showed no commit.
 581         */
 582        if (finish_command(&cmd))
 583                goto error;
 584
 585        /* All the non-tip ones are ancestors of what we advertised */
 586        return 0;
 587
 588error:
 589        sigchain_pop(SIGPIPE);
 590        if (cmd.out >= 0)
 591                close(cmd.out);
 592        return 1;
 593}
 594
 595static void check_non_tip(struct object_array *want_obj)
 596{
 597        int i;
 598
 599        /*
 600         * In the normal in-process case without
 601         * uploadpack.allowReachableSHA1InWant,
 602         * non-tip requests can never happen.
 603         */
 604        if (!stateless_rpc && !(allow_unadvertised_object_request & ALLOW_REACHABLE_SHA1))
 605                goto error;
 606        if (!has_unreachable(want_obj))
 607                /* All the non-tip ones are ancestors of what we advertised */
 608                return;
 609
 610error:
 611        /* Pick one of them (we know there at least is one) */
 612        for (i = 0; i < want_obj->nr; i++) {
 613                struct object *o = want_obj->objects[i].item;
 614                if (!is_our_ref(o))
 615                        die("git upload-pack: not our ref %s",
 616                            oid_to_hex(&o->oid));
 617        }
 618}
 619
 620static void send_shallow(struct packet_writer *writer,
 621                         struct commit_list *result)
 622{
 623        while (result) {
 624                struct object *object = &result->item->object;
 625                if (!(object->flags & (CLIENT_SHALLOW|NOT_SHALLOW))) {
 626                        packet_writer_write(writer, "shallow %s",
 627                                            oid_to_hex(&object->oid));
 628                        register_shallow(the_repository, &object->oid);
 629                        shallow_nr++;
 630                }
 631                result = result->next;
 632        }
 633}
 634
 635static void send_unshallow(struct packet_writer *writer,
 636                           const struct object_array *shallows,
 637                           struct object_array *want_obj)
 638{
 639        int i;
 640
 641        for (i = 0; i < shallows->nr; i++) {
 642                struct object *object = shallows->objects[i].item;
 643                if (object->flags & NOT_SHALLOW) {
 644                        struct commit_list *parents;
 645                        packet_writer_write(writer, "unshallow %s",
 646                                            oid_to_hex(&object->oid));
 647                        object->flags &= ~CLIENT_SHALLOW;
 648                        /*
 649                         * We want to _register_ "object" as shallow, but we
 650                         * also need to traverse object's parents to deepen a
 651                         * shallow clone. Unregister it for now so we can
 652                         * parse and add the parents to the want list, then
 653                         * re-register it.
 654                         */
 655                        unregister_shallow(&object->oid);
 656                        object->parsed = 0;
 657                        parse_commit_or_die((struct commit *)object);
 658                        parents = ((struct commit *)object)->parents;
 659                        while (parents) {
 660                                add_object_array(&parents->item->object,
 661                                                 NULL, want_obj);
 662                                parents = parents->next;
 663                        }
 664                        add_object_array(object, NULL, &extra_edge_obj);
 665                }
 666                /* make sure commit traversal conforms to client */
 667                register_shallow(the_repository, &object->oid);
 668        }
 669}
 670
 671static int check_ref(const char *refname_full, const struct object_id *oid,
 672                     int flag, void *cb_data);
 673static void deepen(struct packet_writer *writer, int depth, int deepen_relative,
 674                   struct object_array *shallows, struct object_array *want_obj)
 675{
 676        if (depth == INFINITE_DEPTH && !is_repository_shallow(the_repository)) {
 677                int i;
 678
 679                for (i = 0; i < shallows->nr; i++) {
 680                        struct object *object = shallows->objects[i].item;
 681                        object->flags |= NOT_SHALLOW;
 682                }
 683        } else if (deepen_relative) {
 684                struct object_array reachable_shallows = OBJECT_ARRAY_INIT;
 685                struct commit_list *result;
 686
 687                /*
 688                 * Checking for reachable shallows requires that our refs be
 689                 * marked with OUR_REF.
 690                 */
 691                head_ref_namespaced(check_ref, NULL);
 692                for_each_namespaced_ref(check_ref, NULL);
 693
 694                get_reachable_list(shallows, &reachable_shallows);
 695                result = get_shallow_commits(&reachable_shallows,
 696                                             depth + 1,
 697                                             SHALLOW, NOT_SHALLOW);
 698                send_shallow(writer, result);
 699                free_commit_list(result);
 700                object_array_clear(&reachable_shallows);
 701        } else {
 702                struct commit_list *result;
 703
 704                result = get_shallow_commits(want_obj, depth,
 705                                             SHALLOW, NOT_SHALLOW);
 706                send_shallow(writer, result);
 707                free_commit_list(result);
 708        }
 709
 710        send_unshallow(writer, shallows, want_obj);
 711}
 712
 713static void deepen_by_rev_list(struct packet_writer *writer, int ac,
 714                               const char **av,
 715                               struct object_array *shallows,
 716                               struct object_array *want_obj)
 717{
 718        struct commit_list *result;
 719
 720        close_commit_graph(the_repository);
 721        result = get_shallow_commits_by_rev_list(ac, av, SHALLOW, NOT_SHALLOW);
 722        send_shallow(writer, result);
 723        free_commit_list(result);
 724        send_unshallow(writer, shallows, want_obj);
 725}
 726
 727/* Returns 1 if a shallow list is sent or 0 otherwise */
 728static int send_shallow_list(struct packet_writer *writer,
 729                             int depth, int deepen_rev_list,
 730                             timestamp_t deepen_since,
 731                             struct string_list *deepen_not,
 732                             int deepen_relative,
 733                             struct object_array *shallows,
 734                             struct object_array *want_obj)
 735{
 736        int ret = 0;
 737
 738        if (depth > 0 && deepen_rev_list)
 739                die("git upload-pack: deepen and deepen-since (or deepen-not) cannot be used together");
 740        if (depth > 0) {
 741                deepen(writer, depth, deepen_relative, shallows, want_obj);
 742                ret = 1;
 743        } else if (deepen_rev_list) {
 744                struct argv_array av = ARGV_ARRAY_INIT;
 745                int i;
 746
 747                argv_array_push(&av, "rev-list");
 748                if (deepen_since)
 749                        argv_array_pushf(&av, "--max-age=%"PRItime, deepen_since);
 750                if (deepen_not->nr) {
 751                        argv_array_push(&av, "--not");
 752                        for (i = 0; i < deepen_not->nr; i++) {
 753                                struct string_list_item *s = deepen_not->items + i;
 754                                argv_array_push(&av, s->string);
 755                        }
 756                        argv_array_push(&av, "--not");
 757                }
 758                for (i = 0; i < want_obj->nr; i++) {
 759                        struct object *o = want_obj->objects[i].item;
 760                        argv_array_push(&av, oid_to_hex(&o->oid));
 761                }
 762                deepen_by_rev_list(writer, av.argc, av.argv, shallows, want_obj);
 763                argv_array_clear(&av);
 764                ret = 1;
 765        } else {
 766                if (shallows->nr > 0) {
 767                        int i;
 768                        for (i = 0; i < shallows->nr; i++)
 769                                register_shallow(the_repository,
 770                                                 &shallows->objects[i].item->oid);
 771                }
 772        }
 773
 774        shallow_nr += shallows->nr;
 775        return ret;
 776}
 777
 778static int process_shallow(const char *line, struct object_array *shallows)
 779{
 780        const char *arg;
 781        if (skip_prefix(line, "shallow ", &arg)) {
 782                struct object_id oid;
 783                struct object *object;
 784                if (get_oid_hex(arg, &oid))
 785                        die("invalid shallow line: %s", line);
 786                object = parse_object(the_repository, &oid);
 787                if (!object)
 788                        return 1;
 789                if (object->type != OBJ_COMMIT)
 790                        die("invalid shallow object %s", oid_to_hex(&oid));
 791                if (!(object->flags & CLIENT_SHALLOW)) {
 792                        object->flags |= CLIENT_SHALLOW;
 793                        add_object_array(object, NULL, shallows);
 794                }
 795                return 1;
 796        }
 797
 798        return 0;
 799}
 800
 801static int process_deepen(const char *line, int *depth)
 802{
 803        const char *arg;
 804        if (skip_prefix(line, "deepen ", &arg)) {
 805                char *end = NULL;
 806                *depth = (int)strtol(arg, &end, 0);
 807                if (!end || *end || *depth <= 0)
 808                        die("Invalid deepen: %s", line);
 809                return 1;
 810        }
 811
 812        return 0;
 813}
 814
 815static int process_deepen_since(const char *line, timestamp_t *deepen_since, int *deepen_rev_list)
 816{
 817        const char *arg;
 818        if (skip_prefix(line, "deepen-since ", &arg)) {
 819                char *end = NULL;
 820                *deepen_since = parse_timestamp(arg, &end, 0);
 821                if (!end || *end || !deepen_since ||
 822                    /* revisions.c's max_age -1 is special */
 823                    *deepen_since == -1)
 824                        die("Invalid deepen-since: %s", line);
 825                *deepen_rev_list = 1;
 826                return 1;
 827        }
 828        return 0;
 829}
 830
 831static int process_deepen_not(const char *line, struct string_list *deepen_not, int *deepen_rev_list)
 832{
 833        const char *arg;
 834        if (skip_prefix(line, "deepen-not ", &arg)) {
 835                char *ref = NULL;
 836                struct object_id oid;
 837                if (expand_ref(arg, strlen(arg), &oid, &ref) != 1)
 838                        die("git upload-pack: ambiguous deepen-not: %s", line);
 839                string_list_append(deepen_not, ref);
 840                free(ref);
 841                *deepen_rev_list = 1;
 842                return 1;
 843        }
 844        return 0;
 845}
 846
 847static void receive_needs(struct packet_reader *reader, struct object_array *want_obj)
 848{
 849        struct object_array shallows = OBJECT_ARRAY_INIT;
 850        struct string_list deepen_not = STRING_LIST_INIT_DUP;
 851        int depth = 0;
 852        int has_non_tip = 0;
 853        timestamp_t deepen_since = 0;
 854        int deepen_rev_list = 0;
 855        int deepen_relative = 0;
 856        struct packet_writer writer;
 857
 858        shallow_nr = 0;
 859        packet_writer_init(&writer, 1);
 860        for (;;) {
 861                struct object *o;
 862                const char *features;
 863                struct object_id oid_buf;
 864                const char *arg;
 865
 866                reset_timeout();
 867                if (packet_reader_read(reader) != PACKET_READ_NORMAL)
 868                        break;
 869
 870                if (process_shallow(reader->line, &shallows))
 871                        continue;
 872                if (process_deepen(reader->line, &depth))
 873                        continue;
 874                if (process_deepen_since(reader->line, &deepen_since, &deepen_rev_list))
 875                        continue;
 876                if (process_deepen_not(reader->line, &deepen_not, &deepen_rev_list))
 877                        continue;
 878
 879                if (skip_prefix(reader->line, "filter ", &arg)) {
 880                        if (!filter_capability_requested)
 881                                die("git upload-pack: filtering capability not negotiated");
 882                        parse_list_objects_filter(&filter_options, arg);
 883                        continue;
 884                }
 885
 886                if (!skip_prefix(reader->line, "want ", &arg) ||
 887                    parse_oid_hex(arg, &oid_buf, &features))
 888                        die("git upload-pack: protocol error, "
 889                            "expected to get object ID, not '%s'", reader->line);
 890
 891                if (parse_feature_request(features, "deepen-relative"))
 892                        deepen_relative = 1;
 893                if (parse_feature_request(features, "multi_ack_detailed"))
 894                        multi_ack = 2;
 895                else if (parse_feature_request(features, "multi_ack"))
 896                        multi_ack = 1;
 897                if (parse_feature_request(features, "no-done"))
 898                        no_done = 1;
 899                if (parse_feature_request(features, "thin-pack"))
 900                        use_thin_pack = 1;
 901                if (parse_feature_request(features, "ofs-delta"))
 902                        use_ofs_delta = 1;
 903                if (parse_feature_request(features, "side-band-64k"))
 904                        use_sideband = LARGE_PACKET_MAX;
 905                else if (parse_feature_request(features, "side-band"))
 906                        use_sideband = DEFAULT_PACKET_MAX;
 907                if (parse_feature_request(features, "no-progress"))
 908                        no_progress = 1;
 909                if (parse_feature_request(features, "include-tag"))
 910                        use_include_tag = 1;
 911                if (allow_filter && parse_feature_request(features, "filter"))
 912                        filter_capability_requested = 1;
 913
 914                o = parse_object(the_repository, &oid_buf);
 915                if (!o) {
 916                        packet_writer_error(&writer,
 917                                            "upload-pack: not our ref %s",
 918                                            oid_to_hex(&oid_buf));
 919                        die("git upload-pack: not our ref %s",
 920                            oid_to_hex(&oid_buf));
 921                }
 922                if (!(o->flags & WANTED)) {
 923                        o->flags |= WANTED;
 924                        if (!((allow_unadvertised_object_request & ALLOW_ANY_SHA1) == ALLOW_ANY_SHA1
 925                              || is_our_ref(o)))
 926                                has_non_tip = 1;
 927                        add_object_array(o, NULL, want_obj);
 928                }
 929        }
 930
 931        /*
 932         * We have sent all our refs already, and the other end
 933         * should have chosen out of them. When we are operating
 934         * in the stateless RPC mode, however, their choice may
 935         * have been based on the set of older refs advertised
 936         * by another process that handled the initial request.
 937         */
 938        if (has_non_tip)
 939                check_non_tip(want_obj);
 940
 941        if (!use_sideband && daemon_mode)
 942                no_progress = 1;
 943
 944        if (depth == 0 && !deepen_rev_list && shallows.nr == 0)
 945                return;
 946
 947        if (send_shallow_list(&writer, depth, deepen_rev_list, deepen_since,
 948                              &deepen_not, deepen_relative, &shallows,
 949                              want_obj))
 950                packet_flush(1);
 951        object_array_clear(&shallows);
 952}
 953
 954/* return non-zero if the ref is hidden, otherwise 0 */
 955static int mark_our_ref(const char *refname, const char *refname_full,
 956                        const struct object_id *oid)
 957{
 958        struct object *o = lookup_unknown_object(oid->hash);
 959
 960        if (ref_is_hidden(refname, refname_full)) {
 961                o->flags |= HIDDEN_REF;
 962                return 1;
 963        }
 964        o->flags |= OUR_REF;
 965        return 0;
 966}
 967
 968static int check_ref(const char *refname_full, const struct object_id *oid,
 969                     int flag, void *cb_data)
 970{
 971        const char *refname = strip_namespace(refname_full);
 972
 973        mark_our_ref(refname, refname_full, oid);
 974        return 0;
 975}
 976
 977static void format_symref_info(struct strbuf *buf, struct string_list *symref)
 978{
 979        struct string_list_item *item;
 980
 981        if (!symref->nr)
 982                return;
 983        for_each_string_list_item(item, symref)
 984                strbuf_addf(buf, " symref=%s:%s", item->string, (char *)item->util);
 985}
 986
 987static int send_ref(const char *refname, const struct object_id *oid,
 988                    int flag, void *cb_data)
 989{
 990        static const char *capabilities = "multi_ack thin-pack side-band"
 991                " side-band-64k ofs-delta shallow deepen-since deepen-not"
 992                " deepen-relative no-progress include-tag multi_ack_detailed";
 993        const char *refname_nons = strip_namespace(refname);
 994        struct object_id peeled;
 995
 996        if (mark_our_ref(refname_nons, refname, oid))
 997                return 0;
 998
 999        if (capabilities) {
1000                struct strbuf symref_info = STRBUF_INIT;
1001
1002                format_symref_info(&symref_info, cb_data);
1003                packet_write_fmt(1, "%s %s%c%s%s%s%s%s%s agent=%s\n",
1004                             oid_to_hex(oid), refname_nons,
1005                             0, capabilities,
1006                             (allow_unadvertised_object_request & ALLOW_TIP_SHA1) ?
1007                                     " allow-tip-sha1-in-want" : "",
1008                             (allow_unadvertised_object_request & ALLOW_REACHABLE_SHA1) ?
1009                                     " allow-reachable-sha1-in-want" : "",
1010                             stateless_rpc ? " no-done" : "",
1011                             symref_info.buf,
1012                             allow_filter ? " filter" : "",
1013                             git_user_agent_sanitized());
1014                strbuf_release(&symref_info);
1015        } else {
1016                packet_write_fmt(1, "%s %s\n", oid_to_hex(oid), refname_nons);
1017        }
1018        capabilities = NULL;
1019        if (!peel_ref(refname, &peeled))
1020                packet_write_fmt(1, "%s %s^{}\n", oid_to_hex(&peeled), refname_nons);
1021        return 0;
1022}
1023
1024static int find_symref(const char *refname, const struct object_id *oid,
1025                       int flag, void *cb_data)
1026{
1027        const char *symref_target;
1028        struct string_list_item *item;
1029
1030        if ((flag & REF_ISSYMREF) == 0)
1031                return 0;
1032        symref_target = resolve_ref_unsafe(refname, 0, NULL, &flag);
1033        if (!symref_target || (flag & REF_ISSYMREF) == 0)
1034                die("'%s' is a symref but it is not?", refname);
1035        item = string_list_append(cb_data, refname);
1036        item->util = xstrdup(symref_target);
1037        return 0;
1038}
1039
1040static int upload_pack_config(const char *var, const char *value, void *unused)
1041{
1042        if (!strcmp("uploadpack.allowtipsha1inwant", var)) {
1043                if (git_config_bool(var, value))
1044                        allow_unadvertised_object_request |= ALLOW_TIP_SHA1;
1045                else
1046                        allow_unadvertised_object_request &= ~ALLOW_TIP_SHA1;
1047        } else if (!strcmp("uploadpack.allowreachablesha1inwant", var)) {
1048                if (git_config_bool(var, value))
1049                        allow_unadvertised_object_request |= ALLOW_REACHABLE_SHA1;
1050                else
1051                        allow_unadvertised_object_request &= ~ALLOW_REACHABLE_SHA1;
1052        } else if (!strcmp("uploadpack.allowanysha1inwant", var)) {
1053                if (git_config_bool(var, value))
1054                        allow_unadvertised_object_request |= ALLOW_ANY_SHA1;
1055                else
1056                        allow_unadvertised_object_request &= ~ALLOW_ANY_SHA1;
1057        } else if (!strcmp("uploadpack.keepalive", var)) {
1058                keepalive = git_config_int(var, value);
1059                if (!keepalive)
1060                        keepalive = -1;
1061        } else if (!strcmp("uploadpack.allowfilter", var)) {
1062                allow_filter = git_config_bool(var, value);
1063        } else if (!strcmp("uploadpack.allowrefinwant", var)) {
1064                allow_ref_in_want = git_config_bool(var, value);
1065        } else if (!strcmp("uploadpack.allowsidebandall", var)) {
1066                allow_sideband_all = git_config_bool(var, value);
1067        }
1068
1069        if (current_config_scope() != CONFIG_SCOPE_REPO) {
1070                if (!strcmp("uploadpack.packobjectshook", var))
1071                        return git_config_string(&pack_objects_hook, var, value);
1072        }
1073
1074        return parse_hide_refs_config(var, value, "uploadpack");
1075}
1076
1077void upload_pack(struct upload_pack_options *options)
1078{
1079        struct string_list symref = STRING_LIST_INIT_DUP;
1080        struct object_array want_obj = OBJECT_ARRAY_INIT;
1081        struct packet_reader reader;
1082
1083        stateless_rpc = options->stateless_rpc;
1084        timeout = options->timeout;
1085        daemon_mode = options->daemon_mode;
1086
1087        git_config(upload_pack_config, NULL);
1088
1089        head_ref_namespaced(find_symref, &symref);
1090
1091        if (options->advertise_refs || !stateless_rpc) {
1092                reset_timeout();
1093                head_ref_namespaced(send_ref, &symref);
1094                for_each_namespaced_ref(send_ref, &symref);
1095                advertise_shallow_grafts(1);
1096                packet_flush(1);
1097        } else {
1098                head_ref_namespaced(check_ref, NULL);
1099                for_each_namespaced_ref(check_ref, NULL);
1100        }
1101        string_list_clear(&symref, 1);
1102        if (options->advertise_refs)
1103                return;
1104
1105        packet_reader_init(&reader, 0, NULL, 0,
1106                           PACKET_READ_CHOMP_NEWLINE |
1107                           PACKET_READ_DIE_ON_ERR_PACKET);
1108
1109        receive_needs(&reader, &want_obj);
1110        if (want_obj.nr) {
1111                struct object_array have_obj = OBJECT_ARRAY_INIT;
1112                get_common_commits(&reader, &have_obj, &want_obj);
1113                create_pack_file(&have_obj, &want_obj);
1114        }
1115}
1116
1117struct upload_pack_data {
1118        struct object_array wants;
1119        struct string_list wanted_refs;
1120        struct oid_array haves;
1121
1122        struct object_array shallows;
1123        struct string_list deepen_not;
1124        int depth;
1125        timestamp_t deepen_since;
1126        int deepen_rev_list;
1127        int deepen_relative;
1128
1129        struct packet_writer writer;
1130
1131        unsigned stateless_rpc : 1;
1132
1133        unsigned use_thin_pack : 1;
1134        unsigned use_ofs_delta : 1;
1135        unsigned no_progress : 1;
1136        unsigned use_include_tag : 1;
1137        unsigned done : 1;
1138};
1139
1140static void upload_pack_data_init(struct upload_pack_data *data)
1141{
1142        struct object_array wants = OBJECT_ARRAY_INIT;
1143        struct string_list wanted_refs = STRING_LIST_INIT_DUP;
1144        struct oid_array haves = OID_ARRAY_INIT;
1145        struct object_array shallows = OBJECT_ARRAY_INIT;
1146        struct string_list deepen_not = STRING_LIST_INIT_DUP;
1147
1148        memset(data, 0, sizeof(*data));
1149        data->wants = wants;
1150        data->wanted_refs = wanted_refs;
1151        data->haves = haves;
1152        data->shallows = shallows;
1153        data->deepen_not = deepen_not;
1154        packet_writer_init(&data->writer, 1);
1155}
1156
1157static void upload_pack_data_clear(struct upload_pack_data *data)
1158{
1159        object_array_clear(&data->wants);
1160        string_list_clear(&data->wanted_refs, 1);
1161        oid_array_clear(&data->haves);
1162        object_array_clear(&data->shallows);
1163        string_list_clear(&data->deepen_not, 0);
1164}
1165
1166static int parse_want(struct packet_writer *writer, const char *line,
1167                      struct object_array *want_obj)
1168{
1169        const char *arg;
1170        if (skip_prefix(line, "want ", &arg)) {
1171                struct object_id oid;
1172                struct object *o;
1173
1174                if (get_oid_hex(arg, &oid))
1175                        die("git upload-pack: protocol error, "
1176                            "expected to get oid, not '%s'", line);
1177
1178                o = parse_object(the_repository, &oid);
1179                if (!o) {
1180                        packet_writer_error(writer,
1181                                            "upload-pack: not our ref %s",
1182                                            oid_to_hex(&oid));
1183                        die("git upload-pack: not our ref %s",
1184                            oid_to_hex(&oid));
1185                }
1186
1187                if (!(o->flags & WANTED)) {
1188                        o->flags |= WANTED;
1189                        add_object_array(o, NULL, want_obj);
1190                }
1191
1192                return 1;
1193        }
1194
1195        return 0;
1196}
1197
1198static int parse_want_ref(struct packet_writer *writer, const char *line,
1199                          struct string_list *wanted_refs,
1200                          struct object_array *want_obj)
1201{
1202        const char *arg;
1203        if (skip_prefix(line, "want-ref ", &arg)) {
1204                struct object_id oid;
1205                struct string_list_item *item;
1206                struct object *o;
1207
1208                if (read_ref(arg, &oid)) {
1209                        packet_writer_error(writer, "unknown ref %s", arg);
1210                        die("unknown ref %s", arg);
1211                }
1212
1213                item = string_list_append(wanted_refs, arg);
1214                item->util = oiddup(&oid);
1215
1216                o = parse_object_or_die(&oid, arg);
1217                if (!(o->flags & WANTED)) {
1218                        o->flags |= WANTED;
1219                        add_object_array(o, NULL, want_obj);
1220                }
1221
1222                return 1;
1223        }
1224
1225        return 0;
1226}
1227
1228static int parse_have(const char *line, struct oid_array *haves)
1229{
1230        const char *arg;
1231        if (skip_prefix(line, "have ", &arg)) {
1232                struct object_id oid;
1233
1234                if (get_oid_hex(arg, &oid))
1235                        die("git upload-pack: expected SHA1 object, got '%s'", arg);
1236                oid_array_append(haves, &oid);
1237                return 1;
1238        }
1239
1240        return 0;
1241}
1242
1243static void process_args(struct packet_reader *request,
1244                         struct upload_pack_data *data,
1245                         struct object_array *want_obj)
1246{
1247        while (packet_reader_read(request) != PACKET_READ_FLUSH) {
1248                const char *arg = request->line;
1249                const char *p;
1250
1251                /* process want */
1252                if (parse_want(&data->writer, arg, want_obj))
1253                        continue;
1254                if (allow_ref_in_want &&
1255                    parse_want_ref(&data->writer, arg, &data->wanted_refs,
1256                                   want_obj))
1257                        continue;
1258                /* process have line */
1259                if (parse_have(arg, &data->haves))
1260                        continue;
1261
1262                /* process args like thin-pack */
1263                if (!strcmp(arg, "thin-pack")) {
1264                        use_thin_pack = 1;
1265                        continue;
1266                }
1267                if (!strcmp(arg, "ofs-delta")) {
1268                        use_ofs_delta = 1;
1269                        continue;
1270                }
1271                if (!strcmp(arg, "no-progress")) {
1272                        no_progress = 1;
1273                        continue;
1274                }
1275                if (!strcmp(arg, "include-tag")) {
1276                        use_include_tag = 1;
1277                        continue;
1278                }
1279                if (!strcmp(arg, "done")) {
1280                        data->done = 1;
1281                        continue;
1282                }
1283
1284                /* Shallow related arguments */
1285                if (process_shallow(arg, &data->shallows))
1286                        continue;
1287                if (process_deepen(arg, &data->depth))
1288                        continue;
1289                if (process_deepen_since(arg, &data->deepen_since,
1290                                         &data->deepen_rev_list))
1291                        continue;
1292                if (process_deepen_not(arg, &data->deepen_not,
1293                                       &data->deepen_rev_list))
1294                        continue;
1295                if (!strcmp(arg, "deepen-relative")) {
1296                        data->deepen_relative = 1;
1297                        continue;
1298                }
1299
1300                if (allow_filter && skip_prefix(arg, "filter ", &p)) {
1301                        parse_list_objects_filter(&filter_options, p);
1302                        continue;
1303                }
1304
1305                if ((git_env_bool("GIT_TEST_SIDEBAND_ALL", 0) ||
1306                     allow_sideband_all) &&
1307                    !strcmp(arg, "sideband-all")) {
1308                        data->writer.use_sideband = 1;
1309                        continue;
1310                }
1311
1312                /* ignore unknown lines maybe? */
1313                die("unexpected line: '%s'", arg);
1314        }
1315}
1316
1317static int process_haves(struct oid_array *haves, struct oid_array *common,
1318                         struct object_array *have_obj)
1319{
1320        int i;
1321
1322        /* Process haves */
1323        for (i = 0; i < haves->nr; i++) {
1324                const struct object_id *oid = &haves->oid[i];
1325                struct object *o;
1326                int we_knew_they_have = 0;
1327
1328                if (!has_object_file(oid))
1329                        continue;
1330
1331                oid_array_append(common, oid);
1332
1333                o = parse_object(the_repository, oid);
1334                if (!o)
1335                        die("oops (%s)", oid_to_hex(oid));
1336                if (o->type == OBJ_COMMIT) {
1337                        struct commit_list *parents;
1338                        struct commit *commit = (struct commit *)o;
1339                        if (o->flags & THEY_HAVE)
1340                                we_knew_they_have = 1;
1341                        else
1342                                o->flags |= THEY_HAVE;
1343                        if (!oldest_have || (commit->date < oldest_have))
1344                                oldest_have = commit->date;
1345                        for (parents = commit->parents;
1346                             parents;
1347                             parents = parents->next)
1348                                parents->item->object.flags |= THEY_HAVE;
1349                }
1350                if (!we_knew_they_have)
1351                        add_object_array(o, NULL, have_obj);
1352        }
1353
1354        return 0;
1355}
1356
1357static int send_acks(struct packet_writer *writer, struct oid_array *acks,
1358                     const struct object_array *have_obj,
1359                     struct object_array *want_obj)
1360{
1361        int i;
1362
1363        packet_writer_write(writer, "acknowledgments\n");
1364
1365        /* Send Acks */
1366        if (!acks->nr)
1367                packet_writer_write(writer, "NAK\n");
1368
1369        for (i = 0; i < acks->nr; i++) {
1370                packet_writer_write(writer, "ACK %s\n",
1371                                    oid_to_hex(&acks->oid[i]));
1372        }
1373
1374        if (ok_to_give_up(have_obj, want_obj)) {
1375                /* Send Ready */
1376                packet_writer_write(writer, "ready\n");
1377                return 1;
1378        }
1379
1380        return 0;
1381}
1382
1383static int process_haves_and_send_acks(struct upload_pack_data *data,
1384                                       struct object_array *have_obj,
1385                                       struct object_array *want_obj)
1386{
1387        struct oid_array common = OID_ARRAY_INIT;
1388        int ret = 0;
1389
1390        process_haves(&data->haves, &common, have_obj);
1391        if (data->done) {
1392                ret = 1;
1393        } else if (send_acks(&data->writer, &common, have_obj, want_obj)) {
1394                packet_writer_delim(&data->writer);
1395                ret = 1;
1396        } else {
1397                /* Add Flush */
1398                packet_writer_flush(&data->writer);
1399                ret = 0;
1400        }
1401
1402        oid_array_clear(&data->haves);
1403        oid_array_clear(&common);
1404        return ret;
1405}
1406
1407static void send_wanted_ref_info(struct upload_pack_data *data)
1408{
1409        const struct string_list_item *item;
1410
1411        if (!data->wanted_refs.nr)
1412                return;
1413
1414        packet_writer_write(&data->writer, "wanted-refs\n");
1415
1416        for_each_string_list_item(item, &data->wanted_refs) {
1417                packet_writer_write(&data->writer, "%s %s\n",
1418                                    oid_to_hex(item->util),
1419                                    item->string);
1420        }
1421
1422        packet_writer_delim(&data->writer);
1423}
1424
1425static void send_shallow_info(struct upload_pack_data *data,
1426                              struct object_array *want_obj)
1427{
1428        /* No shallow info needs to be sent */
1429        if (!data->depth && !data->deepen_rev_list && !data->shallows.nr &&
1430            !is_repository_shallow(the_repository))
1431                return;
1432
1433        packet_writer_write(&data->writer, "shallow-info\n");
1434
1435        if (!send_shallow_list(&data->writer, data->depth,
1436                               data->deepen_rev_list,
1437                               data->deepen_since, &data->deepen_not,
1438                               data->deepen_relative,
1439                               &data->shallows, want_obj) &&
1440            is_repository_shallow(the_repository))
1441                deepen(&data->writer, INFINITE_DEPTH, data->deepen_relative,
1442                       &data->shallows, want_obj);
1443
1444        packet_delim(1);
1445}
1446
1447enum fetch_state {
1448        FETCH_PROCESS_ARGS = 0,
1449        FETCH_SEND_ACKS,
1450        FETCH_SEND_PACK,
1451        FETCH_DONE,
1452};
1453
1454int upload_pack_v2(struct repository *r, struct argv_array *keys,
1455                   struct packet_reader *request)
1456{
1457        enum fetch_state state = FETCH_PROCESS_ARGS;
1458        struct upload_pack_data data;
1459        struct object_array have_obj = OBJECT_ARRAY_INIT;
1460        struct object_array want_obj = OBJECT_ARRAY_INIT;
1461
1462        clear_object_flags(ALL_FLAGS);
1463
1464        git_config(upload_pack_config, NULL);
1465
1466        upload_pack_data_init(&data);
1467        use_sideband = LARGE_PACKET_MAX;
1468
1469        while (state != FETCH_DONE) {
1470                switch (state) {
1471                case FETCH_PROCESS_ARGS:
1472                        process_args(request, &data, &want_obj);
1473
1474                        if (!want_obj.nr) {
1475                                /*
1476                                 * Request didn't contain any 'want' lines,
1477                                 * guess they didn't want anything.
1478                                 */
1479                                state = FETCH_DONE;
1480                        } else if (data.haves.nr) {
1481                                /*
1482                                 * Request had 'have' lines, so lets ACK them.
1483                                 */
1484                                state = FETCH_SEND_ACKS;
1485                        } else {
1486                                /*
1487                                 * Request had 'want's but no 'have's so we can
1488                                 * immedietly go to construct and send a pack.
1489                                 */
1490                                state = FETCH_SEND_PACK;
1491                        }
1492                        break;
1493                case FETCH_SEND_ACKS:
1494                        if (process_haves_and_send_acks(&data, &have_obj,
1495                                                        &want_obj))
1496                                state = FETCH_SEND_PACK;
1497                        else
1498                                state = FETCH_DONE;
1499                        break;
1500                case FETCH_SEND_PACK:
1501                        send_wanted_ref_info(&data);
1502                        send_shallow_info(&data, &want_obj);
1503
1504                        packet_writer_write(&data.writer, "packfile\n");
1505                        create_pack_file(&have_obj, &want_obj);
1506                        state = FETCH_DONE;
1507                        break;
1508                case FETCH_DONE:
1509                        continue;
1510                }
1511        }
1512
1513        upload_pack_data_clear(&data);
1514        object_array_clear(&have_obj);
1515        object_array_clear(&want_obj);
1516        return 0;
1517}
1518
1519int upload_pack_advertise(struct repository *r,
1520                          struct strbuf *value)
1521{
1522        if (value) {
1523                int allow_filter_value;
1524                int allow_ref_in_want;
1525                int allow_sideband_all_value;
1526
1527                strbuf_addstr(value, "shallow");
1528
1529                if (!repo_config_get_bool(the_repository,
1530                                         "uploadpack.allowfilter",
1531                                         &allow_filter_value) &&
1532                    allow_filter_value)
1533                        strbuf_addstr(value, " filter");
1534
1535                if (!repo_config_get_bool(the_repository,
1536                                         "uploadpack.allowrefinwant",
1537                                         &allow_ref_in_want) &&
1538                    allow_ref_in_want)
1539                        strbuf_addstr(value, " ref-in-want");
1540
1541                if (git_env_bool("GIT_TEST_SIDEBAND_ALL", 0) ||
1542                    (!repo_config_get_bool(the_repository,
1543                                           "uploadpack.allowsidebandall",
1544                                           &allow_sideband_all_value) &&
1545                     allow_sideband_all_value))
1546                        strbuf_addstr(value, " sideband-all");
1547        }
1548
1549        return 1;
1550}