upload-pack.con commit remote: add promisor and partial clone config to the doc (75de085)
   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                          struct packet_writer *writer)
 597{
 598        int i;
 599
 600        /*
 601         * In the normal in-process case without
 602         * uploadpack.allowReachableSHA1InWant,
 603         * non-tip requests can never happen.
 604         */
 605        if (!stateless_rpc && !(allow_unadvertised_object_request & ALLOW_REACHABLE_SHA1))
 606                goto error;
 607        if (!has_unreachable(want_obj))
 608                /* All the non-tip ones are ancestors of what we advertised */
 609                return;
 610
 611error:
 612        /* Pick one of them (we know there at least is one) */
 613        for (i = 0; i < want_obj->nr; i++) {
 614                struct object *o = want_obj->objects[i].item;
 615                if (!is_our_ref(o)) {
 616                        packet_writer_error(writer,
 617                                            "upload-pack: not our ref %s",
 618                                            oid_to_hex(&o->oid));
 619                        die("git upload-pack: not our ref %s",
 620                            oid_to_hex(&o->oid));
 621                }
 622        }
 623}
 624
 625static void send_shallow(struct packet_writer *writer,
 626                         struct commit_list *result)
 627{
 628        while (result) {
 629                struct object *object = &result->item->object;
 630                if (!(object->flags & (CLIENT_SHALLOW|NOT_SHALLOW))) {
 631                        packet_writer_write(writer, "shallow %s",
 632                                            oid_to_hex(&object->oid));
 633                        register_shallow(the_repository, &object->oid);
 634                        shallow_nr++;
 635                }
 636                result = result->next;
 637        }
 638}
 639
 640static void send_unshallow(struct packet_writer *writer,
 641                           const struct object_array *shallows,
 642                           struct object_array *want_obj)
 643{
 644        int i;
 645
 646        for (i = 0; i < shallows->nr; i++) {
 647                struct object *object = shallows->objects[i].item;
 648                if (object->flags & NOT_SHALLOW) {
 649                        struct commit_list *parents;
 650                        packet_writer_write(writer, "unshallow %s",
 651                                            oid_to_hex(&object->oid));
 652                        object->flags &= ~CLIENT_SHALLOW;
 653                        /*
 654                         * We want to _register_ "object" as shallow, but we
 655                         * also need to traverse object's parents to deepen a
 656                         * shallow clone. Unregister it for now so we can
 657                         * parse and add the parents to the want list, then
 658                         * re-register it.
 659                         */
 660                        unregister_shallow(&object->oid);
 661                        object->parsed = 0;
 662                        parse_commit_or_die((struct commit *)object);
 663                        parents = ((struct commit *)object)->parents;
 664                        while (parents) {
 665                                add_object_array(&parents->item->object,
 666                                                 NULL, want_obj);
 667                                parents = parents->next;
 668                        }
 669                        add_object_array(object, NULL, &extra_edge_obj);
 670                }
 671                /* make sure commit traversal conforms to client */
 672                register_shallow(the_repository, &object->oid);
 673        }
 674}
 675
 676static int check_ref(const char *refname_full, const struct object_id *oid,
 677                     int flag, void *cb_data);
 678static void deepen(struct packet_writer *writer, int depth, int deepen_relative,
 679                   struct object_array *shallows, struct object_array *want_obj)
 680{
 681        if (depth == INFINITE_DEPTH && !is_repository_shallow(the_repository)) {
 682                int i;
 683
 684                for (i = 0; i < shallows->nr; i++) {
 685                        struct object *object = shallows->objects[i].item;
 686                        object->flags |= NOT_SHALLOW;
 687                }
 688        } else if (deepen_relative) {
 689                struct object_array reachable_shallows = OBJECT_ARRAY_INIT;
 690                struct commit_list *result;
 691
 692                /*
 693                 * Checking for reachable shallows requires that our refs be
 694                 * marked with OUR_REF.
 695                 */
 696                head_ref_namespaced(check_ref, NULL);
 697                for_each_namespaced_ref(check_ref, NULL);
 698
 699                get_reachable_list(shallows, &reachable_shallows);
 700                result = get_shallow_commits(&reachable_shallows,
 701                                             depth + 1,
 702                                             SHALLOW, NOT_SHALLOW);
 703                send_shallow(writer, result);
 704                free_commit_list(result);
 705                object_array_clear(&reachable_shallows);
 706        } else {
 707                struct commit_list *result;
 708
 709                result = get_shallow_commits(want_obj, depth,
 710                                             SHALLOW, NOT_SHALLOW);
 711                send_shallow(writer, result);
 712                free_commit_list(result);
 713        }
 714
 715        send_unshallow(writer, shallows, want_obj);
 716}
 717
 718static void deepen_by_rev_list(struct packet_writer *writer, int ac,
 719                               const char **av,
 720                               struct object_array *shallows,
 721                               struct object_array *want_obj)
 722{
 723        struct commit_list *result;
 724
 725        close_commit_graph(the_repository);
 726        result = get_shallow_commits_by_rev_list(ac, av, SHALLOW, NOT_SHALLOW);
 727        send_shallow(writer, result);
 728        free_commit_list(result);
 729        send_unshallow(writer, shallows, want_obj);
 730}
 731
 732/* Returns 1 if a shallow list is sent or 0 otherwise */
 733static int send_shallow_list(struct packet_writer *writer,
 734                             int depth, int deepen_rev_list,
 735                             timestamp_t deepen_since,
 736                             struct string_list *deepen_not,
 737                             int deepen_relative,
 738                             struct object_array *shallows,
 739                             struct object_array *want_obj)
 740{
 741        int ret = 0;
 742
 743        if (depth > 0 && deepen_rev_list)
 744                die("git upload-pack: deepen and deepen-since (or deepen-not) cannot be used together");
 745        if (depth > 0) {
 746                deepen(writer, depth, deepen_relative, shallows, want_obj);
 747                ret = 1;
 748        } else if (deepen_rev_list) {
 749                struct argv_array av = ARGV_ARRAY_INIT;
 750                int i;
 751
 752                argv_array_push(&av, "rev-list");
 753                if (deepen_since)
 754                        argv_array_pushf(&av, "--max-age=%"PRItime, deepen_since);
 755                if (deepen_not->nr) {
 756                        argv_array_push(&av, "--not");
 757                        for (i = 0; i < deepen_not->nr; i++) {
 758                                struct string_list_item *s = deepen_not->items + i;
 759                                argv_array_push(&av, s->string);
 760                        }
 761                        argv_array_push(&av, "--not");
 762                }
 763                for (i = 0; i < want_obj->nr; i++) {
 764                        struct object *o = want_obj->objects[i].item;
 765                        argv_array_push(&av, oid_to_hex(&o->oid));
 766                }
 767                deepen_by_rev_list(writer, av.argc, av.argv, shallows, want_obj);
 768                argv_array_clear(&av);
 769                ret = 1;
 770        } else {
 771                if (shallows->nr > 0) {
 772                        int i;
 773                        for (i = 0; i < shallows->nr; i++)
 774                                register_shallow(the_repository,
 775                                                 &shallows->objects[i].item->oid);
 776                }
 777        }
 778
 779        shallow_nr += shallows->nr;
 780        return ret;
 781}
 782
 783static int process_shallow(const char *line, struct object_array *shallows)
 784{
 785        const char *arg;
 786        if (skip_prefix(line, "shallow ", &arg)) {
 787                struct object_id oid;
 788                struct object *object;
 789                if (get_oid_hex(arg, &oid))
 790                        die("invalid shallow line: %s", line);
 791                object = parse_object(the_repository, &oid);
 792                if (!object)
 793                        return 1;
 794                if (object->type != OBJ_COMMIT)
 795                        die("invalid shallow object %s", oid_to_hex(&oid));
 796                if (!(object->flags & CLIENT_SHALLOW)) {
 797                        object->flags |= CLIENT_SHALLOW;
 798                        add_object_array(object, NULL, shallows);
 799                }
 800                return 1;
 801        }
 802
 803        return 0;
 804}
 805
 806static int process_deepen(const char *line, int *depth)
 807{
 808        const char *arg;
 809        if (skip_prefix(line, "deepen ", &arg)) {
 810                char *end = NULL;
 811                *depth = (int)strtol(arg, &end, 0);
 812                if (!end || *end || *depth <= 0)
 813                        die("Invalid deepen: %s", line);
 814                return 1;
 815        }
 816
 817        return 0;
 818}
 819
 820static int process_deepen_since(const char *line, timestamp_t *deepen_since, int *deepen_rev_list)
 821{
 822        const char *arg;
 823        if (skip_prefix(line, "deepen-since ", &arg)) {
 824                char *end = NULL;
 825                *deepen_since = parse_timestamp(arg, &end, 0);
 826                if (!end || *end || !deepen_since ||
 827                    /* revisions.c's max_age -1 is special */
 828                    *deepen_since == -1)
 829                        die("Invalid deepen-since: %s", line);
 830                *deepen_rev_list = 1;
 831                return 1;
 832        }
 833        return 0;
 834}
 835
 836static int process_deepen_not(const char *line, struct string_list *deepen_not, int *deepen_rev_list)
 837{
 838        const char *arg;
 839        if (skip_prefix(line, "deepen-not ", &arg)) {
 840                char *ref = NULL;
 841                struct object_id oid;
 842                if (expand_ref(the_repository, arg, strlen(arg), &oid, &ref) != 1)
 843                        die("git upload-pack: ambiguous deepen-not: %s", line);
 844                string_list_append(deepen_not, ref);
 845                free(ref);
 846                *deepen_rev_list = 1;
 847                return 1;
 848        }
 849        return 0;
 850}
 851
 852static void receive_needs(struct packet_reader *reader, struct object_array *want_obj)
 853{
 854        struct object_array shallows = OBJECT_ARRAY_INIT;
 855        struct string_list deepen_not = STRING_LIST_INIT_DUP;
 856        int depth = 0;
 857        int has_non_tip = 0;
 858        timestamp_t deepen_since = 0;
 859        int deepen_rev_list = 0;
 860        int deepen_relative = 0;
 861        struct packet_writer writer;
 862
 863        shallow_nr = 0;
 864        packet_writer_init(&writer, 1);
 865        for (;;) {
 866                struct object *o;
 867                const char *features;
 868                struct object_id oid_buf;
 869                const char *arg;
 870
 871                reset_timeout();
 872                if (packet_reader_read(reader) != PACKET_READ_NORMAL)
 873                        break;
 874
 875                if (process_shallow(reader->line, &shallows))
 876                        continue;
 877                if (process_deepen(reader->line, &depth))
 878                        continue;
 879                if (process_deepen_since(reader->line, &deepen_since, &deepen_rev_list))
 880                        continue;
 881                if (process_deepen_not(reader->line, &deepen_not, &deepen_rev_list))
 882                        continue;
 883
 884                if (skip_prefix(reader->line, "filter ", &arg)) {
 885                        if (!filter_capability_requested)
 886                                die("git upload-pack: filtering capability not negotiated");
 887                        parse_list_objects_filter(&filter_options, arg);
 888                        continue;
 889                }
 890
 891                if (!skip_prefix(reader->line, "want ", &arg) ||
 892                    parse_oid_hex(arg, &oid_buf, &features))
 893                        die("git upload-pack: protocol error, "
 894                            "expected to get object ID, not '%s'", reader->line);
 895
 896                if (parse_feature_request(features, "deepen-relative"))
 897                        deepen_relative = 1;
 898                if (parse_feature_request(features, "multi_ack_detailed"))
 899                        multi_ack = 2;
 900                else if (parse_feature_request(features, "multi_ack"))
 901                        multi_ack = 1;
 902                if (parse_feature_request(features, "no-done"))
 903                        no_done = 1;
 904                if (parse_feature_request(features, "thin-pack"))
 905                        use_thin_pack = 1;
 906                if (parse_feature_request(features, "ofs-delta"))
 907                        use_ofs_delta = 1;
 908                if (parse_feature_request(features, "side-band-64k"))
 909                        use_sideband = LARGE_PACKET_MAX;
 910                else if (parse_feature_request(features, "side-band"))
 911                        use_sideband = DEFAULT_PACKET_MAX;
 912                if (parse_feature_request(features, "no-progress"))
 913                        no_progress = 1;
 914                if (parse_feature_request(features, "include-tag"))
 915                        use_include_tag = 1;
 916                if (allow_filter && parse_feature_request(features, "filter"))
 917                        filter_capability_requested = 1;
 918
 919                o = parse_object(the_repository, &oid_buf);
 920                if (!o) {
 921                        packet_writer_error(&writer,
 922                                            "upload-pack: not our ref %s",
 923                                            oid_to_hex(&oid_buf));
 924                        die("git upload-pack: not our ref %s",
 925                            oid_to_hex(&oid_buf));
 926                }
 927                if (!(o->flags & WANTED)) {
 928                        o->flags |= WANTED;
 929                        if (!((allow_unadvertised_object_request & ALLOW_ANY_SHA1) == ALLOW_ANY_SHA1
 930                              || is_our_ref(o)))
 931                                has_non_tip = 1;
 932                        add_object_array(o, NULL, want_obj);
 933                }
 934        }
 935
 936        /*
 937         * We have sent all our refs already, and the other end
 938         * should have chosen out of them. When we are operating
 939         * in the stateless RPC mode, however, their choice may
 940         * have been based on the set of older refs advertised
 941         * by another process that handled the initial request.
 942         */
 943        if (has_non_tip)
 944                check_non_tip(want_obj, &writer);
 945
 946        if (!use_sideband && daemon_mode)
 947                no_progress = 1;
 948
 949        if (depth == 0 && !deepen_rev_list && shallows.nr == 0)
 950                return;
 951
 952        if (send_shallow_list(&writer, depth, deepen_rev_list, deepen_since,
 953                              &deepen_not, deepen_relative, &shallows,
 954                              want_obj))
 955                packet_flush(1);
 956        object_array_clear(&shallows);
 957}
 958
 959/* return non-zero if the ref is hidden, otherwise 0 */
 960static int mark_our_ref(const char *refname, const char *refname_full,
 961                        const struct object_id *oid)
 962{
 963        struct object *o = lookup_unknown_object(oid->hash);
 964
 965        if (ref_is_hidden(refname, refname_full)) {
 966                o->flags |= HIDDEN_REF;
 967                return 1;
 968        }
 969        o->flags |= OUR_REF;
 970        return 0;
 971}
 972
 973static int check_ref(const char *refname_full, const struct object_id *oid,
 974                     int flag, void *cb_data)
 975{
 976        const char *refname = strip_namespace(refname_full);
 977
 978        mark_our_ref(refname, refname_full, oid);
 979        return 0;
 980}
 981
 982static void format_symref_info(struct strbuf *buf, struct string_list *symref)
 983{
 984        struct string_list_item *item;
 985
 986        if (!symref->nr)
 987                return;
 988        for_each_string_list_item(item, symref)
 989                strbuf_addf(buf, " symref=%s:%s", item->string, (char *)item->util);
 990}
 991
 992static int send_ref(const char *refname, const struct object_id *oid,
 993                    int flag, void *cb_data)
 994{
 995        static const char *capabilities = "multi_ack thin-pack side-band"
 996                " side-band-64k ofs-delta shallow deepen-since deepen-not"
 997                " deepen-relative no-progress include-tag multi_ack_detailed";
 998        const char *refname_nons = strip_namespace(refname);
 999        struct object_id peeled;
1000
1001        if (mark_our_ref(refname_nons, refname, oid))
1002                return 0;
1003
1004        if (capabilities) {
1005                struct strbuf symref_info = STRBUF_INIT;
1006
1007                format_symref_info(&symref_info, cb_data);
1008                packet_write_fmt(1, "%s %s%c%s%s%s%s%s%s agent=%s\n",
1009                             oid_to_hex(oid), refname_nons,
1010                             0, capabilities,
1011                             (allow_unadvertised_object_request & ALLOW_TIP_SHA1) ?
1012                                     " allow-tip-sha1-in-want" : "",
1013                             (allow_unadvertised_object_request & ALLOW_REACHABLE_SHA1) ?
1014                                     " allow-reachable-sha1-in-want" : "",
1015                             stateless_rpc ? " no-done" : "",
1016                             symref_info.buf,
1017                             allow_filter ? " filter" : "",
1018                             git_user_agent_sanitized());
1019                strbuf_release(&symref_info);
1020        } else {
1021                packet_write_fmt(1, "%s %s\n", oid_to_hex(oid), refname_nons);
1022        }
1023        capabilities = NULL;
1024        if (!peel_ref(refname, &peeled))
1025                packet_write_fmt(1, "%s %s^{}\n", oid_to_hex(&peeled), refname_nons);
1026        return 0;
1027}
1028
1029static int find_symref(const char *refname, const struct object_id *oid,
1030                       int flag, void *cb_data)
1031{
1032        const char *symref_target;
1033        struct string_list_item *item;
1034
1035        if ((flag & REF_ISSYMREF) == 0)
1036                return 0;
1037        symref_target = resolve_ref_unsafe(refname, 0, NULL, &flag);
1038        if (!symref_target || (flag & REF_ISSYMREF) == 0)
1039                die("'%s' is a symref but it is not?", refname);
1040        item = string_list_append(cb_data, strip_namespace(refname));
1041        item->util = xstrdup(strip_namespace(symref_target));
1042        return 0;
1043}
1044
1045static int upload_pack_config(const char *var, const char *value, void *unused)
1046{
1047        if (!strcmp("uploadpack.allowtipsha1inwant", var)) {
1048                if (git_config_bool(var, value))
1049                        allow_unadvertised_object_request |= ALLOW_TIP_SHA1;
1050                else
1051                        allow_unadvertised_object_request &= ~ALLOW_TIP_SHA1;
1052        } else if (!strcmp("uploadpack.allowreachablesha1inwant", var)) {
1053                if (git_config_bool(var, value))
1054                        allow_unadvertised_object_request |= ALLOW_REACHABLE_SHA1;
1055                else
1056                        allow_unadvertised_object_request &= ~ALLOW_REACHABLE_SHA1;
1057        } else if (!strcmp("uploadpack.allowanysha1inwant", var)) {
1058                if (git_config_bool(var, value))
1059                        allow_unadvertised_object_request |= ALLOW_ANY_SHA1;
1060                else
1061                        allow_unadvertised_object_request &= ~ALLOW_ANY_SHA1;
1062        } else if (!strcmp("uploadpack.keepalive", var)) {
1063                keepalive = git_config_int(var, value);
1064                if (!keepalive)
1065                        keepalive = -1;
1066        } else if (!strcmp("uploadpack.allowfilter", var)) {
1067                allow_filter = git_config_bool(var, value);
1068        } else if (!strcmp("uploadpack.allowrefinwant", var)) {
1069                allow_ref_in_want = git_config_bool(var, value);
1070        } else if (!strcmp("uploadpack.allowsidebandall", var)) {
1071                allow_sideband_all = git_config_bool(var, value);
1072        } else if (!strcmp("core.precomposeunicode", var)) {
1073                precomposed_unicode = git_config_bool(var, value);
1074        }
1075
1076        if (current_config_scope() != CONFIG_SCOPE_REPO) {
1077                if (!strcmp("uploadpack.packobjectshook", var))
1078                        return git_config_string(&pack_objects_hook, var, value);
1079        }
1080
1081        return parse_hide_refs_config(var, value, "uploadpack");
1082}
1083
1084void upload_pack(struct upload_pack_options *options)
1085{
1086        struct string_list symref = STRING_LIST_INIT_DUP;
1087        struct object_array want_obj = OBJECT_ARRAY_INIT;
1088        struct packet_reader reader;
1089
1090        stateless_rpc = options->stateless_rpc;
1091        timeout = options->timeout;
1092        daemon_mode = options->daemon_mode;
1093
1094        git_config(upload_pack_config, NULL);
1095
1096        head_ref_namespaced(find_symref, &symref);
1097
1098        if (options->advertise_refs || !stateless_rpc) {
1099                reset_timeout();
1100                head_ref_namespaced(send_ref, &symref);
1101                for_each_namespaced_ref(send_ref, &symref);
1102                advertise_shallow_grafts(1);
1103                packet_flush(1);
1104        } else {
1105                head_ref_namespaced(check_ref, NULL);
1106                for_each_namespaced_ref(check_ref, NULL);
1107        }
1108        string_list_clear(&symref, 1);
1109        if (options->advertise_refs)
1110                return;
1111
1112        packet_reader_init(&reader, 0, NULL, 0,
1113                           PACKET_READ_CHOMP_NEWLINE |
1114                           PACKET_READ_DIE_ON_ERR_PACKET);
1115
1116        receive_needs(&reader, &want_obj);
1117        if (want_obj.nr) {
1118                struct object_array have_obj = OBJECT_ARRAY_INIT;
1119                get_common_commits(&reader, &have_obj, &want_obj);
1120                create_pack_file(&have_obj, &want_obj);
1121        }
1122}
1123
1124struct upload_pack_data {
1125        struct object_array wants;
1126        struct string_list wanted_refs;
1127        struct oid_array haves;
1128
1129        struct object_array shallows;
1130        struct string_list deepen_not;
1131        int depth;
1132        timestamp_t deepen_since;
1133        int deepen_rev_list;
1134        int deepen_relative;
1135
1136        struct packet_writer writer;
1137
1138        unsigned stateless_rpc : 1;
1139
1140        unsigned use_thin_pack : 1;
1141        unsigned use_ofs_delta : 1;
1142        unsigned no_progress : 1;
1143        unsigned use_include_tag : 1;
1144        unsigned done : 1;
1145};
1146
1147static void upload_pack_data_init(struct upload_pack_data *data)
1148{
1149        struct object_array wants = OBJECT_ARRAY_INIT;
1150        struct string_list wanted_refs = STRING_LIST_INIT_DUP;
1151        struct oid_array haves = OID_ARRAY_INIT;
1152        struct object_array shallows = OBJECT_ARRAY_INIT;
1153        struct string_list deepen_not = STRING_LIST_INIT_DUP;
1154
1155        memset(data, 0, sizeof(*data));
1156        data->wants = wants;
1157        data->wanted_refs = wanted_refs;
1158        data->haves = haves;
1159        data->shallows = shallows;
1160        data->deepen_not = deepen_not;
1161        packet_writer_init(&data->writer, 1);
1162}
1163
1164static void upload_pack_data_clear(struct upload_pack_data *data)
1165{
1166        object_array_clear(&data->wants);
1167        string_list_clear(&data->wanted_refs, 1);
1168        oid_array_clear(&data->haves);
1169        object_array_clear(&data->shallows);
1170        string_list_clear(&data->deepen_not, 0);
1171}
1172
1173static int parse_want(struct packet_writer *writer, const char *line,
1174                      struct object_array *want_obj)
1175{
1176        const char *arg;
1177        if (skip_prefix(line, "want ", &arg)) {
1178                struct object_id oid;
1179                struct object *o;
1180
1181                if (get_oid_hex(arg, &oid))
1182                        die("git upload-pack: protocol error, "
1183                            "expected to get oid, not '%s'", line);
1184
1185                o = parse_object(the_repository, &oid);
1186                if (!o) {
1187                        packet_writer_error(writer,
1188                                            "upload-pack: not our ref %s",
1189                                            oid_to_hex(&oid));
1190                        die("git upload-pack: not our ref %s",
1191                            oid_to_hex(&oid));
1192                }
1193
1194                if (!(o->flags & WANTED)) {
1195                        o->flags |= WANTED;
1196                        add_object_array(o, NULL, want_obj);
1197                }
1198
1199                return 1;
1200        }
1201
1202        return 0;
1203}
1204
1205static int parse_want_ref(struct packet_writer *writer, const char *line,
1206                          struct string_list *wanted_refs,
1207                          struct object_array *want_obj)
1208{
1209        const char *arg;
1210        if (skip_prefix(line, "want-ref ", &arg)) {
1211                struct object_id oid;
1212                struct string_list_item *item;
1213                struct object *o;
1214
1215                if (read_ref(arg, &oid)) {
1216                        packet_writer_error(writer, "unknown ref %s", arg);
1217                        die("unknown ref %s", arg);
1218                }
1219
1220                item = string_list_append(wanted_refs, arg);
1221                item->util = oiddup(&oid);
1222
1223                o = parse_object_or_die(&oid, arg);
1224                if (!(o->flags & WANTED)) {
1225                        o->flags |= WANTED;
1226                        add_object_array(o, NULL, want_obj);
1227                }
1228
1229                return 1;
1230        }
1231
1232        return 0;
1233}
1234
1235static int parse_have(const char *line, struct oid_array *haves)
1236{
1237        const char *arg;
1238        if (skip_prefix(line, "have ", &arg)) {
1239                struct object_id oid;
1240
1241                if (get_oid_hex(arg, &oid))
1242                        die("git upload-pack: expected SHA1 object, got '%s'", arg);
1243                oid_array_append(haves, &oid);
1244                return 1;
1245        }
1246
1247        return 0;
1248}
1249
1250static void process_args(struct packet_reader *request,
1251                         struct upload_pack_data *data,
1252                         struct object_array *want_obj)
1253{
1254        while (packet_reader_read(request) != PACKET_READ_FLUSH) {
1255                const char *arg = request->line;
1256                const char *p;
1257
1258                /* process want */
1259                if (parse_want(&data->writer, arg, want_obj))
1260                        continue;
1261                if (allow_ref_in_want &&
1262                    parse_want_ref(&data->writer, arg, &data->wanted_refs,
1263                                   want_obj))
1264                        continue;
1265                /* process have line */
1266                if (parse_have(arg, &data->haves))
1267                        continue;
1268
1269                /* process args like thin-pack */
1270                if (!strcmp(arg, "thin-pack")) {
1271                        use_thin_pack = 1;
1272                        continue;
1273                }
1274                if (!strcmp(arg, "ofs-delta")) {
1275                        use_ofs_delta = 1;
1276                        continue;
1277                }
1278                if (!strcmp(arg, "no-progress")) {
1279                        no_progress = 1;
1280                        continue;
1281                }
1282                if (!strcmp(arg, "include-tag")) {
1283                        use_include_tag = 1;
1284                        continue;
1285                }
1286                if (!strcmp(arg, "done")) {
1287                        data->done = 1;
1288                        continue;
1289                }
1290
1291                /* Shallow related arguments */
1292                if (process_shallow(arg, &data->shallows))
1293                        continue;
1294                if (process_deepen(arg, &data->depth))
1295                        continue;
1296                if (process_deepen_since(arg, &data->deepen_since,
1297                                         &data->deepen_rev_list))
1298                        continue;
1299                if (process_deepen_not(arg, &data->deepen_not,
1300                                       &data->deepen_rev_list))
1301                        continue;
1302                if (!strcmp(arg, "deepen-relative")) {
1303                        data->deepen_relative = 1;
1304                        continue;
1305                }
1306
1307                if (allow_filter && skip_prefix(arg, "filter ", &p)) {
1308                        parse_list_objects_filter(&filter_options, p);
1309                        continue;
1310                }
1311
1312                if ((git_env_bool("GIT_TEST_SIDEBAND_ALL", 0) ||
1313                     allow_sideband_all) &&
1314                    !strcmp(arg, "sideband-all")) {
1315                        data->writer.use_sideband = 1;
1316                        continue;
1317                }
1318
1319                /* ignore unknown lines maybe? */
1320                die("unexpected line: '%s'", arg);
1321        }
1322}
1323
1324static int process_haves(struct oid_array *haves, struct oid_array *common,
1325                         struct object_array *have_obj)
1326{
1327        int i;
1328
1329        /* Process haves */
1330        for (i = 0; i < haves->nr; i++) {
1331                const struct object_id *oid = &haves->oid[i];
1332                struct object *o;
1333                int we_knew_they_have = 0;
1334
1335                if (!has_object_file(oid))
1336                        continue;
1337
1338                oid_array_append(common, oid);
1339
1340                o = parse_object(the_repository, oid);
1341                if (!o)
1342                        die("oops (%s)", oid_to_hex(oid));
1343                if (o->type == OBJ_COMMIT) {
1344                        struct commit_list *parents;
1345                        struct commit *commit = (struct commit *)o;
1346                        if (o->flags & THEY_HAVE)
1347                                we_knew_they_have = 1;
1348                        else
1349                                o->flags |= THEY_HAVE;
1350                        if (!oldest_have || (commit->date < oldest_have))
1351                                oldest_have = commit->date;
1352                        for (parents = commit->parents;
1353                             parents;
1354                             parents = parents->next)
1355                                parents->item->object.flags |= THEY_HAVE;
1356                }
1357                if (!we_knew_they_have)
1358                        add_object_array(o, NULL, have_obj);
1359        }
1360
1361        return 0;
1362}
1363
1364static int send_acks(struct packet_writer *writer, struct oid_array *acks,
1365                     const struct object_array *have_obj,
1366                     struct object_array *want_obj)
1367{
1368        int i;
1369
1370        packet_writer_write(writer, "acknowledgments\n");
1371
1372        /* Send Acks */
1373        if (!acks->nr)
1374                packet_writer_write(writer, "NAK\n");
1375
1376        for (i = 0; i < acks->nr; i++) {
1377                packet_writer_write(writer, "ACK %s\n",
1378                                    oid_to_hex(&acks->oid[i]));
1379        }
1380
1381        if (ok_to_give_up(have_obj, want_obj)) {
1382                /* Send Ready */
1383                packet_writer_write(writer, "ready\n");
1384                return 1;
1385        }
1386
1387        return 0;
1388}
1389
1390static int process_haves_and_send_acks(struct upload_pack_data *data,
1391                                       struct object_array *have_obj,
1392                                       struct object_array *want_obj)
1393{
1394        struct oid_array common = OID_ARRAY_INIT;
1395        int ret = 0;
1396
1397        process_haves(&data->haves, &common, have_obj);
1398        if (data->done) {
1399                ret = 1;
1400        } else if (send_acks(&data->writer, &common, have_obj, want_obj)) {
1401                packet_writer_delim(&data->writer);
1402                ret = 1;
1403        } else {
1404                /* Add Flush */
1405                packet_writer_flush(&data->writer);
1406                ret = 0;
1407        }
1408
1409        oid_array_clear(&data->haves);
1410        oid_array_clear(&common);
1411        return ret;
1412}
1413
1414static void send_wanted_ref_info(struct upload_pack_data *data)
1415{
1416        const struct string_list_item *item;
1417
1418        if (!data->wanted_refs.nr)
1419                return;
1420
1421        packet_writer_write(&data->writer, "wanted-refs\n");
1422
1423        for_each_string_list_item(item, &data->wanted_refs) {
1424                packet_writer_write(&data->writer, "%s %s\n",
1425                                    oid_to_hex(item->util),
1426                                    item->string);
1427        }
1428
1429        packet_writer_delim(&data->writer);
1430}
1431
1432static void send_shallow_info(struct upload_pack_data *data,
1433                              struct object_array *want_obj)
1434{
1435        /* No shallow info needs to be sent */
1436        if (!data->depth && !data->deepen_rev_list && !data->shallows.nr &&
1437            !is_repository_shallow(the_repository))
1438                return;
1439
1440        packet_writer_write(&data->writer, "shallow-info\n");
1441
1442        if (!send_shallow_list(&data->writer, data->depth,
1443                               data->deepen_rev_list,
1444                               data->deepen_since, &data->deepen_not,
1445                               data->deepen_relative,
1446                               &data->shallows, want_obj) &&
1447            is_repository_shallow(the_repository))
1448                deepen(&data->writer, INFINITE_DEPTH, data->deepen_relative,
1449                       &data->shallows, want_obj);
1450
1451        packet_delim(1);
1452}
1453
1454enum fetch_state {
1455        FETCH_PROCESS_ARGS = 0,
1456        FETCH_SEND_ACKS,
1457        FETCH_SEND_PACK,
1458        FETCH_DONE,
1459};
1460
1461int upload_pack_v2(struct repository *r, struct argv_array *keys,
1462                   struct packet_reader *request)
1463{
1464        enum fetch_state state = FETCH_PROCESS_ARGS;
1465        struct upload_pack_data data;
1466        struct object_array have_obj = OBJECT_ARRAY_INIT;
1467        struct object_array want_obj = OBJECT_ARRAY_INIT;
1468
1469        clear_object_flags(ALL_FLAGS);
1470
1471        git_config(upload_pack_config, NULL);
1472
1473        upload_pack_data_init(&data);
1474        use_sideband = LARGE_PACKET_MAX;
1475
1476        while (state != FETCH_DONE) {
1477                switch (state) {
1478                case FETCH_PROCESS_ARGS:
1479                        process_args(request, &data, &want_obj);
1480
1481                        if (!want_obj.nr) {
1482                                /*
1483                                 * Request didn't contain any 'want' lines,
1484                                 * guess they didn't want anything.
1485                                 */
1486                                state = FETCH_DONE;
1487                        } else if (data.haves.nr) {
1488                                /*
1489                                 * Request had 'have' lines, so lets ACK them.
1490                                 */
1491                                state = FETCH_SEND_ACKS;
1492                        } else {
1493                                /*
1494                                 * Request had 'want's but no 'have's so we can
1495                                 * immedietly go to construct and send a pack.
1496                                 */
1497                                state = FETCH_SEND_PACK;
1498                        }
1499                        break;
1500                case FETCH_SEND_ACKS:
1501                        if (process_haves_and_send_acks(&data, &have_obj,
1502                                                        &want_obj))
1503                                state = FETCH_SEND_PACK;
1504                        else
1505                                state = FETCH_DONE;
1506                        break;
1507                case FETCH_SEND_PACK:
1508                        send_wanted_ref_info(&data);
1509                        send_shallow_info(&data, &want_obj);
1510
1511                        packet_writer_write(&data.writer, "packfile\n");
1512                        create_pack_file(&have_obj, &want_obj);
1513                        state = FETCH_DONE;
1514                        break;
1515                case FETCH_DONE:
1516                        continue;
1517                }
1518        }
1519
1520        upload_pack_data_clear(&data);
1521        object_array_clear(&have_obj);
1522        object_array_clear(&want_obj);
1523        return 0;
1524}
1525
1526int upload_pack_advertise(struct repository *r,
1527                          struct strbuf *value)
1528{
1529        if (value) {
1530                int allow_filter_value;
1531                int allow_ref_in_want;
1532                int allow_sideband_all_value;
1533
1534                strbuf_addstr(value, "shallow");
1535
1536                if (!repo_config_get_bool(the_repository,
1537                                         "uploadpack.allowfilter",
1538                                         &allow_filter_value) &&
1539                    allow_filter_value)
1540                        strbuf_addstr(value, " filter");
1541
1542                if (!repo_config_get_bool(the_repository,
1543                                         "uploadpack.allowrefinwant",
1544                                         &allow_ref_in_want) &&
1545                    allow_ref_in_want)
1546                        strbuf_addstr(value, " ref-in-want");
1547
1548                if (git_env_bool("GIT_TEST_SIDEBAND_ALL", 0) ||
1549                    (!repo_config_get_bool(the_repository,
1550                                           "uploadpack.allowsidebandall",
1551                                           &allow_sideband_all_value) &&
1552                     allow_sideband_all_value))
1553                        strbuf_addstr(value, " sideband-all");
1554        }
1555
1556        return 1;
1557}