fetch-pack.con commit send-pack/receive-pack: allow errors to be reported back to pusher. (cfee10a)
   1#include "cache.h"
   2#include "refs.h"
   3#include "pkt-line.h"
   4#include "commit.h"
   5#include "tag.h"
   6
   7static int keep_pack;
   8static int quiet;
   9static int verbose;
  10static const char fetch_pack_usage[] =
  11"git-fetch-pack [-q] [-v] [-k] [--exec=upload-pack] [host:]directory <refs>...";
  12static const char *exec = "git-upload-pack";
  13
  14#define COMPLETE        (1U << 0)
  15#define COMMON          (1U << 1)
  16#define COMMON_REF      (1U << 2)
  17#define SEEN            (1U << 3)
  18#define POPPED          (1U << 4)
  19
  20static struct commit_list *rev_list = NULL;
  21static int non_common_revs = 0, multi_ack = 0;
  22
  23static void rev_list_push(struct commit *commit, int mark)
  24{
  25        if (!(commit->object.flags & mark)) {
  26                commit->object.flags |= mark;
  27
  28                if (!(commit->object.parsed))
  29                        parse_commit(commit);
  30
  31                insert_by_date(commit, &rev_list);
  32
  33                if (!(commit->object.flags & COMMON))
  34                        non_common_revs++;
  35        }
  36}
  37
  38static int rev_list_insert_ref(const char *path, const unsigned char *sha1)
  39{
  40        struct object *o = deref_tag(parse_object(sha1), path, 0);
  41
  42        if (o && o->type == commit_type)
  43                rev_list_push((struct commit *)o, SEEN);
  44
  45        return 0;
  46}
  47
  48/*
  49   This function marks a rev and its ancestors as common.
  50   In some cases, it is desirable to mark only the ancestors (for example
  51   when only the server does not yet know that they are common).
  52*/
  53
  54static void mark_common(struct commit *commit,
  55                int ancestors_only, int dont_parse)
  56{
  57        if (commit != NULL && !(commit->object.flags & COMMON)) {
  58                struct object *o = (struct object *)commit;
  59
  60                if (!ancestors_only)
  61                        o->flags |= COMMON;
  62
  63                if (!(o->flags & SEEN))
  64                        rev_list_push(commit, SEEN);
  65                else {
  66                        struct commit_list *parents;
  67
  68                        if (!ancestors_only && !(o->flags & POPPED))
  69                                non_common_revs--;
  70                        if (!o->parsed && !dont_parse)
  71                                parse_commit(commit);
  72
  73                        for (parents = commit->parents;
  74                                        parents;
  75                                        parents = parents->next)
  76                                mark_common(parents->item, 0, dont_parse);
  77                }
  78        }
  79}
  80
  81/*
  82  Get the next rev to send, ignoring the common.
  83*/
  84
  85static const unsigned char* get_rev()
  86{
  87        struct commit *commit = NULL;
  88
  89        while (commit == NULL) {
  90                unsigned int mark;
  91                struct commit_list* parents;
  92
  93                if (rev_list == NULL || non_common_revs == 0)
  94                        return NULL;
  95
  96                commit = rev_list->item;
  97                if (!(commit->object.parsed))
  98                        parse_commit(commit);
  99                commit->object.flags |= POPPED;
 100                if (!(commit->object.flags & COMMON))
 101                        non_common_revs--;
 102        
 103                parents = commit->parents;
 104
 105                if (commit->object.flags & COMMON) {
 106                        /* do not send "have", and ignore ancestors */
 107                        commit = NULL;
 108                        mark = COMMON | SEEN;
 109                } else if (commit->object.flags & COMMON_REF)
 110                        /* send "have", and ignore ancestors */
 111                        mark = COMMON | SEEN;
 112                else
 113                        /* send "have", also for its ancestors */
 114                        mark = SEEN;
 115
 116                while (parents) {
 117                        if (!(parents->item->object.flags & SEEN))
 118                                rev_list_push(parents->item, mark);
 119                        if (mark & COMMON)
 120                                mark_common(parents->item, 1, 0);
 121                        parents = parents->next;
 122                }
 123
 124                rev_list = rev_list->next;
 125        }
 126
 127        return commit->object.sha1;
 128}
 129
 130static int find_common(int fd[2], unsigned char *result_sha1,
 131                       struct ref *refs)
 132{
 133        int fetching;
 134        int count = 0, flushes = 0, retval;
 135        const unsigned char *sha1;
 136
 137        for_each_ref(rev_list_insert_ref);
 138
 139        fetching = 0;
 140        for ( ; refs ; refs = refs->next) {
 141                unsigned char *remote = refs->old_sha1;
 142                struct object *o;
 143
 144                /*
 145                 * If that object is complete (i.e. it is an ancestor of a
 146                 * local ref), we tell them we have it but do not have to
 147                 * tell them about its ancestors, which they already know
 148                 * about.
 149                 *
 150                 * We use lookup_object here because we are only
 151                 * interested in the case we *know* the object is
 152                 * reachable and we have already scanned it.
 153                 */
 154                if (((o = lookup_object(remote)) != NULL) &&
 155                                (o->flags & COMPLETE)) {
 156                        continue;
 157                }
 158
 159                packet_write(fd[1], "want %s%s\n", sha1_to_hex(remote),
 160                        multi_ack ? " multi_ack" : "");
 161                fetching++;
 162        }
 163        packet_flush(fd[1]);
 164        if (!fetching)
 165                return 1;
 166
 167        flushes = 0;
 168        retval = -1;
 169        while ((sha1 = get_rev())) {
 170                packet_write(fd[1], "have %s\n", sha1_to_hex(sha1));
 171                if (verbose)
 172                        fprintf(stderr, "have %s\n", sha1_to_hex(sha1));
 173                if (!(31 & ++count)) {
 174                        int ack;
 175
 176                        packet_flush(fd[1]);
 177                        flushes++;
 178
 179                        /*
 180                         * We keep one window "ahead" of the other side, and
 181                         * will wait for an ACK only on the next one
 182                         */
 183                        if (count == 32)
 184                                continue;
 185
 186                        do {
 187                                ack = get_ack(fd[0], result_sha1);
 188                                if (verbose && ack)
 189                                        fprintf(stderr, "got ack %d %s\n", ack,
 190                                                        sha1_to_hex(result_sha1));
 191                                if (ack == 1) {
 192                                        flushes = 0;
 193                                        multi_ack = 0;
 194                                        retval = 0;
 195                                        goto done;
 196                                } else if (ack == 2) {
 197                                        struct commit *commit =
 198                                                lookup_commit(result_sha1);
 199                                        mark_common(commit, 0, 1);
 200                                        retval = 0;
 201                                }
 202                        } while (ack);
 203                        flushes--;
 204                }
 205        }
 206done:
 207        packet_write(fd[1], "done\n");
 208        if (verbose)
 209                fprintf(stderr, "done\n");
 210        if (retval != 0) {
 211                multi_ack = 0;
 212                flushes++;
 213        }
 214        while (flushes || multi_ack) {
 215                int ack = get_ack(fd[0], result_sha1);
 216                if (ack) {
 217                        if (verbose)
 218                                fprintf(stderr, "got ack (%d) %s\n", ack,
 219                                        sha1_to_hex(result_sha1));
 220                        if (ack == 1)
 221                                return 0;
 222                        multi_ack = 1;
 223                        continue;
 224                }
 225                flushes--;
 226        }
 227        return retval;
 228}
 229
 230static struct commit_list *complete = NULL;
 231
 232static int mark_complete(const char *path, const unsigned char *sha1)
 233{
 234        struct object *o = parse_object(sha1);
 235
 236        while (o && o->type == tag_type) {
 237                struct tag *t = (struct tag *) o;
 238                if (!t->tagged)
 239                        break; /* broken repository */
 240                o->flags |= COMPLETE;
 241                o = parse_object(t->tagged->sha1);
 242        }
 243        if (o && o->type == commit_type) {
 244                struct commit *commit = (struct commit *)o;
 245                commit->object.flags |= COMPLETE;
 246                insert_by_date(commit, &complete);
 247        }
 248        return 0;
 249}
 250
 251static void mark_recent_complete_commits(unsigned long cutoff)
 252{
 253        while (complete && cutoff <= complete->item->date) {
 254                if (verbose)
 255                        fprintf(stderr, "Marking %s as complete\n",
 256                                sha1_to_hex(complete->item->object.sha1));
 257                pop_most_recent_commit(&complete, COMPLETE);
 258        }
 259}
 260
 261static void filter_refs(struct ref **refs, int nr_match, char **match)
 262{
 263        struct ref *prev, *current, *next;
 264
 265        if (!nr_match)
 266                return;
 267
 268        for (prev = NULL, current = *refs; current; current = next) {
 269                next = current->next;
 270                if ((!memcmp(current->name, "refs/", 5) &&
 271                                        check_ref_format(current->name + 5)) ||
 272                                !path_match(current->name, nr_match, match)) {
 273                        if (prev == NULL)
 274                                *refs = next;
 275                        else
 276                                prev->next = next;
 277                        free(current);
 278                } else
 279                        prev = current;
 280        }
 281}
 282
 283static int everything_local(struct ref **refs, int nr_match, char **match)
 284{
 285        struct ref *ref;
 286        int retval;
 287        unsigned long cutoff = 0;
 288
 289        track_object_refs = 0;
 290        save_commit_buffer = 0;
 291
 292        for (ref = *refs; ref; ref = ref->next) {
 293                struct object *o;
 294
 295                o = parse_object(ref->old_sha1);
 296                if (!o)
 297                        continue;
 298
 299                /* We already have it -- which may mean that we were
 300                 * in sync with the other side at some time after
 301                 * that (it is OK if we guess wrong here).
 302                 */
 303                if (o->type == commit_type) {
 304                        struct commit *commit = (struct commit *)o;
 305                        if (!cutoff || cutoff < commit->date)
 306                                cutoff = commit->date;
 307                }
 308        }
 309
 310        for_each_ref(mark_complete);
 311        if (cutoff)
 312                mark_recent_complete_commits(cutoff);
 313
 314        /*
 315         * Mark all complete remote refs as common refs.
 316         * Don't mark them common yet; the server has to be told so first.
 317         */
 318        for (ref = *refs; ref; ref = ref->next) {
 319                struct object *o = deref_tag(lookup_object(ref->old_sha1),
 320                                             NULL, 0);
 321
 322                if (!o || o->type != commit_type || !(o->flags & COMPLETE))
 323                        continue;
 324
 325                if (!(o->flags & SEEN)) {
 326                        rev_list_push((struct commit *)o, COMMON_REF | SEEN);
 327
 328                        mark_common((struct commit *)o, 1, 1);
 329                }
 330        }
 331
 332        filter_refs(refs, nr_match, match);
 333
 334        for (retval = 1, ref = *refs; ref ; ref = ref->next) {
 335                const unsigned char *remote = ref->old_sha1;
 336                unsigned char local[20];
 337                struct object *o;
 338
 339                o = lookup_object(remote);
 340                if (!o || !(o->flags & COMPLETE)) {
 341                        retval = 0;
 342                        if (!verbose)
 343                                continue;
 344                        fprintf(stderr,
 345                                "want %s (%s)\n", sha1_to_hex(remote),
 346                                ref->name);
 347                        continue;
 348                }
 349
 350                memcpy(ref->new_sha1, local, 20);
 351                if (!verbose)
 352                        continue;
 353                fprintf(stderr,
 354                        "already have %s (%s)\n", sha1_to_hex(remote),
 355                        ref->name);
 356        }
 357        return retval;
 358}
 359
 360static int fetch_pack(int fd[2], int nr_match, char **match)
 361{
 362        struct ref *ref;
 363        unsigned char sha1[20];
 364        int status;
 365
 366        get_remote_heads(fd[0], &ref, 0, NULL, 0);
 367        if (server_supports("multi_ack")) {
 368                if (verbose)
 369                        fprintf(stderr, "Server supports multi_ack\n");
 370                multi_ack = 1;
 371        }
 372        if (!ref) {
 373                packet_flush(fd[1]);
 374                die("no matching remote head");
 375        }
 376        if (everything_local(&ref, nr_match, match)) {
 377                packet_flush(fd[1]);
 378                goto all_done;
 379        }
 380        if (find_common(fd, sha1, ref) < 0)
 381                fprintf(stderr, "warning: no common commits\n");
 382
 383        if (keep_pack)
 384                status = receive_keep_pack(fd, "git-fetch-pack");
 385        else
 386                status = receive_unpack_pack(fd, "git-fetch-pack", quiet);
 387
 388        if (status)
 389                die("git-fetch-pack: fetch failed.");
 390
 391 all_done:
 392        while (ref) {
 393                printf("%s %s\n",
 394                       sha1_to_hex(ref->old_sha1), ref->name);
 395                ref = ref->next;
 396        }
 397        return 0;
 398}
 399
 400int main(int argc, char **argv)
 401{
 402        int i, ret, nr_heads;
 403        char *dest = NULL, **heads;
 404        int fd[2];
 405        pid_t pid;
 406
 407        setup_git_directory();
 408
 409        nr_heads = 0;
 410        heads = NULL;
 411        for (i = 1; i < argc; i++) {
 412                char *arg = argv[i];
 413
 414                if (*arg == '-') {
 415                        if (!strncmp("--exec=", arg, 7)) {
 416                                exec = arg + 7;
 417                                continue;
 418                        }
 419                        if (!strcmp("--quiet", arg) || !strcmp("-q", arg)) {
 420                                quiet = 1;
 421                                continue;
 422                        }
 423                        if (!strcmp("--keep", arg) || !strcmp("-k", arg)) {
 424                                keep_pack = 1;
 425                                continue;
 426                        }
 427                        if (!strcmp("-v", arg)) {
 428                                verbose = 1;
 429                                continue;
 430                        }
 431                        usage(fetch_pack_usage);
 432                }
 433                dest = arg;
 434                heads = argv + i + 1;
 435                nr_heads = argc - i - 1;
 436                break;
 437        }
 438        if (!dest)
 439                usage(fetch_pack_usage);
 440        pid = git_connect(fd, dest, exec);
 441        if (pid < 0)
 442                return 1;
 443        ret = fetch_pack(fd, nr_heads, heads);
 444        close(fd[0]);
 445        close(fd[1]);
 446        finish_connect(pid);
 447
 448        if (!ret && nr_heads) {
 449                /* If the heads to pull were given, we should have
 450                 * consumed all of them by matching the remote.
 451                 * Otherwise, 'git-fetch remote no-such-ref' would
 452                 * silently succeed without issuing an error.
 453                 */
 454                for (i = 0; i < nr_heads; i++)
 455                        if (heads[i] && heads[i][0]) {
 456                                error("no such remote ref %s", heads[i]);
 457                                ret = 1;
 458                        }
 459        }
 460
 461        return ret;
 462}