builtin-fetch.con commit Use the asyncronous function infrastructure in builtin-fetch-pack.c. (088fab5)
   1/*
   2 * "git fetch"
   3 */
   4#include "cache.h"
   5#include "refs.h"
   6#include "commit.h"
   7#include "builtin.h"
   8#include "path-list.h"
   9#include "remote.h"
  10#include "transport.h"
  11
  12static const char fetch_usage[] = "git-fetch [-a | --append] [--upload-pack <upload-pack>] [-f | --force] [--no-tags] [-t | --tags] [-k | --keep] [-u | --update-head-ok] [--depth <depth>] [-v | --verbose] [<repository> <refspec>...]";
  13
  14static int append, force, tags, no_tags, update_head_ok, verbose, quiet;
  15static char *default_rla = NULL;
  16static struct transport *transport;
  17
  18static void unlock_pack(void)
  19{
  20        if (transport)
  21                transport_unlock_pack(transport);
  22}
  23
  24static void unlock_pack_on_signal(int signo)
  25{
  26        unlock_pack();
  27        signal(SIGINT, SIG_DFL);
  28        raise(signo);
  29}
  30
  31static void add_merge_config(struct ref **head,
  32                           struct ref *remote_refs,
  33                           struct branch *branch,
  34                           struct ref ***tail)
  35{
  36        int i;
  37
  38        for (i = 0; i < branch->merge_nr; i++) {
  39                struct ref *rm, **old_tail = *tail;
  40                struct refspec refspec;
  41
  42                for (rm = *head; rm; rm = rm->next) {
  43                        if (branch_merge_matches(branch, i, rm->name)) {
  44                                rm->merge = 1;
  45                                break;
  46                        }
  47                }
  48                if (rm)
  49                        continue;
  50
  51                /* Not fetched to a tracking branch?  We need to fetch
  52                 * it anyway to allow this branch's "branch.$name.merge"
  53                 * to be honored by git-pull.
  54                 */
  55                refspec.src = branch->merge[i]->src;
  56                refspec.dst = NULL;
  57                refspec.pattern = 0;
  58                refspec.force = 0;
  59                get_fetch_map(remote_refs, &refspec, tail);
  60                for (rm = *old_tail; rm; rm = rm->next)
  61                        rm->merge = 1;
  62        }
  63}
  64
  65static struct ref *get_ref_map(struct transport *transport,
  66                               struct refspec *refs, int ref_count, int tags,
  67                               int *autotags)
  68{
  69        int i;
  70        struct ref *rm;
  71        struct ref *ref_map = NULL;
  72        struct ref **tail = &ref_map;
  73
  74        struct ref *remote_refs = transport_get_remote_refs(transport);
  75
  76        if (ref_count || tags) {
  77                for (i = 0; i < ref_count; i++) {
  78                        get_fetch_map(remote_refs, &refs[i], &tail);
  79                        if (refs[i].dst && refs[i].dst[0])
  80                                *autotags = 1;
  81                }
  82                /* Merge everything on the command line, but not --tags */
  83                for (rm = ref_map; rm; rm = rm->next)
  84                        rm->merge = 1;
  85                if (tags) {
  86                        struct refspec refspec;
  87                        refspec.src = "refs/tags/";
  88                        refspec.dst = "refs/tags/";
  89                        refspec.pattern = 1;
  90                        refspec.force = 0;
  91                        get_fetch_map(remote_refs, &refspec, &tail);
  92                }
  93        } else {
  94                /* Use the defaults */
  95                struct remote *remote = transport->remote;
  96                struct branch *branch = branch_get(NULL);
  97                int has_merge = branch_has_merge_config(branch);
  98                if (remote && (remote->fetch_refspec_nr || has_merge)) {
  99                        for (i = 0; i < remote->fetch_refspec_nr; i++) {
 100                                get_fetch_map(remote_refs, &remote->fetch[i], &tail);
 101                                if (remote->fetch[i].dst &&
 102                                    remote->fetch[i].dst[0])
 103                                        *autotags = 1;
 104                                if (!i && !has_merge && ref_map &&
 105                                    !remote->fetch[0].pattern)
 106                                        ref_map->merge = 1;
 107                        }
 108                        /*
 109                         * if the remote we're fetching from is the same
 110                         * as given in branch.<name>.remote, we add the
 111                         * ref given in branch.<name>.merge, too.
 112                         */
 113                        if (has_merge && !strcmp(branch->remote_name,
 114                                                remote->name))
 115                                add_merge_config(&ref_map, remote_refs, branch, &tail);
 116                } else {
 117                        ref_map = get_remote_ref(remote_refs, "HEAD");
 118                        ref_map->merge = 1;
 119                }
 120        }
 121        ref_remove_duplicates(ref_map);
 122
 123        return ref_map;
 124}
 125
 126static void show_new(enum object_type type, unsigned char *sha1_new)
 127{
 128        fprintf(stderr, "  %s: %s\n", typename(type),
 129                find_unique_abbrev(sha1_new, DEFAULT_ABBREV));
 130}
 131
 132static int s_update_ref(const char *action,
 133                        struct ref *ref,
 134                        int check_old)
 135{
 136        char msg[1024];
 137        char *rla = getenv("GIT_REFLOG_ACTION");
 138        static struct ref_lock *lock;
 139
 140        if (!rla)
 141                rla = default_rla;
 142        snprintf(msg, sizeof(msg), "%s: %s", rla, action);
 143        lock = lock_any_ref_for_update(ref->name,
 144                                       check_old ? ref->old_sha1 : NULL, 0);
 145        if (!lock)
 146                return 1;
 147        if (write_ref_sha1(lock, ref->new_sha1, msg) < 0)
 148                return 1;
 149        return 0;
 150}
 151
 152static int update_local_ref(struct ref *ref,
 153                            const char *note,
 154                            int verbose)
 155{
 156        char oldh[41], newh[41];
 157        struct commit *current = NULL, *updated;
 158        enum object_type type;
 159        struct branch *current_branch = branch_get(NULL);
 160
 161        type = sha1_object_info(ref->new_sha1, NULL);
 162        if (type < 0)
 163                die("object %s not found", sha1_to_hex(ref->new_sha1));
 164
 165        if (!*ref->name) {
 166                /* Not storing */
 167                if (verbose) {
 168                        fprintf(stderr, "* fetched %s\n", note);
 169                        show_new(type, ref->new_sha1);
 170                }
 171                return 0;
 172        }
 173
 174        if (!hashcmp(ref->old_sha1, ref->new_sha1)) {
 175                if (verbose) {
 176                        fprintf(stderr, "* %s: same as %s\n",
 177                                ref->name, note);
 178                        show_new(type, ref->new_sha1);
 179                }
 180                return 0;
 181        }
 182
 183        if (current_branch &&
 184            !strcmp(ref->name, current_branch->name) &&
 185            !(update_head_ok || is_bare_repository()) &&
 186            !is_null_sha1(ref->old_sha1)) {
 187                /*
 188                 * If this is the head, and it's not okay to update
 189                 * the head, and the old value of the head isn't empty...
 190                 */
 191                fprintf(stderr,
 192                        " * %s: Cannot fetch into the current branch.\n",
 193                        ref->name);
 194                return 1;
 195        }
 196
 197        if (!is_null_sha1(ref->old_sha1) &&
 198            !prefixcmp(ref->name, "refs/tags/")) {
 199                fprintf(stderr, "* %s: updating with %s\n",
 200                        ref->name, note);
 201                show_new(type, ref->new_sha1);
 202                return s_update_ref("updating tag", ref, 0);
 203        }
 204
 205        current = lookup_commit_reference_gently(ref->old_sha1, 1);
 206        updated = lookup_commit_reference_gently(ref->new_sha1, 1);
 207        if (!current || !updated) {
 208                char *msg;
 209                if (!strncmp(ref->name, "refs/tags/", 10))
 210                        msg = "storing tag";
 211                else
 212                        msg = "storing head";
 213                fprintf(stderr, "* %s: storing %s\n",
 214                        ref->name, note);
 215                show_new(type, ref->new_sha1);
 216                return s_update_ref(msg, ref, 0);
 217        }
 218
 219        strcpy(oldh, find_unique_abbrev(current->object.sha1, DEFAULT_ABBREV));
 220        strcpy(newh, find_unique_abbrev(ref->new_sha1, DEFAULT_ABBREV));
 221
 222        if (in_merge_bases(current, &updated, 1)) {
 223                fprintf(stderr, "* %s: fast forward to %s\n",
 224                        ref->name, note);
 225                fprintf(stderr, "  old..new: %s..%s\n", oldh, newh);
 226                return s_update_ref("fast forward", ref, 1);
 227        }
 228        if (!force && !ref->force) {
 229                fprintf(stderr,
 230                        "* %s: not updating to non-fast forward %s\n",
 231                        ref->name, note);
 232                fprintf(stderr,
 233                        "  old...new: %s...%s\n", oldh, newh);
 234                return 1;
 235        }
 236        fprintf(stderr,
 237                "* %s: forcing update to non-fast forward %s\n",
 238                ref->name, note);
 239        fprintf(stderr, "  old...new: %s...%s\n", oldh, newh);
 240        return s_update_ref("forced-update", ref, 1);
 241}
 242
 243static void store_updated_refs(const char *url, struct ref *ref_map)
 244{
 245        FILE *fp;
 246        struct commit *commit;
 247        int url_len, i, note_len;
 248        char note[1024];
 249        const char *what, *kind;
 250        struct ref *rm;
 251
 252        fp = fopen(git_path("FETCH_HEAD"), "a");
 253        for (rm = ref_map; rm; rm = rm->next) {
 254                struct ref *ref = NULL;
 255
 256                if (rm->peer_ref) {
 257                        ref = xcalloc(1, sizeof(*ref) + strlen(rm->peer_ref->name) + 1);
 258                        strcpy(ref->name, rm->peer_ref->name);
 259                        hashcpy(ref->old_sha1, rm->peer_ref->old_sha1);
 260                        hashcpy(ref->new_sha1, rm->old_sha1);
 261                        ref->force = rm->peer_ref->force;
 262                }
 263
 264                commit = lookup_commit_reference_gently(rm->old_sha1, 1);
 265                if (!commit)
 266                        rm->merge = 0;
 267
 268                if (!strcmp(rm->name, "HEAD")) {
 269                        kind = "";
 270                        what = "";
 271                }
 272                else if (!prefixcmp(rm->name, "refs/heads/")) {
 273                        kind = "branch";
 274                        what = rm->name + 11;
 275                }
 276                else if (!prefixcmp(rm->name, "refs/tags/")) {
 277                        kind = "tag";
 278                        what = rm->name + 10;
 279                }
 280                else if (!prefixcmp(rm->name, "refs/remotes/")) {
 281                        kind = "remote branch";
 282                        what = rm->name + 13;
 283                }
 284                else {
 285                        kind = "";
 286                        what = rm->name;
 287                }
 288
 289                url_len = strlen(url);
 290                for (i = url_len - 1; url[i] == '/' && 0 <= i; i--)
 291                        ;
 292                url_len = i + 1;
 293                if (4 < i && !strncmp(".git", url + i - 3, 4))
 294                        url_len = i - 3;
 295
 296                note_len = 0;
 297                if (*what) {
 298                        if (*kind)
 299                                note_len += sprintf(note + note_len, "%s ",
 300                                                    kind);
 301                        note_len += sprintf(note + note_len, "'%s' of ", what);
 302                }
 303                note_len += sprintf(note + note_len, "%.*s", url_len, url);
 304                fprintf(fp, "%s\t%s\t%s\n",
 305                        sha1_to_hex(commit ? commit->object.sha1 :
 306                                    rm->old_sha1),
 307                        rm->merge ? "" : "not-for-merge",
 308                        note);
 309
 310                if (ref)
 311                        update_local_ref(ref, note, verbose);
 312        }
 313        fclose(fp);
 314}
 315
 316static int fetch_refs(struct transport *transport, struct ref *ref_map)
 317{
 318        int ret = transport_fetch_refs(transport, ref_map);
 319        if (!ret)
 320                store_updated_refs(transport->url, ref_map);
 321        transport_unlock_pack(transport);
 322        return ret;
 323}
 324
 325static int add_existing(const char *refname, const unsigned char *sha1,
 326                        int flag, void *cbdata)
 327{
 328        struct path_list *list = (struct path_list *)cbdata;
 329        path_list_insert(refname, list);
 330        return 0;
 331}
 332
 333static struct ref *find_non_local_tags(struct transport *transport,
 334                                       struct ref *fetch_map)
 335{
 336        static struct path_list existing_refs = { NULL, 0, 0, 0 };
 337        struct path_list new_refs = { NULL, 0, 0, 1 };
 338        char *ref_name;
 339        int ref_name_len;
 340        unsigned char *ref_sha1;
 341        struct ref *tag_ref;
 342        struct ref *rm = NULL;
 343        struct ref *ref_map = NULL;
 344        struct ref **tail = &ref_map;
 345        struct ref *ref;
 346
 347        for_each_ref(add_existing, &existing_refs);
 348        for (ref = transport_get_remote_refs(transport); ref; ref = ref->next) {
 349                if (prefixcmp(ref->name, "refs/tags"))
 350                        continue;
 351
 352                ref_name = xstrdup(ref->name);
 353                ref_name_len = strlen(ref_name);
 354                ref_sha1 = ref->old_sha1;
 355
 356                if (!strcmp(ref_name + ref_name_len - 3, "^{}")) {
 357                        ref_name[ref_name_len - 3] = 0;
 358                        tag_ref = transport_get_remote_refs(transport);
 359                        while (tag_ref) {
 360                                if (!strcmp(tag_ref->name, ref_name)) {
 361                                        ref_sha1 = tag_ref->old_sha1;
 362                                        break;
 363                                }
 364                                tag_ref = tag_ref->next;
 365                        }
 366                }
 367
 368                if (!path_list_has_path(&existing_refs, ref_name) &&
 369                    !path_list_has_path(&new_refs, ref_name) &&
 370                    lookup_object(ref->old_sha1)) {
 371                        fprintf(stderr, "Auto-following %s\n",
 372                                ref_name);
 373
 374                        path_list_insert(ref_name, &new_refs);
 375
 376                        rm = alloc_ref(strlen(ref_name) + 1);
 377                        strcpy(rm->name, ref_name);
 378                        rm->peer_ref = alloc_ref(strlen(ref_name) + 1);
 379                        strcpy(rm->peer_ref->name, ref_name);
 380                        hashcpy(rm->old_sha1, ref_sha1);
 381
 382                        *tail = rm;
 383                        tail = &rm->next;
 384                }
 385                free(ref_name);
 386        }
 387
 388        return ref_map;
 389}
 390
 391static int do_fetch(struct transport *transport,
 392                    struct refspec *refs, int ref_count)
 393{
 394        struct ref *ref_map, *fetch_map;
 395        struct ref *rm;
 396        int autotags = (transport->remote->fetch_tags == 1);
 397        if (transport->remote->fetch_tags == 2 && !no_tags)
 398                tags = 1;
 399        if (transport->remote->fetch_tags == -1)
 400                no_tags = 1;
 401
 402        if (!transport->get_refs_list || !transport->fetch)
 403                die("Don't know how to fetch from %s", transport->url);
 404
 405        /* if not appending, truncate FETCH_HEAD */
 406        if (!append)
 407                fclose(fopen(git_path("FETCH_HEAD"), "w"));
 408
 409        ref_map = get_ref_map(transport, refs, ref_count, tags, &autotags);
 410
 411        for (rm = ref_map; rm; rm = rm->next) {
 412                if (rm->peer_ref)
 413                        read_ref(rm->peer_ref->name, rm->peer_ref->old_sha1);
 414        }
 415
 416        if (fetch_refs(transport, ref_map)) {
 417                free_refs(ref_map);
 418                return 1;
 419        }
 420
 421        fetch_map = ref_map;
 422
 423        /* if neither --no-tags nor --tags was specified, do automated tag
 424         * following ... */
 425        if (!(tags || no_tags) && autotags) {
 426                ref_map = find_non_local_tags(transport, fetch_map);
 427                if (ref_map) {
 428                        transport_set_option(transport, TRANS_OPT_DEPTH, "0");
 429                        fetch_refs(transport, ref_map);
 430                }
 431                free_refs(ref_map);
 432        }
 433
 434        free_refs(fetch_map);
 435
 436        return 0;
 437}
 438
 439static void set_option(const char *name, const char *value)
 440{
 441        int r = transport_set_option(transport, name, value);
 442        if (r < 0)
 443                die("Option \"%s\" value \"%s\" is not valid for %s\n",
 444                        name, value, transport->url);
 445        if (r > 0)
 446                warning("Option \"%s\" is ignored for %s\n",
 447                        name, transport->url);
 448}
 449
 450int cmd_fetch(int argc, const char **argv, const char *prefix)
 451{
 452        struct remote *remote;
 453        int i, j, rla_offset;
 454        static const char **refs = NULL;
 455        int ref_nr = 0;
 456        int cmd_len = 0;
 457        const char *depth = NULL, *upload_pack = NULL;
 458        int keep = 0;
 459
 460        for (i = 1; i < argc; i++) {
 461                const char *arg = argv[i];
 462                cmd_len += strlen(arg);
 463
 464                if (arg[0] != '-')
 465                        break;
 466                if (!strcmp(arg, "--append") || !strcmp(arg, "-a")) {
 467                        append = 1;
 468                        continue;
 469                }
 470                if (!prefixcmp(arg, "--upload-pack=")) {
 471                        upload_pack = arg + 14;
 472                        continue;
 473                }
 474                if (!strcmp(arg, "--upload-pack")) {
 475                        i++;
 476                        if (i == argc)
 477                                usage(fetch_usage);
 478                        upload_pack = argv[i];
 479                        continue;
 480                }
 481                if (!strcmp(arg, "--force") || !strcmp(arg, "-f")) {
 482                        force = 1;
 483                        continue;
 484                }
 485                if (!strcmp(arg, "--no-tags")) {
 486                        no_tags = 1;
 487                        continue;
 488                }
 489                if (!strcmp(arg, "--tags") || !strcmp(arg, "-t")) {
 490                        tags = 1;
 491                        continue;
 492                }
 493                if (!strcmp(arg, "--keep") || !strcmp(arg, "-k")) {
 494                        keep = 1;
 495                        continue;
 496                }
 497                if (!strcmp(arg, "--update-head-ok") || !strcmp(arg, "-u")) {
 498                        update_head_ok = 1;
 499                        continue;
 500                }
 501                if (!prefixcmp(arg, "--depth=")) {
 502                        depth = arg + 8;
 503                        continue;
 504                }
 505                if (!strcmp(arg, "--depth")) {
 506                        i++;
 507                        if (i == argc)
 508                                usage(fetch_usage);
 509                        depth = argv[i];
 510                        continue;
 511                }
 512                if (!strcmp(arg, "--quiet")) {
 513                        quiet = 1;
 514                        continue;
 515                }
 516                if (!strcmp(arg, "--verbose") || !strcmp(arg, "-v")) {
 517                        verbose++;
 518                        continue;
 519                }
 520                usage(fetch_usage);
 521        }
 522
 523        for (j = i; j < argc; j++)
 524                cmd_len += strlen(argv[j]);
 525
 526        default_rla = xmalloc(cmd_len + 5 + argc + 1);
 527        sprintf(default_rla, "fetch");
 528        rla_offset = strlen(default_rla);
 529        for (j = 1; j < argc; j++) {
 530                sprintf(default_rla + rla_offset, " %s", argv[j]);
 531                rla_offset += strlen(argv[j]) + 1;
 532        }
 533
 534        if (i == argc)
 535                remote = remote_get(NULL);
 536        else
 537                remote = remote_get(argv[i++]);
 538
 539        transport = transport_get(remote, remote->url[0]);
 540        if (verbose >= 2)
 541                transport->verbose = 1;
 542        if (quiet)
 543                transport->verbose = -1;
 544        if (upload_pack)
 545                set_option(TRANS_OPT_UPLOADPACK, upload_pack);
 546        if (keep)
 547                set_option(TRANS_OPT_KEEP, "yes");
 548        if (depth)
 549                set_option(TRANS_OPT_DEPTH, depth);
 550
 551        if (!transport->url)
 552                die("Where do you want to fetch from today?");
 553
 554        if (i < argc) {
 555                int j = 0;
 556                refs = xcalloc(argc - i + 1, sizeof(const char *));
 557                while (i < argc) {
 558                        if (!strcmp(argv[i], "tag")) {
 559                                char *ref;
 560                                i++;
 561                                ref = xmalloc(strlen(argv[i]) * 2 + 22);
 562                                strcpy(ref, "refs/tags/");
 563                                strcat(ref, argv[i]);
 564                                strcat(ref, ":refs/tags/");
 565                                strcat(ref, argv[i]);
 566                                refs[j++] = ref;
 567                        } else
 568                                refs[j++] = argv[i];
 569                        i++;
 570                }
 571                refs[j] = NULL;
 572                ref_nr = j;
 573        }
 574
 575        signal(SIGINT, unlock_pack_on_signal);
 576        atexit(unlock_pack);
 577        return do_fetch(transport, parse_ref_spec(ref_nr, refs), ref_nr);
 578}