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