builtin-send-pack.con commit move duplicated get_local_heads() to remote.c (454e202)
   1#include "cache.h"
   2#include "commit.h"
   3#include "tag.h"
   4#include "refs.h"
   5#include "pkt-line.h"
   6#include "run-command.h"
   7#include "remote.h"
   8#include "send-pack.h"
   9
  10static const char send_pack_usage[] =
  11"git send-pack [--all | --mirror] [--dry-run] [--force] [--receive-pack=<git-receive-pack>] [--verbose] [--thin] [<host>:]<directory> [<ref>...]\n"
  12"  --all and explicit <ref> specification are mutually exclusive.";
  13
  14static struct send_pack_args args = {
  15        /* .receivepack = */ "git-receive-pack",
  16};
  17
  18static int feed_object(const unsigned char *sha1, int fd, int negative)
  19{
  20        char buf[42];
  21
  22        if (negative && !has_sha1_file(sha1))
  23                return 1;
  24
  25        memcpy(buf + negative, sha1_to_hex(sha1), 40);
  26        if (negative)
  27                buf[0] = '^';
  28        buf[40 + negative] = '\n';
  29        return write_or_whine(fd, buf, 41 + negative, "send-pack: send refs");
  30}
  31
  32/*
  33 * Make a pack stream and spit it out into file descriptor fd
  34 */
  35static int pack_objects(int fd, struct ref *refs, struct extra_have_objects *extra)
  36{
  37        /*
  38         * The child becomes pack-objects --revs; we feed
  39         * the revision parameters to it via its stdin and
  40         * let its stdout go back to the other end.
  41         */
  42        const char *argv[] = {
  43                "pack-objects",
  44                "--all-progress",
  45                "--revs",
  46                "--stdout",
  47                NULL,
  48                NULL,
  49        };
  50        struct child_process po;
  51        int i;
  52
  53        if (args.use_thin_pack)
  54                argv[4] = "--thin";
  55        memset(&po, 0, sizeof(po));
  56        po.argv = argv;
  57        po.in = -1;
  58        po.out = fd;
  59        po.git_cmd = 1;
  60        if (start_command(&po))
  61                die("git pack-objects failed (%s)", strerror(errno));
  62
  63        /*
  64         * We feed the pack-objects we just spawned with revision
  65         * parameters by writing to the pipe.
  66         */
  67        for (i = 0; i < extra->nr; i++)
  68                if (!feed_object(extra->array[i], po.in, 1))
  69                        break;
  70
  71        while (refs) {
  72                if (!is_null_sha1(refs->old_sha1) &&
  73                    !feed_object(refs->old_sha1, po.in, 1))
  74                        break;
  75                if (!is_null_sha1(refs->new_sha1) &&
  76                    !feed_object(refs->new_sha1, po.in, 0))
  77                        break;
  78                refs = refs->next;
  79        }
  80
  81        close(po.in);
  82        if (finish_command(&po))
  83                return error("pack-objects died with strange error");
  84        return 0;
  85}
  86
  87static void unmark_and_free(struct commit_list *list, unsigned int mark)
  88{
  89        while (list) {
  90                struct commit_list *temp = list;
  91                temp->item->object.flags &= ~mark;
  92                list = temp->next;
  93                free(temp);
  94        }
  95}
  96
  97static int ref_newer(const unsigned char *new_sha1,
  98                     const unsigned char *old_sha1)
  99{
 100        struct object *o;
 101        struct commit *old, *new;
 102        struct commit_list *list, *used;
 103        int found = 0;
 104
 105        /* Both new and old must be commit-ish and new is descendant of
 106         * old.  Otherwise we require --force.
 107         */
 108        o = deref_tag(parse_object(old_sha1), NULL, 0);
 109        if (!o || o->type != OBJ_COMMIT)
 110                return 0;
 111        old = (struct commit *) o;
 112
 113        o = deref_tag(parse_object(new_sha1), NULL, 0);
 114        if (!o || o->type != OBJ_COMMIT)
 115                return 0;
 116        new = (struct commit *) o;
 117
 118        if (parse_commit(new) < 0)
 119                return 0;
 120
 121        used = list = NULL;
 122        commit_list_insert(new, &list);
 123        while (list) {
 124                new = pop_most_recent_commit(&list, 1);
 125                commit_list_insert(new, &used);
 126                if (new == old) {
 127                        found = 1;
 128                        break;
 129                }
 130        }
 131        unmark_and_free(list, 1);
 132        unmark_and_free(used, 1);
 133        return found;
 134}
 135
 136static struct ref *remote_refs, **remote_tail;
 137
 138static int receive_status(int in, struct ref *refs)
 139{
 140        struct ref *hint;
 141        char line[1000];
 142        int ret = 0;
 143        int len = packet_read_line(in, line, sizeof(line));
 144        if (len < 10 || memcmp(line, "unpack ", 7))
 145                return error("did not receive remote status");
 146        if (memcmp(line, "unpack ok\n", 10)) {
 147                char *p = line + strlen(line) - 1;
 148                if (*p == '\n')
 149                        *p = '\0';
 150                error("unpack failed: %s", line + 7);
 151                ret = -1;
 152        }
 153        hint = NULL;
 154        while (1) {
 155                char *refname;
 156                char *msg;
 157                len = packet_read_line(in, line, sizeof(line));
 158                if (!len)
 159                        break;
 160                if (len < 3 ||
 161                    (memcmp(line, "ok ", 3) && memcmp(line, "ng ", 3))) {
 162                        fprintf(stderr, "protocol error: %s\n", line);
 163                        ret = -1;
 164                        break;
 165                }
 166
 167                line[strlen(line)-1] = '\0';
 168                refname = line + 3;
 169                msg = strchr(refname, ' ');
 170                if (msg)
 171                        *msg++ = '\0';
 172
 173                /* first try searching at our hint, falling back to all refs */
 174                if (hint)
 175                        hint = find_ref_by_name(hint, refname);
 176                if (!hint)
 177                        hint = find_ref_by_name(refs, refname);
 178                if (!hint) {
 179                        warning("remote reported status on unknown ref: %s",
 180                                        refname);
 181                        continue;
 182                }
 183                if (hint->status != REF_STATUS_EXPECTING_REPORT) {
 184                        warning("remote reported status on unexpected ref: %s",
 185                                        refname);
 186                        continue;
 187                }
 188
 189                if (line[0] == 'o' && line[1] == 'k')
 190                        hint->status = REF_STATUS_OK;
 191                else {
 192                        hint->status = REF_STATUS_REMOTE_REJECT;
 193                        ret = -1;
 194                }
 195                if (msg)
 196                        hint->remote_status = xstrdup(msg);
 197                /* start our next search from the next ref */
 198                hint = hint->next;
 199        }
 200        return ret;
 201}
 202
 203static void update_tracking_ref(struct remote *remote, struct ref *ref)
 204{
 205        struct refspec rs;
 206
 207        if (ref->status != REF_STATUS_OK && ref->status != REF_STATUS_UPTODATE)
 208                return;
 209
 210        rs.src = ref->name;
 211        rs.dst = NULL;
 212
 213        if (!remote_find_tracking(remote, &rs)) {
 214                if (args.verbose)
 215                        fprintf(stderr, "updating local tracking ref '%s'\n", rs.dst);
 216                if (ref->deletion) {
 217                        delete_ref(rs.dst, NULL, 0);
 218                } else
 219                        update_ref("update by push", rs.dst,
 220                                        ref->new_sha1, NULL, 0, 0);
 221                free(rs.dst);
 222        }
 223}
 224
 225static const char *prettify_ref(const struct ref *ref)
 226{
 227        const char *name = ref->name;
 228        return name + (
 229                !prefixcmp(name, "refs/heads/") ? 11 :
 230                !prefixcmp(name, "refs/tags/") ? 10 :
 231                !prefixcmp(name, "refs/remotes/") ? 13 :
 232                0);
 233}
 234
 235#define SUMMARY_WIDTH (2 * DEFAULT_ABBREV + 3)
 236
 237static void print_ref_status(char flag, const char *summary, struct ref *to, struct ref *from, const char *msg)
 238{
 239        fprintf(stderr, " %c %-*s ", flag, SUMMARY_WIDTH, summary);
 240        if (from)
 241                fprintf(stderr, "%s -> %s", prettify_ref(from), prettify_ref(to));
 242        else
 243                fputs(prettify_ref(to), stderr);
 244        if (msg) {
 245                fputs(" (", stderr);
 246                fputs(msg, stderr);
 247                fputc(')', stderr);
 248        }
 249        fputc('\n', stderr);
 250}
 251
 252static const char *status_abbrev(unsigned char sha1[20])
 253{
 254        return find_unique_abbrev(sha1, DEFAULT_ABBREV);
 255}
 256
 257static void print_ok_ref_status(struct ref *ref)
 258{
 259        if (ref->deletion)
 260                print_ref_status('-', "[deleted]", ref, NULL, NULL);
 261        else if (is_null_sha1(ref->old_sha1))
 262                print_ref_status('*',
 263                        (!prefixcmp(ref->name, "refs/tags/") ? "[new tag]" :
 264                          "[new branch]"),
 265                        ref, ref->peer_ref, NULL);
 266        else {
 267                char quickref[84];
 268                char type;
 269                const char *msg;
 270
 271                strcpy(quickref, status_abbrev(ref->old_sha1));
 272                if (ref->nonfastforward) {
 273                        strcat(quickref, "...");
 274                        type = '+';
 275                        msg = "forced update";
 276                } else {
 277                        strcat(quickref, "..");
 278                        type = ' ';
 279                        msg = NULL;
 280                }
 281                strcat(quickref, status_abbrev(ref->new_sha1));
 282
 283                print_ref_status(type, quickref, ref, ref->peer_ref, msg);
 284        }
 285}
 286
 287static int print_one_push_status(struct ref *ref, const char *dest, int count)
 288{
 289        if (!count)
 290                fprintf(stderr, "To %s\n", dest);
 291
 292        switch(ref->status) {
 293        case REF_STATUS_NONE:
 294                print_ref_status('X', "[no match]", ref, NULL, NULL);
 295                break;
 296        case REF_STATUS_REJECT_NODELETE:
 297                print_ref_status('!', "[rejected]", ref, NULL,
 298                                "remote does not support deleting refs");
 299                break;
 300        case REF_STATUS_UPTODATE:
 301                print_ref_status('=', "[up to date]", ref,
 302                                ref->peer_ref, NULL);
 303                break;
 304        case REF_STATUS_REJECT_NONFASTFORWARD:
 305                print_ref_status('!', "[rejected]", ref, ref->peer_ref,
 306                                "non-fast forward");
 307                break;
 308        case REF_STATUS_REMOTE_REJECT:
 309                print_ref_status('!', "[remote rejected]", ref,
 310                                ref->deletion ? NULL : ref->peer_ref,
 311                                ref->remote_status);
 312                break;
 313        case REF_STATUS_EXPECTING_REPORT:
 314                print_ref_status('!', "[remote failure]", ref,
 315                                ref->deletion ? NULL : ref->peer_ref,
 316                                "remote failed to report status");
 317                break;
 318        case REF_STATUS_OK:
 319                print_ok_ref_status(ref);
 320                break;
 321        }
 322
 323        return 1;
 324}
 325
 326static void print_push_status(const char *dest, struct ref *refs)
 327{
 328        struct ref *ref;
 329        int n = 0;
 330
 331        if (args.verbose) {
 332                for (ref = refs; ref; ref = ref->next)
 333                        if (ref->status == REF_STATUS_UPTODATE)
 334                                n += print_one_push_status(ref, dest, n);
 335        }
 336
 337        for (ref = refs; ref; ref = ref->next)
 338                if (ref->status == REF_STATUS_OK)
 339                        n += print_one_push_status(ref, dest, n);
 340
 341        for (ref = refs; ref; ref = ref->next) {
 342                if (ref->status != REF_STATUS_NONE &&
 343                    ref->status != REF_STATUS_UPTODATE &&
 344                    ref->status != REF_STATUS_OK)
 345                        n += print_one_push_status(ref, dest, n);
 346        }
 347}
 348
 349static int refs_pushed(struct ref *ref)
 350{
 351        for (; ref; ref = ref->next) {
 352                switch(ref->status) {
 353                case REF_STATUS_NONE:
 354                case REF_STATUS_UPTODATE:
 355                        break;
 356                default:
 357                        return 1;
 358                }
 359        }
 360        return 0;
 361}
 362
 363static int do_send_pack(int in, int out, struct remote *remote, const char *dest, int nr_refspec, const char **refspec)
 364{
 365        struct ref *ref, *local_refs;
 366        int new_refs;
 367        int ask_for_status_report = 0;
 368        int allow_deleting_refs = 0;
 369        int expect_status_report = 0;
 370        int flags = MATCH_REFS_NONE;
 371        int ret;
 372        struct extra_have_objects extra_have;
 373
 374        memset(&extra_have, 0, sizeof(extra_have));
 375        if (args.send_all)
 376                flags |= MATCH_REFS_ALL;
 377        if (args.send_mirror)
 378                flags |= MATCH_REFS_MIRROR;
 379
 380        /* No funny business with the matcher */
 381        remote_tail = get_remote_heads(in, &remote_refs, 0, NULL, REF_NORMAL,
 382                                       &extra_have);
 383        local_refs = get_local_heads();
 384
 385        /* Does the other end support the reporting? */
 386        if (server_supports("report-status"))
 387                ask_for_status_report = 1;
 388        if (server_supports("delete-refs"))
 389                allow_deleting_refs = 1;
 390
 391        /* match them up */
 392        if (!remote_tail)
 393                remote_tail = &remote_refs;
 394        if (match_refs(local_refs, remote_refs, &remote_tail,
 395                       nr_refspec, refspec, flags)) {
 396                close(out);
 397                return -1;
 398        }
 399
 400        if (!remote_refs) {
 401                fprintf(stderr, "No refs in common and none specified; doing nothing.\n"
 402                        "Perhaps you should specify a branch such as 'master'.\n");
 403                close(out);
 404                return 0;
 405        }
 406
 407        /*
 408         * Finally, tell the other end!
 409         */
 410        new_refs = 0;
 411        for (ref = remote_refs; ref; ref = ref->next) {
 412
 413                if (ref->peer_ref)
 414                        hashcpy(ref->new_sha1, ref->peer_ref->new_sha1);
 415                else if (!args.send_mirror)
 416                        continue;
 417
 418                ref->deletion = is_null_sha1(ref->new_sha1);
 419                if (ref->deletion && !allow_deleting_refs) {
 420                        ref->status = REF_STATUS_REJECT_NODELETE;
 421                        continue;
 422                }
 423                if (!ref->deletion &&
 424                    !hashcmp(ref->old_sha1, ref->new_sha1)) {
 425                        ref->status = REF_STATUS_UPTODATE;
 426                        continue;
 427                }
 428
 429                /* This part determines what can overwrite what.
 430                 * The rules are:
 431                 *
 432                 * (0) you can always use --force or +A:B notation to
 433                 *     selectively force individual ref pairs.
 434                 *
 435                 * (1) if the old thing does not exist, it is OK.
 436                 *
 437                 * (2) if you do not have the old thing, you are not allowed
 438                 *     to overwrite it; you would not know what you are losing
 439                 *     otherwise.
 440                 *
 441                 * (3) if both new and old are commit-ish, and new is a
 442                 *     descendant of old, it is OK.
 443                 *
 444                 * (4) regardless of all of the above, removing :B is
 445                 *     always allowed.
 446                 */
 447
 448                ref->nonfastforward =
 449                    !ref->deletion &&
 450                    !is_null_sha1(ref->old_sha1) &&
 451                    (!has_sha1_file(ref->old_sha1)
 452                      || !ref_newer(ref->new_sha1, ref->old_sha1));
 453
 454                if (ref->nonfastforward && !ref->force && !args.force_update) {
 455                        ref->status = REF_STATUS_REJECT_NONFASTFORWARD;
 456                        continue;
 457                }
 458
 459                if (!ref->deletion)
 460                        new_refs++;
 461
 462                if (!args.dry_run) {
 463                        char *old_hex = sha1_to_hex(ref->old_sha1);
 464                        char *new_hex = sha1_to_hex(ref->new_sha1);
 465
 466                        if (ask_for_status_report) {
 467                                packet_write(out, "%s %s %s%c%s",
 468                                        old_hex, new_hex, ref->name, 0,
 469                                        "report-status");
 470                                ask_for_status_report = 0;
 471                                expect_status_report = 1;
 472                        }
 473                        else
 474                                packet_write(out, "%s %s %s",
 475                                        old_hex, new_hex, ref->name);
 476                }
 477                ref->status = expect_status_report ?
 478                        REF_STATUS_EXPECTING_REPORT :
 479                        REF_STATUS_OK;
 480        }
 481
 482        packet_flush(out);
 483        if (new_refs && !args.dry_run) {
 484                if (pack_objects(out, remote_refs, &extra_have) < 0)
 485                        return -1;
 486        }
 487        else
 488                close(out);
 489
 490        if (expect_status_report)
 491                ret = receive_status(in, remote_refs);
 492        else
 493                ret = 0;
 494
 495        print_push_status(dest, remote_refs);
 496
 497        if (!args.dry_run && remote) {
 498                for (ref = remote_refs; ref; ref = ref->next)
 499                        update_tracking_ref(remote, ref);
 500        }
 501
 502        if (!refs_pushed(remote_refs))
 503                fprintf(stderr, "Everything up-to-date\n");
 504        if (ret < 0)
 505                return ret;
 506        for (ref = remote_refs; ref; ref = ref->next) {
 507                switch (ref->status) {
 508                case REF_STATUS_NONE:
 509                case REF_STATUS_UPTODATE:
 510                case REF_STATUS_OK:
 511                        break;
 512                default:
 513                        return -1;
 514                }
 515        }
 516        return 0;
 517}
 518
 519static void verify_remote_names(int nr_heads, const char **heads)
 520{
 521        int i;
 522
 523        for (i = 0; i < nr_heads; i++) {
 524                const char *local = heads[i];
 525                const char *remote = strrchr(heads[i], ':');
 526
 527                if (*local == '+')
 528                        local++;
 529
 530                /* A matching refspec is okay.  */
 531                if (remote == local && remote[1] == '\0')
 532                        continue;
 533
 534                remote = remote ? (remote + 1) : local;
 535                switch (check_ref_format(remote)) {
 536                case 0: /* ok */
 537                case CHECK_REF_FORMAT_ONELEVEL:
 538                        /* ok but a single level -- that is fine for
 539                         * a match pattern.
 540                         */
 541                case CHECK_REF_FORMAT_WILDCARD:
 542                        /* ok but ends with a pattern-match character */
 543                        continue;
 544                }
 545                die("remote part of refspec is not a valid name in %s",
 546                    heads[i]);
 547        }
 548}
 549
 550int cmd_send_pack(int argc, const char **argv, const char *prefix)
 551{
 552        int i, nr_heads = 0;
 553        const char **heads = NULL;
 554        const char *remote_name = NULL;
 555        struct remote *remote = NULL;
 556        const char *dest = NULL;
 557
 558        argv++;
 559        for (i = 1; i < argc; i++, argv++) {
 560                const char *arg = *argv;
 561
 562                if (*arg == '-') {
 563                        if (!prefixcmp(arg, "--receive-pack=")) {
 564                                args.receivepack = arg + 15;
 565                                continue;
 566                        }
 567                        if (!prefixcmp(arg, "--exec=")) {
 568                                args.receivepack = arg + 7;
 569                                continue;
 570                        }
 571                        if (!prefixcmp(arg, "--remote=")) {
 572                                remote_name = arg + 9;
 573                                continue;
 574                        }
 575                        if (!strcmp(arg, "--all")) {
 576                                args.send_all = 1;
 577                                continue;
 578                        }
 579                        if (!strcmp(arg, "--dry-run")) {
 580                                args.dry_run = 1;
 581                                continue;
 582                        }
 583                        if (!strcmp(arg, "--mirror")) {
 584                                args.send_mirror = 1;
 585                                continue;
 586                        }
 587                        if (!strcmp(arg, "--force")) {
 588                                args.force_update = 1;
 589                                continue;
 590                        }
 591                        if (!strcmp(arg, "--verbose")) {
 592                                args.verbose = 1;
 593                                continue;
 594                        }
 595                        if (!strcmp(arg, "--thin")) {
 596                                args.use_thin_pack = 1;
 597                                continue;
 598                        }
 599                        usage(send_pack_usage);
 600                }
 601                if (!dest) {
 602                        dest = arg;
 603                        continue;
 604                }
 605                heads = (const char **) argv;
 606                nr_heads = argc - i;
 607                break;
 608        }
 609        if (!dest)
 610                usage(send_pack_usage);
 611        /*
 612         * --all and --mirror are incompatible; neither makes sense
 613         * with any refspecs.
 614         */
 615        if ((heads && (args.send_all || args.send_mirror)) ||
 616                                        (args.send_all && args.send_mirror))
 617                usage(send_pack_usage);
 618
 619        if (remote_name) {
 620                remote = remote_get(remote_name);
 621                if (!remote_has_url(remote, dest)) {
 622                        die("Destination %s is not a uri for %s",
 623                            dest, remote_name);
 624                }
 625        }
 626
 627        return send_pack(&args, dest, remote, nr_heads, heads);
 628}
 629
 630int send_pack(struct send_pack_args *my_args,
 631              const char *dest, struct remote *remote,
 632              int nr_heads, const char **heads)
 633{
 634        int fd[2], ret;
 635        struct child_process *conn;
 636
 637        memcpy(&args, my_args, sizeof(args));
 638
 639        verify_remote_names(nr_heads, heads);
 640
 641        conn = git_connect(fd, dest, args.receivepack, args.verbose ? CONNECT_VERBOSE : 0);
 642        ret = do_send_pack(fd[0], fd[1], remote, dest, nr_heads, heads);
 643        close(fd[0]);
 644        /* do_send_pack always closes fd[1] */
 645        ret |= finish_connect(conn);
 646        return !!ret;
 647}