transport.con commit cat-file: use oidset check-and-insert (ced9fff)
   1#include "cache.h"
   2#include "config.h"
   3#include "transport.h"
   4#include "run-command.h"
   5#include "pkt-line.h"
   6#include "fetch-pack.h"
   7#include "remote.h"
   8#include "connect.h"
   9#include "send-pack.h"
  10#include "walker.h"
  11#include "bundle.h"
  12#include "dir.h"
  13#include "refs.h"
  14#include "refspec.h"
  15#include "branch.h"
  16#include "url.h"
  17#include "submodule.h"
  18#include "string-list.h"
  19#include "sha1-array.h"
  20#include "sigchain.h"
  21#include "transport-internal.h"
  22#include "protocol.h"
  23#include "object-store.h"
  24#include "color.h"
  25
  26static int transport_use_color = -1;
  27static char transport_colors[][COLOR_MAXLEN] = {
  28        GIT_COLOR_RESET,
  29        GIT_COLOR_RED           /* REJECTED */
  30};
  31
  32enum color_transport {
  33        TRANSPORT_COLOR_RESET = 0,
  34        TRANSPORT_COLOR_REJECTED = 1
  35};
  36
  37static int transport_color_config(void)
  38{
  39        const char *keys[] = {
  40                "color.transport.reset",
  41                "color.transport.rejected"
  42        }, *key = "color.transport";
  43        char *value;
  44        int i;
  45        static int initialized;
  46
  47        if (initialized)
  48                return 0;
  49        initialized = 1;
  50
  51        if (!git_config_get_string(key, &value))
  52                transport_use_color = git_config_colorbool(key, value);
  53
  54        if (!want_color_stderr(transport_use_color))
  55                return 0;
  56
  57        for (i = 0; i < ARRAY_SIZE(keys); i++)
  58                if (!git_config_get_string(keys[i], &value)) {
  59                        if (!value)
  60                                return config_error_nonbool(keys[i]);
  61                        if (color_parse(value, transport_colors[i]) < 0)
  62                                return -1;
  63                }
  64
  65        return 0;
  66}
  67
  68static const char *transport_get_color(enum color_transport ix)
  69{
  70        if (want_color_stderr(transport_use_color))
  71                return transport_colors[ix];
  72        return "";
  73}
  74
  75static void set_upstreams(struct transport *transport, struct ref *refs,
  76        int pretend)
  77{
  78        struct ref *ref;
  79        for (ref = refs; ref; ref = ref->next) {
  80                const char *localname;
  81                const char *tmp;
  82                const char *remotename;
  83                int flag = 0;
  84                /*
  85                 * Check suitability for tracking. Must be successful /
  86                 * already up-to-date ref create/modify (not delete).
  87                 */
  88                if (ref->status != REF_STATUS_OK &&
  89                        ref->status != REF_STATUS_UPTODATE)
  90                        continue;
  91                if (!ref->peer_ref)
  92                        continue;
  93                if (is_null_oid(&ref->new_oid))
  94                        continue;
  95
  96                /* Follow symbolic refs (mainly for HEAD). */
  97                localname = ref->peer_ref->name;
  98                remotename = ref->name;
  99                tmp = resolve_ref_unsafe(localname, RESOLVE_REF_READING,
 100                                         NULL, &flag);
 101                if (tmp && flag & REF_ISSYMREF &&
 102                        starts_with(tmp, "refs/heads/"))
 103                        localname = tmp;
 104
 105                /* Both source and destination must be local branches. */
 106                if (!localname || !starts_with(localname, "refs/heads/"))
 107                        continue;
 108                if (!remotename || !starts_with(remotename, "refs/heads/"))
 109                        continue;
 110
 111                if (!pretend)
 112                        install_branch_config(BRANCH_CONFIG_VERBOSE,
 113                                localname + 11, transport->remote->name,
 114                                remotename);
 115                else
 116                        printf(_("Would set upstream of '%s' to '%s' of '%s'\n"),
 117                                localname + 11, remotename + 11,
 118                                transport->remote->name);
 119        }
 120}
 121
 122struct bundle_transport_data {
 123        int fd;
 124        struct bundle_header header;
 125};
 126
 127static struct ref *get_refs_from_bundle(struct transport *transport,
 128                                        int for_push,
 129                                        const struct argv_array *ref_prefixes)
 130{
 131        struct bundle_transport_data *data = transport->data;
 132        struct ref *result = NULL;
 133        int i;
 134
 135        if (for_push)
 136                return NULL;
 137
 138        if (data->fd > 0)
 139                close(data->fd);
 140        data->fd = read_bundle_header(transport->url, &data->header);
 141        if (data->fd < 0)
 142                die ("Could not read bundle '%s'.", transport->url);
 143        for (i = 0; i < data->header.references.nr; i++) {
 144                struct ref_list_entry *e = data->header.references.list + i;
 145                struct ref *ref = alloc_ref(e->name);
 146                oidcpy(&ref->old_oid, &e->oid);
 147                ref->next = result;
 148                result = ref;
 149        }
 150        return result;
 151}
 152
 153static int fetch_refs_from_bundle(struct transport *transport,
 154                               int nr_heads, struct ref **to_fetch,
 155                               struct ref **fetched_refs)
 156{
 157        struct bundle_transport_data *data = transport->data;
 158        return unbundle(&data->header, data->fd,
 159                        transport->progress ? BUNDLE_VERBOSE : 0);
 160}
 161
 162static int close_bundle(struct transport *transport)
 163{
 164        struct bundle_transport_data *data = transport->data;
 165        if (data->fd > 0)
 166                close(data->fd);
 167        free(data);
 168        return 0;
 169}
 170
 171struct git_transport_data {
 172        struct git_transport_options options;
 173        struct child_process *conn;
 174        int fd[2];
 175        unsigned got_remote_heads : 1;
 176        enum protocol_version version;
 177        struct oid_array extra_have;
 178        struct oid_array shallow;
 179};
 180
 181static int set_git_option(struct git_transport_options *opts,
 182                          const char *name, const char *value)
 183{
 184        if (!strcmp(name, TRANS_OPT_UPLOADPACK)) {
 185                opts->uploadpack = value;
 186                return 0;
 187        } else if (!strcmp(name, TRANS_OPT_RECEIVEPACK)) {
 188                opts->receivepack = value;
 189                return 0;
 190        } else if (!strcmp(name, TRANS_OPT_THIN)) {
 191                opts->thin = !!value;
 192                return 0;
 193        } else if (!strcmp(name, TRANS_OPT_FOLLOWTAGS)) {
 194                opts->followtags = !!value;
 195                return 0;
 196        } else if (!strcmp(name, TRANS_OPT_KEEP)) {
 197                opts->keep = !!value;
 198                return 0;
 199        } else if (!strcmp(name, TRANS_OPT_UPDATE_SHALLOW)) {
 200                opts->update_shallow = !!value;
 201                return 0;
 202        } else if (!strcmp(name, TRANS_OPT_DEPTH)) {
 203                if (!value)
 204                        opts->depth = 0;
 205                else {
 206                        char *end;
 207                        opts->depth = strtol(value, &end, 0);
 208                        if (*end)
 209                                die(_("transport: invalid depth option '%s'"), value);
 210                }
 211                return 0;
 212        } else if (!strcmp(name, TRANS_OPT_DEEPEN_SINCE)) {
 213                opts->deepen_since = value;
 214                return 0;
 215        } else if (!strcmp(name, TRANS_OPT_DEEPEN_NOT)) {
 216                opts->deepen_not = (const struct string_list *)value;
 217                return 0;
 218        } else if (!strcmp(name, TRANS_OPT_DEEPEN_RELATIVE)) {
 219                opts->deepen_relative = !!value;
 220                return 0;
 221        } else if (!strcmp(name, TRANS_OPT_FROM_PROMISOR)) {
 222                opts->from_promisor = !!value;
 223                return 0;
 224        } else if (!strcmp(name, TRANS_OPT_NO_DEPENDENTS)) {
 225                opts->no_dependents = !!value;
 226                return 0;
 227        } else if (!strcmp(name, TRANS_OPT_LIST_OBJECTS_FILTER)) {
 228                parse_list_objects_filter(&opts->filter_options, value);
 229                return 0;
 230        }
 231        return 1;
 232}
 233
 234static int connect_setup(struct transport *transport, int for_push)
 235{
 236        struct git_transport_data *data = transport->data;
 237        int flags = transport->verbose > 0 ? CONNECT_VERBOSE : 0;
 238
 239        if (data->conn)
 240                return 0;
 241
 242        switch (transport->family) {
 243        case TRANSPORT_FAMILY_ALL: break;
 244        case TRANSPORT_FAMILY_IPV4: flags |= CONNECT_IPV4; break;
 245        case TRANSPORT_FAMILY_IPV6: flags |= CONNECT_IPV6; break;
 246        }
 247
 248        data->conn = git_connect(data->fd, transport->url,
 249                                 for_push ? data->options.receivepack :
 250                                 data->options.uploadpack,
 251                                 flags);
 252
 253        return 0;
 254}
 255
 256static struct ref *get_refs_via_connect(struct transport *transport, int for_push,
 257                                        const struct argv_array *ref_prefixes)
 258{
 259        struct git_transport_data *data = transport->data;
 260        struct ref *refs = NULL;
 261        struct packet_reader reader;
 262
 263        connect_setup(transport, for_push);
 264
 265        packet_reader_init(&reader, data->fd[0], NULL, 0,
 266                           PACKET_READ_CHOMP_NEWLINE |
 267                           PACKET_READ_GENTLE_ON_EOF);
 268
 269        data->version = discover_version(&reader);
 270        switch (data->version) {
 271        case protocol_v2:
 272                get_remote_refs(data->fd[1], &reader, &refs, for_push,
 273                                ref_prefixes, transport->server_options);
 274                break;
 275        case protocol_v1:
 276        case protocol_v0:
 277                get_remote_heads(&reader, &refs,
 278                                 for_push ? REF_NORMAL : 0,
 279                                 &data->extra_have,
 280                                 &data->shallow);
 281                break;
 282        case protocol_unknown_version:
 283                BUG("unknown protocol version");
 284        }
 285        data->got_remote_heads = 1;
 286
 287        return refs;
 288}
 289
 290static int fetch_refs_via_pack(struct transport *transport,
 291                               int nr_heads, struct ref **to_fetch,
 292                               struct ref **fetched_refs)
 293{
 294        int ret = 0;
 295        struct git_transport_data *data = transport->data;
 296        struct ref *refs = NULL;
 297        char *dest = xstrdup(transport->url);
 298        struct fetch_pack_args args;
 299        struct ref *refs_tmp = NULL;
 300
 301        memset(&args, 0, sizeof(args));
 302        args.uploadpack = data->options.uploadpack;
 303        args.keep_pack = data->options.keep;
 304        args.lock_pack = 1;
 305        args.use_thin_pack = data->options.thin;
 306        args.include_tag = data->options.followtags;
 307        args.verbose = (transport->verbose > 1);
 308        args.quiet = (transport->verbose < 0);
 309        args.no_progress = !transport->progress;
 310        args.depth = data->options.depth;
 311        args.deepen_since = data->options.deepen_since;
 312        args.deepen_not = data->options.deepen_not;
 313        args.deepen_relative = data->options.deepen_relative;
 314        args.check_self_contained_and_connected =
 315                data->options.check_self_contained_and_connected;
 316        args.cloning = transport->cloning;
 317        args.update_shallow = data->options.update_shallow;
 318        args.from_promisor = data->options.from_promisor;
 319        args.no_dependents = data->options.no_dependents;
 320        args.filter_options = data->options.filter_options;
 321        args.stateless_rpc = transport->stateless_rpc;
 322        args.server_options = transport->server_options;
 323        args.negotiation_tips = data->options.negotiation_tips;
 324
 325        if (!data->got_remote_heads)
 326                refs_tmp = get_refs_via_connect(transport, 0, NULL);
 327
 328        switch (data->version) {
 329        case protocol_v2:
 330                refs = fetch_pack(&args, data->fd, data->conn,
 331                                  refs_tmp ? refs_tmp : transport->remote_refs,
 332                                  dest, to_fetch, nr_heads, &data->shallow,
 333                                  &transport->pack_lockfile, data->version);
 334                break;
 335        case protocol_v1:
 336        case protocol_v0:
 337                refs = fetch_pack(&args, data->fd, data->conn,
 338                                  refs_tmp ? refs_tmp : transport->remote_refs,
 339                                  dest, to_fetch, nr_heads, &data->shallow,
 340                                  &transport->pack_lockfile, data->version);
 341                break;
 342        case protocol_unknown_version:
 343                BUG("unknown protocol version");
 344        }
 345
 346        close(data->fd[0]);
 347        close(data->fd[1]);
 348        if (finish_connect(data->conn))
 349                ret = -1;
 350        data->conn = NULL;
 351        data->got_remote_heads = 0;
 352        data->options.self_contained_and_connected =
 353                args.self_contained_and_connected;
 354        data->options.connectivity_checked = args.connectivity_checked;
 355
 356        if (refs == NULL)
 357                ret = -1;
 358        if (report_unmatched_refs(to_fetch, nr_heads))
 359                ret = -1;
 360
 361        if (fetched_refs)
 362                *fetched_refs = refs;
 363        else
 364                free_refs(refs);
 365
 366        free_refs(refs_tmp);
 367        free(dest);
 368        return ret;
 369}
 370
 371static int push_had_errors(struct ref *ref)
 372{
 373        for (; ref; ref = ref->next) {
 374                switch (ref->status) {
 375                case REF_STATUS_NONE:
 376                case REF_STATUS_UPTODATE:
 377                case REF_STATUS_OK:
 378                        break;
 379                default:
 380                        return 1;
 381                }
 382        }
 383        return 0;
 384}
 385
 386int transport_refs_pushed(struct ref *ref)
 387{
 388        for (; ref; ref = ref->next) {
 389                switch(ref->status) {
 390                case REF_STATUS_NONE:
 391                case REF_STATUS_UPTODATE:
 392                        break;
 393                default:
 394                        return 1;
 395                }
 396        }
 397        return 0;
 398}
 399
 400void transport_update_tracking_ref(struct remote *remote, struct ref *ref, int verbose)
 401{
 402        struct refspec_item rs;
 403
 404        if (ref->status != REF_STATUS_OK && ref->status != REF_STATUS_UPTODATE)
 405                return;
 406
 407        rs.src = ref->name;
 408        rs.dst = NULL;
 409
 410        if (!remote_find_tracking(remote, &rs)) {
 411                if (verbose)
 412                        fprintf(stderr, "updating local tracking ref '%s'\n", rs.dst);
 413                if (ref->deletion) {
 414                        delete_ref(NULL, rs.dst, NULL, 0);
 415                } else
 416                        update_ref("update by push", rs.dst, &ref->new_oid,
 417                                   NULL, 0, 0);
 418                free(rs.dst);
 419        }
 420}
 421
 422static void print_ref_status(char flag, const char *summary,
 423                             struct ref *to, struct ref *from, const char *msg,
 424                             int porcelain, int summary_width)
 425{
 426        if (porcelain) {
 427                if (from)
 428                        fprintf(stdout, "%c\t%s:%s\t", flag, from->name, to->name);
 429                else
 430                        fprintf(stdout, "%c\t:%s\t", flag, to->name);
 431                if (msg)
 432                        fprintf(stdout, "%s (%s)\n", summary, msg);
 433                else
 434                        fprintf(stdout, "%s\n", summary);
 435        } else {
 436                const char *red = "", *reset = "";
 437                if (push_had_errors(to)) {
 438                        red = transport_get_color(TRANSPORT_COLOR_REJECTED);
 439                        reset = transport_get_color(TRANSPORT_COLOR_RESET);
 440                }
 441                fprintf(stderr, " %s%c %-*s%s ", red, flag, summary_width,
 442                        summary, reset);
 443                if (from)
 444                        fprintf(stderr, "%s -> %s", prettify_refname(from->name), prettify_refname(to->name));
 445                else
 446                        fputs(prettify_refname(to->name), stderr);
 447                if (msg) {
 448                        fputs(" (", stderr);
 449                        fputs(msg, stderr);
 450                        fputc(')', stderr);
 451                }
 452                fputc('\n', stderr);
 453        }
 454}
 455
 456static void print_ok_ref_status(struct ref *ref, int porcelain, int summary_width)
 457{
 458        if (ref->deletion)
 459                print_ref_status('-', "[deleted]", ref, NULL, NULL,
 460                                 porcelain, summary_width);
 461        else if (is_null_oid(&ref->old_oid))
 462                print_ref_status('*',
 463                        (starts_with(ref->name, "refs/tags/") ? "[new tag]" :
 464                        "[new branch]"),
 465                        ref, ref->peer_ref, NULL, porcelain, summary_width);
 466        else {
 467                struct strbuf quickref = STRBUF_INIT;
 468                char type;
 469                const char *msg;
 470
 471                strbuf_add_unique_abbrev(&quickref, &ref->old_oid,
 472                                         DEFAULT_ABBREV);
 473                if (ref->forced_update) {
 474                        strbuf_addstr(&quickref, "...");
 475                        type = '+';
 476                        msg = "forced update";
 477                } else {
 478                        strbuf_addstr(&quickref, "..");
 479                        type = ' ';
 480                        msg = NULL;
 481                }
 482                strbuf_add_unique_abbrev(&quickref, &ref->new_oid,
 483                                         DEFAULT_ABBREV);
 484
 485                print_ref_status(type, quickref.buf, ref, ref->peer_ref, msg,
 486                                 porcelain, summary_width);
 487                strbuf_release(&quickref);
 488        }
 489}
 490
 491static int print_one_push_status(struct ref *ref, const char *dest, int count,
 492                                 int porcelain, int summary_width)
 493{
 494        if (!count) {
 495                char *url = transport_anonymize_url(dest);
 496                fprintf(porcelain ? stdout : stderr, "To %s\n", url);
 497                free(url);
 498        }
 499
 500        switch(ref->status) {
 501        case REF_STATUS_NONE:
 502                print_ref_status('X', "[no match]", ref, NULL, NULL,
 503                                 porcelain, summary_width);
 504                break;
 505        case REF_STATUS_REJECT_NODELETE:
 506                print_ref_status('!', "[rejected]", ref, NULL,
 507                                 "remote does not support deleting refs",
 508                                 porcelain, summary_width);
 509                break;
 510        case REF_STATUS_UPTODATE:
 511                print_ref_status('=', "[up to date]", ref,
 512                                 ref->peer_ref, NULL, porcelain, summary_width);
 513                break;
 514        case REF_STATUS_REJECT_NONFASTFORWARD:
 515                print_ref_status('!', "[rejected]", ref, ref->peer_ref,
 516                                 "non-fast-forward", porcelain, summary_width);
 517                break;
 518        case REF_STATUS_REJECT_ALREADY_EXISTS:
 519                print_ref_status('!', "[rejected]", ref, ref->peer_ref,
 520                                 "already exists", porcelain, summary_width);
 521                break;
 522        case REF_STATUS_REJECT_FETCH_FIRST:
 523                print_ref_status('!', "[rejected]", ref, ref->peer_ref,
 524                                 "fetch first", porcelain, summary_width);
 525                break;
 526        case REF_STATUS_REJECT_NEEDS_FORCE:
 527                print_ref_status('!', "[rejected]", ref, ref->peer_ref,
 528                                 "needs force", porcelain, summary_width);
 529                break;
 530        case REF_STATUS_REJECT_STALE:
 531                print_ref_status('!', "[rejected]", ref, ref->peer_ref,
 532                                 "stale info", porcelain, summary_width);
 533                break;
 534        case REF_STATUS_REJECT_SHALLOW:
 535                print_ref_status('!', "[rejected]", ref, ref->peer_ref,
 536                                 "new shallow roots not allowed",
 537                                 porcelain, summary_width);
 538                break;
 539        case REF_STATUS_REMOTE_REJECT:
 540                print_ref_status('!', "[remote rejected]", ref,
 541                                 ref->deletion ? NULL : ref->peer_ref,
 542                                 ref->remote_status, porcelain, summary_width);
 543                break;
 544        case REF_STATUS_EXPECTING_REPORT:
 545                print_ref_status('!', "[remote failure]", ref,
 546                                 ref->deletion ? NULL : ref->peer_ref,
 547                                 "remote failed to report status",
 548                                 porcelain, summary_width);
 549                break;
 550        case REF_STATUS_ATOMIC_PUSH_FAILED:
 551                print_ref_status('!', "[rejected]", ref, ref->peer_ref,
 552                                 "atomic push failed", porcelain, summary_width);
 553                break;
 554        case REF_STATUS_OK:
 555                print_ok_ref_status(ref, porcelain, summary_width);
 556                break;
 557        }
 558
 559        return 1;
 560}
 561
 562static int measure_abbrev(const struct object_id *oid, int sofar)
 563{
 564        char hex[GIT_MAX_HEXSZ + 1];
 565        int w = find_unique_abbrev_r(hex, oid, DEFAULT_ABBREV);
 566
 567        return (w < sofar) ? sofar : w;
 568}
 569
 570int transport_summary_width(const struct ref *refs)
 571{
 572        int maxw = -1;
 573
 574        for (; refs; refs = refs->next) {
 575                maxw = measure_abbrev(&refs->old_oid, maxw);
 576                maxw = measure_abbrev(&refs->new_oid, maxw);
 577        }
 578        if (maxw < 0)
 579                maxw = FALLBACK_DEFAULT_ABBREV;
 580        return (2 * maxw + 3);
 581}
 582
 583void transport_print_push_status(const char *dest, struct ref *refs,
 584                                  int verbose, int porcelain, unsigned int *reject_reasons)
 585{
 586        struct ref *ref;
 587        int n = 0;
 588        char *head;
 589        int summary_width = transport_summary_width(refs);
 590
 591        if (transport_color_config() < 0)
 592                warning(_("could not parse transport.color.* config"));
 593
 594        head = resolve_refdup("HEAD", RESOLVE_REF_READING, NULL, NULL);
 595
 596        if (verbose) {
 597                for (ref = refs; ref; ref = ref->next)
 598                        if (ref->status == REF_STATUS_UPTODATE)
 599                                n += print_one_push_status(ref, dest, n,
 600                                                           porcelain, summary_width);
 601        }
 602
 603        for (ref = refs; ref; ref = ref->next)
 604                if (ref->status == REF_STATUS_OK)
 605                        n += print_one_push_status(ref, dest, n,
 606                                                   porcelain, summary_width);
 607
 608        *reject_reasons = 0;
 609        for (ref = refs; ref; ref = ref->next) {
 610                if (ref->status != REF_STATUS_NONE &&
 611                    ref->status != REF_STATUS_UPTODATE &&
 612                    ref->status != REF_STATUS_OK)
 613                        n += print_one_push_status(ref, dest, n,
 614                                                   porcelain, summary_width);
 615                if (ref->status == REF_STATUS_REJECT_NONFASTFORWARD) {
 616                        if (head != NULL && !strcmp(head, ref->name))
 617                                *reject_reasons |= REJECT_NON_FF_HEAD;
 618                        else
 619                                *reject_reasons |= REJECT_NON_FF_OTHER;
 620                } else if (ref->status == REF_STATUS_REJECT_ALREADY_EXISTS) {
 621                        *reject_reasons |= REJECT_ALREADY_EXISTS;
 622                } else if (ref->status == REF_STATUS_REJECT_FETCH_FIRST) {
 623                        *reject_reasons |= REJECT_FETCH_FIRST;
 624                } else if (ref->status == REF_STATUS_REJECT_NEEDS_FORCE) {
 625                        *reject_reasons |= REJECT_NEEDS_FORCE;
 626                }
 627        }
 628        free(head);
 629}
 630
 631static int git_transport_push(struct transport *transport, struct ref *remote_refs, int flags)
 632{
 633        struct git_transport_data *data = transport->data;
 634        struct send_pack_args args;
 635        int ret = 0;
 636
 637        if (transport_color_config() < 0)
 638                return -1;
 639
 640        if (!data->got_remote_heads)
 641                get_refs_via_connect(transport, 1, NULL);
 642
 643        memset(&args, 0, sizeof(args));
 644        args.send_mirror = !!(flags & TRANSPORT_PUSH_MIRROR);
 645        args.force_update = !!(flags & TRANSPORT_PUSH_FORCE);
 646        args.use_thin_pack = data->options.thin;
 647        args.verbose = (transport->verbose > 0);
 648        args.quiet = (transport->verbose < 0);
 649        args.progress = transport->progress;
 650        args.dry_run = !!(flags & TRANSPORT_PUSH_DRY_RUN);
 651        args.porcelain = !!(flags & TRANSPORT_PUSH_PORCELAIN);
 652        args.atomic = !!(flags & TRANSPORT_PUSH_ATOMIC);
 653        args.push_options = transport->push_options;
 654        args.url = transport->url;
 655
 656        if (flags & TRANSPORT_PUSH_CERT_ALWAYS)
 657                args.push_cert = SEND_PACK_PUSH_CERT_ALWAYS;
 658        else if (flags & TRANSPORT_PUSH_CERT_IF_ASKED)
 659                args.push_cert = SEND_PACK_PUSH_CERT_IF_ASKED;
 660        else
 661                args.push_cert = SEND_PACK_PUSH_CERT_NEVER;
 662
 663        switch (data->version) {
 664        case protocol_v2:
 665                die("support for protocol v2 not implemented yet");
 666                break;
 667        case protocol_v1:
 668        case protocol_v0:
 669                ret = send_pack(&args, data->fd, data->conn, remote_refs,
 670                                &data->extra_have);
 671                break;
 672        case protocol_unknown_version:
 673                BUG("unknown protocol version");
 674        }
 675
 676        close(data->fd[1]);
 677        close(data->fd[0]);
 678        ret |= finish_connect(data->conn);
 679        data->conn = NULL;
 680        data->got_remote_heads = 0;
 681
 682        return ret;
 683}
 684
 685static int connect_git(struct transport *transport, const char *name,
 686                       const char *executable, int fd[2])
 687{
 688        struct git_transport_data *data = transport->data;
 689        data->conn = git_connect(data->fd, transport->url,
 690                                 executable, 0);
 691        fd[0] = data->fd[0];
 692        fd[1] = data->fd[1];
 693        return 0;
 694}
 695
 696static int disconnect_git(struct transport *transport)
 697{
 698        struct git_transport_data *data = transport->data;
 699        if (data->conn) {
 700                if (data->got_remote_heads)
 701                        packet_flush(data->fd[1]);
 702                close(data->fd[0]);
 703                close(data->fd[1]);
 704                finish_connect(data->conn);
 705        }
 706
 707        free(data);
 708        return 0;
 709}
 710
 711static struct transport_vtable taken_over_vtable = {
 712        NULL,
 713        get_refs_via_connect,
 714        fetch_refs_via_pack,
 715        git_transport_push,
 716        NULL,
 717        disconnect_git
 718};
 719
 720void transport_take_over(struct transport *transport,
 721                         struct child_process *child)
 722{
 723        struct git_transport_data *data;
 724
 725        if (!transport->smart_options)
 726                BUG("taking over transport requires non-NULL "
 727                    "smart_options field.");
 728
 729        data = xcalloc(1, sizeof(*data));
 730        data->options = *transport->smart_options;
 731        data->conn = child;
 732        data->fd[0] = data->conn->out;
 733        data->fd[1] = data->conn->in;
 734        data->got_remote_heads = 0;
 735        transport->data = data;
 736
 737        transport->vtable = &taken_over_vtable;
 738        transport->smart_options = &(data->options);
 739
 740        transport->cannot_reuse = 1;
 741}
 742
 743static int is_file(const char *url)
 744{
 745        struct stat buf;
 746        if (stat(url, &buf))
 747                return 0;
 748        return S_ISREG(buf.st_mode);
 749}
 750
 751static int external_specification_len(const char *url)
 752{
 753        return strchr(url, ':') - url;
 754}
 755
 756static const struct string_list *protocol_whitelist(void)
 757{
 758        static int enabled = -1;
 759        static struct string_list allowed = STRING_LIST_INIT_DUP;
 760
 761        if (enabled < 0) {
 762                const char *v = getenv("GIT_ALLOW_PROTOCOL");
 763                if (v) {
 764                        string_list_split(&allowed, v, ':', -1);
 765                        string_list_sort(&allowed);
 766                        enabled = 1;
 767                } else {
 768                        enabled = 0;
 769                }
 770        }
 771
 772        return enabled ? &allowed : NULL;
 773}
 774
 775enum protocol_allow_config {
 776        PROTOCOL_ALLOW_NEVER = 0,
 777        PROTOCOL_ALLOW_USER_ONLY,
 778        PROTOCOL_ALLOW_ALWAYS
 779};
 780
 781static enum protocol_allow_config parse_protocol_config(const char *key,
 782                                                        const char *value)
 783{
 784        if (!strcasecmp(value, "always"))
 785                return PROTOCOL_ALLOW_ALWAYS;
 786        else if (!strcasecmp(value, "never"))
 787                return PROTOCOL_ALLOW_NEVER;
 788        else if (!strcasecmp(value, "user"))
 789                return PROTOCOL_ALLOW_USER_ONLY;
 790
 791        die("unknown value for config '%s': %s", key, value);
 792}
 793
 794static enum protocol_allow_config get_protocol_config(const char *type)
 795{
 796        char *key = xstrfmt("protocol.%s.allow", type);
 797        char *value;
 798
 799        /* first check the per-protocol config */
 800        if (!git_config_get_string(key, &value)) {
 801                enum protocol_allow_config ret =
 802                        parse_protocol_config(key, value);
 803                free(key);
 804                free(value);
 805                return ret;
 806        }
 807        free(key);
 808
 809        /* if defined, fallback to user-defined default for unknown protocols */
 810        if (!git_config_get_string("protocol.allow", &value)) {
 811                enum protocol_allow_config ret =
 812                        parse_protocol_config("protocol.allow", value);
 813                free(value);
 814                return ret;
 815        }
 816
 817        /* fallback to built-in defaults */
 818        /* known safe */
 819        if (!strcmp(type, "http") ||
 820            !strcmp(type, "https") ||
 821            !strcmp(type, "git") ||
 822            !strcmp(type, "ssh") ||
 823            !strcmp(type, "file"))
 824                return PROTOCOL_ALLOW_ALWAYS;
 825
 826        /* known scary; err on the side of caution */
 827        if (!strcmp(type, "ext"))
 828                return PROTOCOL_ALLOW_NEVER;
 829
 830        /* unknown; by default let them be used only directly by the user */
 831        return PROTOCOL_ALLOW_USER_ONLY;
 832}
 833
 834int is_transport_allowed(const char *type, int from_user)
 835{
 836        const struct string_list *whitelist = protocol_whitelist();
 837        if (whitelist)
 838                return string_list_has_string(whitelist, type);
 839
 840        switch (get_protocol_config(type)) {
 841        case PROTOCOL_ALLOW_ALWAYS:
 842                return 1;
 843        case PROTOCOL_ALLOW_NEVER:
 844                return 0;
 845        case PROTOCOL_ALLOW_USER_ONLY:
 846                if (from_user < 0)
 847                        from_user = git_env_bool("GIT_PROTOCOL_FROM_USER", 1);
 848                return from_user;
 849        }
 850
 851        BUG("invalid protocol_allow_config type");
 852}
 853
 854void transport_check_allowed(const char *type)
 855{
 856        if (!is_transport_allowed(type, -1))
 857                die("transport '%s' not allowed", type);
 858}
 859
 860static struct transport_vtable bundle_vtable = {
 861        NULL,
 862        get_refs_from_bundle,
 863        fetch_refs_from_bundle,
 864        NULL,
 865        NULL,
 866        close_bundle
 867};
 868
 869static struct transport_vtable builtin_smart_vtable = {
 870        NULL,
 871        get_refs_via_connect,
 872        fetch_refs_via_pack,
 873        git_transport_push,
 874        connect_git,
 875        disconnect_git
 876};
 877
 878struct transport *transport_get(struct remote *remote, const char *url)
 879{
 880        const char *helper;
 881        struct transport *ret = xcalloc(1, sizeof(*ret));
 882
 883        ret->progress = isatty(2);
 884
 885        if (!remote)
 886                die("No remote provided to transport_get()");
 887
 888        ret->got_remote_refs = 0;
 889        ret->remote = remote;
 890        helper = remote->foreign_vcs;
 891
 892        if (!url && remote->url)
 893                url = remote->url[0];
 894        ret->url = url;
 895
 896        /* maybe it is a foreign URL? */
 897        if (url) {
 898                const char *p = url;
 899
 900                while (is_urlschemechar(p == url, *p))
 901                        p++;
 902                if (starts_with(p, "::"))
 903                        helper = xstrndup(url, p - url);
 904        }
 905
 906        if (helper) {
 907                transport_helper_init(ret, helper);
 908        } else if (starts_with(url, "rsync:")) {
 909                die("git-over-rsync is no longer supported");
 910        } else if (url_is_local_not_ssh(url) && is_file(url) && is_bundle(url, 1)) {
 911                struct bundle_transport_data *data = xcalloc(1, sizeof(*data));
 912                transport_check_allowed("file");
 913                ret->data = data;
 914                ret->vtable = &bundle_vtable;
 915                ret->smart_options = NULL;
 916        } else if (!is_url(url)
 917                || starts_with(url, "file://")
 918                || starts_with(url, "git://")
 919                || starts_with(url, "ssh://")
 920                || starts_with(url, "git+ssh://") /* deprecated - do not use */
 921                || starts_with(url, "ssh+git://") /* deprecated - do not use */
 922                ) {
 923                /*
 924                 * These are builtin smart transports; "allowed" transports
 925                 * will be checked individually in git_connect.
 926                 */
 927                struct git_transport_data *data = xcalloc(1, sizeof(*data));
 928                ret->data = data;
 929                ret->vtable = &builtin_smart_vtable;
 930                ret->smart_options = &(data->options);
 931
 932                data->conn = NULL;
 933                data->got_remote_heads = 0;
 934        } else {
 935                /* Unknown protocol in URL. Pass to external handler. */
 936                int len = external_specification_len(url);
 937                char *handler = xmemdupz(url, len);
 938                transport_helper_init(ret, handler);
 939        }
 940
 941        if (ret->smart_options) {
 942                ret->smart_options->thin = 1;
 943                ret->smart_options->uploadpack = "git-upload-pack";
 944                if (remote->uploadpack)
 945                        ret->smart_options->uploadpack = remote->uploadpack;
 946                ret->smart_options->receivepack = "git-receive-pack";
 947                if (remote->receivepack)
 948                        ret->smart_options->receivepack = remote->receivepack;
 949        }
 950
 951        return ret;
 952}
 953
 954int transport_set_option(struct transport *transport,
 955                         const char *name, const char *value)
 956{
 957        int git_reports = 1, protocol_reports = 1;
 958
 959        if (transport->smart_options)
 960                git_reports = set_git_option(transport->smart_options,
 961                                             name, value);
 962
 963        if (transport->vtable->set_option)
 964                protocol_reports = transport->vtable->set_option(transport,
 965                                                                 name, value);
 966
 967        /* If either report is 0, report 0 (success). */
 968        if (!git_reports || !protocol_reports)
 969                return 0;
 970        /* If either reports -1 (invalid value), report -1. */
 971        if ((git_reports == -1) || (protocol_reports == -1))
 972                return -1;
 973        /* Otherwise if both report unknown, report unknown. */
 974        return 1;
 975}
 976
 977void transport_set_verbosity(struct transport *transport, int verbosity,
 978        int force_progress)
 979{
 980        if (verbosity >= 1)
 981                transport->verbose = verbosity <= 3 ? verbosity : 3;
 982        if (verbosity < 0)
 983                transport->verbose = -1;
 984
 985        /**
 986         * Rules used to determine whether to report progress (processing aborts
 987         * when a rule is satisfied):
 988         *
 989         *   . Report progress, if force_progress is 1 (ie. --progress).
 990         *   . Don't report progress, if force_progress is 0 (ie. --no-progress).
 991         *   . Don't report progress, if verbosity < 0 (ie. -q/--quiet ).
 992         *   . Report progress if isatty(2) is 1.
 993         **/
 994        if (force_progress >= 0)
 995                transport->progress = !!force_progress;
 996        else
 997                transport->progress = verbosity >= 0 && isatty(2);
 998}
 999
1000static void die_with_unpushed_submodules(struct string_list *needs_pushing)
1001{
1002        int i;
1003
1004        fprintf(stderr, _("The following submodule paths contain changes that can\n"
1005                        "not be found on any remote:\n"));
1006        for (i = 0; i < needs_pushing->nr; i++)
1007                fprintf(stderr, "  %s\n", needs_pushing->items[i].string);
1008        fprintf(stderr, _("\nPlease try\n\n"
1009                          "     git push --recurse-submodules=on-demand\n\n"
1010                          "or cd to the path and use\n\n"
1011                          "     git push\n\n"
1012                          "to push them to a remote.\n\n"));
1013
1014        string_list_clear(needs_pushing, 0);
1015
1016        die(_("Aborting."));
1017}
1018
1019static int run_pre_push_hook(struct transport *transport,
1020                             struct ref *remote_refs)
1021{
1022        int ret = 0, x;
1023        struct ref *r;
1024        struct child_process proc = CHILD_PROCESS_INIT;
1025        struct strbuf buf;
1026        const char *argv[4];
1027
1028        if (!(argv[0] = find_hook("pre-push")))
1029                return 0;
1030
1031        argv[1] = transport->remote->name;
1032        argv[2] = transport->url;
1033        argv[3] = NULL;
1034
1035        proc.argv = argv;
1036        proc.in = -1;
1037
1038        if (start_command(&proc)) {
1039                finish_command(&proc);
1040                return -1;
1041        }
1042
1043        sigchain_push(SIGPIPE, SIG_IGN);
1044
1045        strbuf_init(&buf, 256);
1046
1047        for (r = remote_refs; r; r = r->next) {
1048                if (!r->peer_ref) continue;
1049                if (r->status == REF_STATUS_REJECT_NONFASTFORWARD) continue;
1050                if (r->status == REF_STATUS_REJECT_STALE) continue;
1051                if (r->status == REF_STATUS_UPTODATE) continue;
1052
1053                strbuf_reset(&buf);
1054                strbuf_addf( &buf, "%s %s %s %s\n",
1055                         r->peer_ref->name, oid_to_hex(&r->new_oid),
1056                         r->name, oid_to_hex(&r->old_oid));
1057
1058                if (write_in_full(proc.in, buf.buf, buf.len) < 0) {
1059                        /* We do not mind if a hook does not read all refs. */
1060                        if (errno != EPIPE)
1061                                ret = -1;
1062                        break;
1063                }
1064        }
1065
1066        strbuf_release(&buf);
1067
1068        x = close(proc.in);
1069        if (!ret)
1070                ret = x;
1071
1072        sigchain_pop(SIGPIPE);
1073
1074        x = finish_command(&proc);
1075        if (!ret)
1076                ret = x;
1077
1078        return ret;
1079}
1080
1081int transport_push(struct transport *transport,
1082                   struct refspec *rs, int flags,
1083                   unsigned int *reject_reasons)
1084{
1085        *reject_reasons = 0;
1086
1087        if (transport_color_config() < 0)
1088                return -1;
1089
1090        if (transport->vtable->push_refs) {
1091                struct ref *remote_refs;
1092                struct ref *local_refs = get_local_heads();
1093                int match_flags = MATCH_REFS_NONE;
1094                int verbose = (transport->verbose > 0);
1095                int quiet = (transport->verbose < 0);
1096                int porcelain = flags & TRANSPORT_PUSH_PORCELAIN;
1097                int pretend = flags & TRANSPORT_PUSH_DRY_RUN;
1098                int push_ret, ret, err;
1099                struct argv_array ref_prefixes = ARGV_ARRAY_INIT;
1100
1101                if (check_push_refs(local_refs, rs) < 0)
1102                        return -1;
1103
1104                refspec_ref_prefixes(rs, &ref_prefixes);
1105
1106                remote_refs = transport->vtable->get_refs_list(transport, 1,
1107                                                               &ref_prefixes);
1108
1109                argv_array_clear(&ref_prefixes);
1110
1111                if (flags & TRANSPORT_PUSH_ALL)
1112                        match_flags |= MATCH_REFS_ALL;
1113                if (flags & TRANSPORT_PUSH_MIRROR)
1114                        match_flags |= MATCH_REFS_MIRROR;
1115                if (flags & TRANSPORT_PUSH_PRUNE)
1116                        match_flags |= MATCH_REFS_PRUNE;
1117                if (flags & TRANSPORT_PUSH_FOLLOW_TAGS)
1118                        match_flags |= MATCH_REFS_FOLLOW_TAGS;
1119
1120                if (match_push_refs(local_refs, &remote_refs, rs, match_flags))
1121                        return -1;
1122
1123                if (transport->smart_options &&
1124                    transport->smart_options->cas &&
1125                    !is_empty_cas(transport->smart_options->cas))
1126                        apply_push_cas(transport->smart_options->cas,
1127                                       transport->remote, remote_refs);
1128
1129                set_ref_status_for_push(remote_refs,
1130                        flags & TRANSPORT_PUSH_MIRROR,
1131                        flags & TRANSPORT_PUSH_FORCE);
1132
1133                if (!(flags & TRANSPORT_PUSH_NO_HOOK))
1134                        if (run_pre_push_hook(transport, remote_refs))
1135                                return -1;
1136
1137                if ((flags & (TRANSPORT_RECURSE_SUBMODULES_ON_DEMAND |
1138                              TRANSPORT_RECURSE_SUBMODULES_ONLY)) &&
1139                    !is_bare_repository()) {
1140                        struct ref *ref = remote_refs;
1141                        struct oid_array commits = OID_ARRAY_INIT;
1142
1143                        for (; ref; ref = ref->next)
1144                                if (!is_null_oid(&ref->new_oid))
1145                                        oid_array_append(&commits,
1146                                                          &ref->new_oid);
1147
1148                        if (!push_unpushed_submodules(&commits,
1149                                                      transport->remote,
1150                                                      rs,
1151                                                      transport->push_options,
1152                                                      pretend)) {
1153                                oid_array_clear(&commits);
1154                                die("Failed to push all needed submodules!");
1155                        }
1156                        oid_array_clear(&commits);
1157                }
1158
1159                if (((flags & TRANSPORT_RECURSE_SUBMODULES_CHECK) ||
1160                     ((flags & (TRANSPORT_RECURSE_SUBMODULES_ON_DEMAND |
1161                                TRANSPORT_RECURSE_SUBMODULES_ONLY)) &&
1162                      !pretend)) && !is_bare_repository()) {
1163                        struct ref *ref = remote_refs;
1164                        struct string_list needs_pushing = STRING_LIST_INIT_DUP;
1165                        struct oid_array commits = OID_ARRAY_INIT;
1166
1167                        for (; ref; ref = ref->next)
1168                                if (!is_null_oid(&ref->new_oid))
1169                                        oid_array_append(&commits,
1170                                                          &ref->new_oid);
1171
1172                        if (find_unpushed_submodules(&commits, transport->remote->name,
1173                                                &needs_pushing)) {
1174                                oid_array_clear(&commits);
1175                                die_with_unpushed_submodules(&needs_pushing);
1176                        }
1177                        string_list_clear(&needs_pushing, 0);
1178                        oid_array_clear(&commits);
1179                }
1180
1181                if (!(flags & TRANSPORT_RECURSE_SUBMODULES_ONLY))
1182                        push_ret = transport->vtable->push_refs(transport, remote_refs, flags);
1183                else
1184                        push_ret = 0;
1185                err = push_had_errors(remote_refs);
1186                ret = push_ret | err;
1187
1188                if (!quiet || err)
1189                        transport_print_push_status(transport->url, remote_refs,
1190                                        verbose | porcelain, porcelain,
1191                                        reject_reasons);
1192
1193                if (flags & TRANSPORT_PUSH_SET_UPSTREAM)
1194                        set_upstreams(transport, remote_refs, pretend);
1195
1196                if (!(flags & (TRANSPORT_PUSH_DRY_RUN |
1197                               TRANSPORT_RECURSE_SUBMODULES_ONLY))) {
1198                        struct ref *ref;
1199                        for (ref = remote_refs; ref; ref = ref->next)
1200                                transport_update_tracking_ref(transport->remote, ref, verbose);
1201                }
1202
1203                if (porcelain && !push_ret)
1204                        puts("Done");
1205                else if (!quiet && !ret && !transport_refs_pushed(remote_refs))
1206                        fprintf(stderr, "Everything up-to-date\n");
1207
1208                return ret;
1209        }
1210        return 1;
1211}
1212
1213const struct ref *transport_get_remote_refs(struct transport *transport,
1214                                            const struct argv_array *ref_prefixes)
1215{
1216        if (!transport->got_remote_refs) {
1217                transport->remote_refs =
1218                        transport->vtable->get_refs_list(transport, 0,
1219                                                         ref_prefixes);
1220                transport->got_remote_refs = 1;
1221        }
1222
1223        return transport->remote_refs;
1224}
1225
1226int transport_fetch_refs(struct transport *transport, struct ref *refs,
1227                         struct ref **fetched_refs)
1228{
1229        int rc;
1230        int nr_heads = 0, nr_alloc = 0, nr_refs = 0;
1231        struct ref **heads = NULL;
1232        struct ref *nop_head = NULL, **nop_tail = &nop_head;
1233        struct ref *rm;
1234
1235        for (rm = refs; rm; rm = rm->next) {
1236                nr_refs++;
1237                if (rm->peer_ref &&
1238                    !is_null_oid(&rm->old_oid) &&
1239                    !oidcmp(&rm->peer_ref->old_oid, &rm->old_oid)) {
1240                        /*
1241                         * These need to be reported as fetched, but we don't
1242                         * actually need to fetch them.
1243                         */
1244                        if (fetched_refs) {
1245                                struct ref *nop_ref = copy_ref(rm);
1246                                *nop_tail = nop_ref;
1247                                nop_tail = &nop_ref->next;
1248                        }
1249                        continue;
1250                }
1251                ALLOC_GROW(heads, nr_heads + 1, nr_alloc);
1252                heads[nr_heads++] = rm;
1253        }
1254
1255        if (!nr_heads) {
1256                /*
1257                 * When deepening of a shallow repository is requested,
1258                 * then local and remote refs are likely to still be equal.
1259                 * Just feed them all to the fetch method in that case.
1260                 * This condition shouldn't be met in a non-deepening fetch
1261                 * (see builtin/fetch.c:quickfetch()).
1262                 */
1263                ALLOC_ARRAY(heads, nr_refs);
1264                for (rm = refs; rm; rm = rm->next)
1265                        heads[nr_heads++] = rm;
1266        }
1267
1268        rc = transport->vtable->fetch(transport, nr_heads, heads, fetched_refs);
1269        if (fetched_refs && nop_head) {
1270                *nop_tail = *fetched_refs;
1271                *fetched_refs = nop_head;
1272        }
1273
1274        free(heads);
1275        return rc;
1276}
1277
1278void transport_unlock_pack(struct transport *transport)
1279{
1280        if (transport->pack_lockfile) {
1281                unlink_or_warn(transport->pack_lockfile);
1282                FREE_AND_NULL(transport->pack_lockfile);
1283        }
1284}
1285
1286int transport_connect(struct transport *transport, const char *name,
1287                      const char *exec, int fd[2])
1288{
1289        if (transport->vtable->connect)
1290                return transport->vtable->connect(transport, name, exec, fd);
1291        else
1292                die("Operation not supported by protocol");
1293}
1294
1295int transport_disconnect(struct transport *transport)
1296{
1297        int ret = 0;
1298        if (transport->vtable->disconnect)
1299                ret = transport->vtable->disconnect(transport);
1300        free(transport);
1301        return ret;
1302}
1303
1304/*
1305 * Strip username (and password) from a URL and return
1306 * it in a newly allocated string.
1307 */
1308char *transport_anonymize_url(const char *url)
1309{
1310        char *scheme_prefix, *anon_part;
1311        size_t anon_len, prefix_len = 0;
1312
1313        anon_part = strchr(url, '@');
1314        if (url_is_local_not_ssh(url) || !anon_part)
1315                goto literal_copy;
1316
1317        anon_len = strlen(++anon_part);
1318        scheme_prefix = strstr(url, "://");
1319        if (!scheme_prefix) {
1320                if (!strchr(anon_part, ':'))
1321                        /* cannot be "me@there:/path/name" */
1322                        goto literal_copy;
1323        } else {
1324                const char *cp;
1325                /* make sure scheme is reasonable */
1326                for (cp = url; cp < scheme_prefix; cp++) {
1327                        switch (*cp) {
1328                                /* RFC 1738 2.1 */
1329                        case '+': case '.': case '-':
1330                                break; /* ok */
1331                        default:
1332                                if (isalnum(*cp))
1333                                        break;
1334                                /* it isn't */
1335                                goto literal_copy;
1336                        }
1337                }
1338                /* @ past the first slash does not count */
1339                cp = strchr(scheme_prefix + 3, '/');
1340                if (cp && cp < anon_part)
1341                        goto literal_copy;
1342                prefix_len = scheme_prefix - url + 3;
1343        }
1344        return xstrfmt("%.*s%.*s", (int)prefix_len, url,
1345                       (int)anon_len, anon_part);
1346literal_copy:
1347        return xstrdup(url);
1348}
1349
1350static void read_alternate_refs(const char *path,
1351                                alternate_ref_fn *cb,
1352                                void *data)
1353{
1354        struct child_process cmd = CHILD_PROCESS_INIT;
1355        struct strbuf line = STRBUF_INIT;
1356        FILE *fh;
1357
1358        cmd.git_cmd = 1;
1359        argv_array_pushf(&cmd.args, "--git-dir=%s", path);
1360        argv_array_push(&cmd.args, "for-each-ref");
1361        argv_array_push(&cmd.args, "--format=%(objectname) %(refname)");
1362        cmd.env = local_repo_env;
1363        cmd.out = -1;
1364
1365        if (start_command(&cmd))
1366                return;
1367
1368        fh = xfdopen(cmd.out, "r");
1369        while (strbuf_getline_lf(&line, fh) != EOF) {
1370                struct object_id oid;
1371
1372                if (get_oid_hex(line.buf, &oid) ||
1373                    line.buf[GIT_SHA1_HEXSZ] != ' ') {
1374                        warning("invalid line while parsing alternate refs: %s",
1375                                line.buf);
1376                        break;
1377                }
1378
1379                cb(line.buf + GIT_SHA1_HEXSZ + 1, &oid, data);
1380        }
1381
1382        fclose(fh);
1383        finish_command(&cmd);
1384}
1385
1386struct alternate_refs_data {
1387        alternate_ref_fn *fn;
1388        void *data;
1389};
1390
1391static int refs_from_alternate_cb(struct alternate_object_database *e,
1392                                  void *data)
1393{
1394        struct strbuf path = STRBUF_INIT;
1395        size_t base_len;
1396        struct alternate_refs_data *cb = data;
1397
1398        if (!strbuf_realpath(&path, e->path, 0))
1399                goto out;
1400        if (!strbuf_strip_suffix(&path, "/objects"))
1401                goto out;
1402        base_len = path.len;
1403
1404        /* Is this a git repository with refs? */
1405        strbuf_addstr(&path, "/refs");
1406        if (!is_directory(path.buf))
1407                goto out;
1408        strbuf_setlen(&path, base_len);
1409
1410        read_alternate_refs(path.buf, cb->fn, cb->data);
1411
1412out:
1413        strbuf_release(&path);
1414        return 0;
1415}
1416
1417void for_each_alternate_ref(alternate_ref_fn fn, void *data)
1418{
1419        struct alternate_refs_data cb;
1420        cb.fn = fn;
1421        cb.data = data;
1422        foreach_alt_odb(refs_from_alternate_cb, &cb);
1423}