builtin-remote.con commit Merge branch 'ak/maint-for-each-ref-no-lookup' (3b91202)
   1#include "cache.h"
   2#include "parse-options.h"
   3#include "transport.h"
   4#include "remote.h"
   5#include "string-list.h"
   6#include "strbuf.h"
   7#include "run-command.h"
   8#include "refs.h"
   9
  10static const char * const builtin_remote_usage[] = {
  11        "git remote [-v | --verbose]",
  12        "git remote add [-t <branch>] [-m <master>] [-f] [--mirror] <name> <url>",
  13        "git remote rename <old> <new>",
  14        "git remote rm <name>",
  15        "git remote set-head <name> [-a | -d | <branch>]",
  16        "git remote show [-n] <name>",
  17        "git remote prune [-n | --dry-run] <name>",
  18        "git remote [-v | --verbose] update [-p | --prune] [group]",
  19        NULL
  20};
  21
  22#define GET_REF_STATES (1<<0)
  23#define GET_HEAD_NAMES (1<<1)
  24#define GET_PUSH_REF_STATES (1<<2)
  25
  26static int verbose;
  27
  28static int show_all(void);
  29static int prune_remote(const char *remote, int dry_run);
  30
  31static inline int postfixcmp(const char *string, const char *postfix)
  32{
  33        int len1 = strlen(string), len2 = strlen(postfix);
  34        if (len1 < len2)
  35                return 1;
  36        return strcmp(string + len1 - len2, postfix);
  37}
  38
  39static int opt_parse_track(const struct option *opt, const char *arg, int not)
  40{
  41        struct string_list *list = opt->value;
  42        if (not)
  43                string_list_clear(list, 0);
  44        else
  45                string_list_append(arg, list);
  46        return 0;
  47}
  48
  49static int fetch_remote(const char *name)
  50{
  51        const char *argv[] = { "fetch", name, NULL, NULL };
  52        if (verbose) {
  53                argv[1] = "-v";
  54                argv[2] = name;
  55        }
  56        printf("Updating %s\n", name);
  57        if (run_command_v_opt(argv, RUN_GIT_CMD))
  58                return error("Could not fetch %s", name);
  59        return 0;
  60}
  61
  62static int add(int argc, const char **argv)
  63{
  64        int fetch = 0, mirror = 0;
  65        struct string_list track = { NULL, 0, 0 };
  66        const char *master = NULL;
  67        struct remote *remote;
  68        struct strbuf buf = STRBUF_INIT, buf2 = STRBUF_INIT;
  69        const char *name, *url;
  70        int i;
  71
  72        struct option options[] = {
  73                OPT_GROUP("add specific options"),
  74                OPT_BOOLEAN('f', "fetch", &fetch, "fetch the remote branches"),
  75                OPT_CALLBACK('t', "track", &track, "branch",
  76                        "branch(es) to track", opt_parse_track),
  77                OPT_STRING('m', "master", &master, "branch", "master branch"),
  78                OPT_BOOLEAN(0, "mirror", &mirror, "no separate remotes"),
  79                OPT_END()
  80        };
  81
  82        argc = parse_options(argc, argv, NULL, options, builtin_remote_usage,
  83                             0);
  84
  85        if (argc < 2)
  86                usage_with_options(builtin_remote_usage, options);
  87
  88        name = argv[0];
  89        url = argv[1];
  90
  91        remote = remote_get(name);
  92        if (remote && (remote->url_nr > 1 || strcmp(name, remote->url[0]) ||
  93                        remote->fetch_refspec_nr))
  94                die("remote %s already exists.", name);
  95
  96        strbuf_addf(&buf2, "refs/heads/test:refs/remotes/%s/test", name);
  97        if (!valid_fetch_refspec(buf2.buf))
  98                die("'%s' is not a valid remote name", name);
  99
 100        strbuf_addf(&buf, "remote.%s.url", name);
 101        if (git_config_set(buf.buf, url))
 102                return 1;
 103
 104        strbuf_reset(&buf);
 105        strbuf_addf(&buf, "remote.%s.fetch", name);
 106
 107        if (track.nr == 0)
 108                string_list_append("*", &track);
 109        for (i = 0; i < track.nr; i++) {
 110                struct string_list_item *item = track.items + i;
 111
 112                strbuf_reset(&buf2);
 113                strbuf_addch(&buf2, '+');
 114                if (mirror)
 115                        strbuf_addf(&buf2, "refs/%s:refs/%s",
 116                                        item->string, item->string);
 117                else
 118                        strbuf_addf(&buf2, "refs/heads/%s:refs/remotes/%s/%s",
 119                                        item->string, name, item->string);
 120                if (git_config_set_multivar(buf.buf, buf2.buf, "^$", 0))
 121                        return 1;
 122        }
 123
 124        if (mirror) {
 125                strbuf_reset(&buf);
 126                strbuf_addf(&buf, "remote.%s.mirror", name);
 127                if (git_config_set(buf.buf, "true"))
 128                        return 1;
 129        }
 130
 131        if (fetch && fetch_remote(name))
 132                return 1;
 133
 134        if (master) {
 135                strbuf_reset(&buf);
 136                strbuf_addf(&buf, "refs/remotes/%s/HEAD", name);
 137
 138                strbuf_reset(&buf2);
 139                strbuf_addf(&buf2, "refs/remotes/%s/%s", name, master);
 140
 141                if (create_symref(buf.buf, buf2.buf, "remote add"))
 142                        return error("Could not setup master '%s'", master);
 143        }
 144
 145        strbuf_release(&buf);
 146        strbuf_release(&buf2);
 147        string_list_clear(&track, 0);
 148
 149        return 0;
 150}
 151
 152struct branch_info {
 153        char *remote_name;
 154        struct string_list merge;
 155        int rebase;
 156};
 157
 158static struct string_list branch_list;
 159
 160static const char *abbrev_ref(const char *name, const char *prefix)
 161{
 162        const char *abbrev = skip_prefix(name, prefix);
 163        if (abbrev)
 164                return abbrev;
 165        return name;
 166}
 167#define abbrev_branch(name) abbrev_ref((name), "refs/heads/")
 168
 169static int config_read_branches(const char *key, const char *value, void *cb)
 170{
 171        if (!prefixcmp(key, "branch.")) {
 172                const char *orig_key = key;
 173                char *name;
 174                struct string_list_item *item;
 175                struct branch_info *info;
 176                enum { REMOTE, MERGE, REBASE } type;
 177
 178                key += 7;
 179                if (!postfixcmp(key, ".remote")) {
 180                        name = xstrndup(key, strlen(key) - 7);
 181                        type = REMOTE;
 182                } else if (!postfixcmp(key, ".merge")) {
 183                        name = xstrndup(key, strlen(key) - 6);
 184                        type = MERGE;
 185                } else if (!postfixcmp(key, ".rebase")) {
 186                        name = xstrndup(key, strlen(key) - 7);
 187                        type = REBASE;
 188                } else
 189                        return 0;
 190
 191                item = string_list_insert(name, &branch_list);
 192
 193                if (!item->util)
 194                        item->util = xcalloc(sizeof(struct branch_info), 1);
 195                info = item->util;
 196                if (type == REMOTE) {
 197                        if (info->remote_name)
 198                                warning("more than one %s", orig_key);
 199                        info->remote_name = xstrdup(value);
 200                } else if (type == MERGE) {
 201                        char *space = strchr(value, ' ');
 202                        value = abbrev_branch(value);
 203                        while (space) {
 204                                char *merge;
 205                                merge = xstrndup(value, space - value);
 206                                string_list_append(merge, &info->merge);
 207                                value = abbrev_branch(space + 1);
 208                                space = strchr(value, ' ');
 209                        }
 210                        string_list_append(xstrdup(value), &info->merge);
 211                } else
 212                        info->rebase = git_config_bool(orig_key, value);
 213        }
 214        return 0;
 215}
 216
 217static void read_branches(void)
 218{
 219        if (branch_list.nr)
 220                return;
 221        git_config(config_read_branches, NULL);
 222}
 223
 224struct ref_states {
 225        struct remote *remote;
 226        struct string_list new, stale, tracked, heads, push;
 227        int queried;
 228};
 229
 230static int handle_one_branch(const char *refname,
 231        const unsigned char *sha1, int flags, void *cb_data)
 232{
 233        struct ref_states *states = cb_data;
 234        struct refspec refspec;
 235
 236        memset(&refspec, 0, sizeof(refspec));
 237        refspec.dst = (char *)refname;
 238        if (!remote_find_tracking(states->remote, &refspec)) {
 239                struct string_list_item *item;
 240                const char *name = abbrev_branch(refspec.src);
 241                /* symbolic refs pointing nowhere were handled already */
 242                if ((flags & REF_ISSYMREF) ||
 243                    string_list_has_string(&states->tracked, name) ||
 244                    string_list_has_string(&states->new, name))
 245                        return 0;
 246                item = string_list_append(name, &states->stale);
 247                item->util = xstrdup(refname);
 248        }
 249        return 0;
 250}
 251
 252static int get_ref_states(const struct ref *remote_refs, struct ref_states *states)
 253{
 254        struct ref *fetch_map = NULL, **tail = &fetch_map;
 255        struct ref *ref;
 256        int i;
 257
 258        for (i = 0; i < states->remote->fetch_refspec_nr; i++)
 259                if (get_fetch_map(remote_refs, states->remote->fetch + i, &tail, 1))
 260                        die("Could not get fetch map for refspec %s",
 261                                states->remote->fetch_refspec[i]);
 262
 263        states->new.strdup_strings = states->tracked.strdup_strings = 1;
 264        for (ref = fetch_map; ref; ref = ref->next) {
 265                unsigned char sha1[20];
 266                if (!ref->peer_ref || read_ref(ref->peer_ref->name, sha1))
 267                        string_list_append(abbrev_branch(ref->name), &states->new);
 268                else
 269                        string_list_append(abbrev_branch(ref->name), &states->tracked);
 270        }
 271        free_refs(fetch_map);
 272
 273        sort_string_list(&states->new);
 274        sort_string_list(&states->tracked);
 275        for_each_ref(handle_one_branch, states);
 276        sort_string_list(&states->stale);
 277
 278        return 0;
 279}
 280
 281struct push_info {
 282        char *dest;
 283        int forced;
 284        enum {
 285                PUSH_STATUS_CREATE = 0,
 286                PUSH_STATUS_DELETE,
 287                PUSH_STATUS_UPTODATE,
 288                PUSH_STATUS_FASTFORWARD,
 289                PUSH_STATUS_OUTOFDATE,
 290                PUSH_STATUS_NOTQUERIED,
 291        } status;
 292};
 293
 294static int get_push_ref_states(const struct ref *remote_refs,
 295        struct ref_states *states)
 296{
 297        struct remote *remote = states->remote;
 298        struct ref *ref, *local_refs, *push_map;
 299        if (remote->mirror)
 300                return 0;
 301
 302        local_refs = get_local_heads();
 303        push_map = copy_ref_list(remote_refs);
 304
 305        match_refs(local_refs, &push_map, remote->push_refspec_nr,
 306                   remote->push_refspec, MATCH_REFS_NONE);
 307
 308        states->push.strdup_strings = 1;
 309        for (ref = push_map; ref; ref = ref->next) {
 310                struct string_list_item *item;
 311                struct push_info *info;
 312
 313                if (!ref->peer_ref)
 314                        continue;
 315                hashcpy(ref->new_sha1, ref->peer_ref->new_sha1);
 316
 317                item = string_list_append(abbrev_branch(ref->peer_ref->name),
 318                                          &states->push);
 319                item->util = xcalloc(sizeof(struct push_info), 1);
 320                info = item->util;
 321                info->forced = ref->force;
 322                info->dest = xstrdup(abbrev_branch(ref->name));
 323
 324                if (is_null_sha1(ref->new_sha1)) {
 325                        info->status = PUSH_STATUS_DELETE;
 326                } else if (!hashcmp(ref->old_sha1, ref->new_sha1))
 327                        info->status = PUSH_STATUS_UPTODATE;
 328                else if (is_null_sha1(ref->old_sha1))
 329                        info->status = PUSH_STATUS_CREATE;
 330                else if (has_sha1_file(ref->old_sha1) &&
 331                         ref_newer(ref->new_sha1, ref->old_sha1))
 332                        info->status = PUSH_STATUS_FASTFORWARD;
 333                else
 334                        info->status = PUSH_STATUS_OUTOFDATE;
 335        }
 336        free_refs(local_refs);
 337        free_refs(push_map);
 338        return 0;
 339}
 340
 341static int get_push_ref_states_noquery(struct ref_states *states)
 342{
 343        int i;
 344        struct remote *remote = states->remote;
 345        struct string_list_item *item;
 346        struct push_info *info;
 347
 348        if (remote->mirror)
 349                return 0;
 350
 351        states->push.strdup_strings = 1;
 352        if (!remote->push_refspec_nr) {
 353                item = string_list_append("(matching)", &states->push);
 354                info = item->util = xcalloc(sizeof(struct push_info), 1);
 355                info->status = PUSH_STATUS_NOTQUERIED;
 356                info->dest = xstrdup(item->string);
 357        }
 358        for (i = 0; i < remote->push_refspec_nr; i++) {
 359                struct refspec *spec = remote->push + i;
 360                if (spec->matching)
 361                        item = string_list_append("(matching)", &states->push);
 362                else if (strlen(spec->src))
 363                        item = string_list_append(spec->src, &states->push);
 364                else
 365                        item = string_list_append("(delete)", &states->push);
 366
 367                info = item->util = xcalloc(sizeof(struct push_info), 1);
 368                info->forced = spec->force;
 369                info->status = PUSH_STATUS_NOTQUERIED;
 370                info->dest = xstrdup(spec->dst ? spec->dst : item->string);
 371        }
 372        return 0;
 373}
 374
 375static int get_head_names(const struct ref *remote_refs, struct ref_states *states)
 376{
 377        struct ref *ref, *matches;
 378        struct ref *fetch_map = NULL, **fetch_map_tail = &fetch_map;
 379        struct refspec refspec;
 380
 381        refspec.force = 0;
 382        refspec.pattern = 1;
 383        refspec.src = refspec.dst = "refs/heads/*";
 384        states->heads.strdup_strings = 1;
 385        get_fetch_map(remote_refs, &refspec, &fetch_map_tail, 0);
 386        matches = guess_remote_head(find_ref_by_name(remote_refs, "HEAD"),
 387                                    fetch_map, 1);
 388        for(ref = matches; ref; ref = ref->next)
 389                string_list_append(abbrev_branch(ref->name), &states->heads);
 390
 391        free_refs(fetch_map);
 392        free_refs(matches);
 393
 394        return 0;
 395}
 396
 397struct known_remote {
 398        struct known_remote *next;
 399        struct remote *remote;
 400};
 401
 402struct known_remotes {
 403        struct remote *to_delete;
 404        struct known_remote *list;
 405};
 406
 407static int add_known_remote(struct remote *remote, void *cb_data)
 408{
 409        struct known_remotes *all = cb_data;
 410        struct known_remote *r;
 411
 412        if (!strcmp(all->to_delete->name, remote->name))
 413                return 0;
 414
 415        r = xmalloc(sizeof(*r));
 416        r->remote = remote;
 417        r->next = all->list;
 418        all->list = r;
 419        return 0;
 420}
 421
 422struct branches_for_remote {
 423        struct remote *remote;
 424        struct string_list *branches, *skipped;
 425        struct known_remotes *keep;
 426};
 427
 428static int add_branch_for_removal(const char *refname,
 429        const unsigned char *sha1, int flags, void *cb_data)
 430{
 431        struct branches_for_remote *branches = cb_data;
 432        struct refspec refspec;
 433        struct string_list_item *item;
 434        struct known_remote *kr;
 435
 436        memset(&refspec, 0, sizeof(refspec));
 437        refspec.dst = (char *)refname;
 438        if (remote_find_tracking(branches->remote, &refspec))
 439                return 0;
 440
 441        /* don't delete a branch if another remote also uses it */
 442        for (kr = branches->keep->list; kr; kr = kr->next) {
 443                memset(&refspec, 0, sizeof(refspec));
 444                refspec.dst = (char *)refname;
 445                if (!remote_find_tracking(kr->remote, &refspec))
 446                        return 0;
 447        }
 448
 449        /* don't delete non-remote refs */
 450        if (prefixcmp(refname, "refs/remotes")) {
 451                /* advise user how to delete local branches */
 452                if (!prefixcmp(refname, "refs/heads/"))
 453                        string_list_append(abbrev_branch(refname),
 454                                           branches->skipped);
 455                /* silently skip over other non-remote refs */
 456                return 0;
 457        }
 458
 459        /* make sure that symrefs are deleted */
 460        if (flags & REF_ISSYMREF)
 461                return unlink(git_path("%s", refname));
 462
 463        item = string_list_append(refname, branches->branches);
 464        item->util = xmalloc(20);
 465        hashcpy(item->util, sha1);
 466
 467        return 0;
 468}
 469
 470struct rename_info {
 471        const char *old;
 472        const char *new;
 473        struct string_list *remote_branches;
 474};
 475
 476static int read_remote_branches(const char *refname,
 477        const unsigned char *sha1, int flags, void *cb_data)
 478{
 479        struct rename_info *rename = cb_data;
 480        struct strbuf buf = STRBUF_INIT;
 481        struct string_list_item *item;
 482        int flag;
 483        unsigned char orig_sha1[20];
 484        const char *symref;
 485
 486        strbuf_addf(&buf, "refs/remotes/%s", rename->old);
 487        if(!prefixcmp(refname, buf.buf)) {
 488                item = string_list_append(xstrdup(refname), rename->remote_branches);
 489                symref = resolve_ref(refname, orig_sha1, 1, &flag);
 490                if (flag & REF_ISSYMREF)
 491                        item->util = xstrdup(symref);
 492                else
 493                        item->util = NULL;
 494        }
 495
 496        return 0;
 497}
 498
 499static int migrate_file(struct remote *remote)
 500{
 501        struct strbuf buf = STRBUF_INIT;
 502        int i;
 503        char *path = NULL;
 504
 505        strbuf_addf(&buf, "remote.%s.url", remote->name);
 506        for (i = 0; i < remote->url_nr; i++)
 507                if (git_config_set_multivar(buf.buf, remote->url[i], "^$", 0))
 508                        return error("Could not append '%s' to '%s'",
 509                                        remote->url[i], buf.buf);
 510        strbuf_reset(&buf);
 511        strbuf_addf(&buf, "remote.%s.push", remote->name);
 512        for (i = 0; i < remote->push_refspec_nr; i++)
 513                if (git_config_set_multivar(buf.buf, remote->push_refspec[i], "^$", 0))
 514                        return error("Could not append '%s' to '%s'",
 515                                        remote->push_refspec[i], buf.buf);
 516        strbuf_reset(&buf);
 517        strbuf_addf(&buf, "remote.%s.fetch", remote->name);
 518        for (i = 0; i < remote->fetch_refspec_nr; i++)
 519                if (git_config_set_multivar(buf.buf, remote->fetch_refspec[i], "^$", 0))
 520                        return error("Could not append '%s' to '%s'",
 521                                        remote->fetch_refspec[i], buf.buf);
 522        if (remote->origin == REMOTE_REMOTES)
 523                path = git_path("remotes/%s", remote->name);
 524        else if (remote->origin == REMOTE_BRANCHES)
 525                path = git_path("branches/%s", remote->name);
 526        if (path)
 527                unlink_or_warn(path);
 528        return 0;
 529}
 530
 531static int mv(int argc, const char **argv)
 532{
 533        struct option options[] = {
 534                OPT_END()
 535        };
 536        struct remote *oldremote, *newremote;
 537        struct strbuf buf = STRBUF_INIT, buf2 = STRBUF_INIT, buf3 = STRBUF_INIT;
 538        struct string_list remote_branches = { NULL, 0, 0, 0 };
 539        struct rename_info rename;
 540        int i;
 541
 542        if (argc != 3)
 543                usage_with_options(builtin_remote_usage, options);
 544
 545        rename.old = argv[1];
 546        rename.new = argv[2];
 547        rename.remote_branches = &remote_branches;
 548
 549        oldremote = remote_get(rename.old);
 550        if (!oldremote)
 551                die("No such remote: %s", rename.old);
 552
 553        if (!strcmp(rename.old, rename.new) && oldremote->origin != REMOTE_CONFIG)
 554                return migrate_file(oldremote);
 555
 556        newremote = remote_get(rename.new);
 557        if (newremote && (newremote->url_nr > 1 || newremote->fetch_refspec_nr))
 558                die("remote %s already exists.", rename.new);
 559
 560        strbuf_addf(&buf, "refs/heads/test:refs/remotes/%s/test", rename.new);
 561        if (!valid_fetch_refspec(buf.buf))
 562                die("'%s' is not a valid remote name", rename.new);
 563
 564        strbuf_reset(&buf);
 565        strbuf_addf(&buf, "remote.%s", rename.old);
 566        strbuf_addf(&buf2, "remote.%s", rename.new);
 567        if (git_config_rename_section(buf.buf, buf2.buf) < 1)
 568                return error("Could not rename config section '%s' to '%s'",
 569                                buf.buf, buf2.buf);
 570
 571        strbuf_reset(&buf);
 572        strbuf_addf(&buf, "remote.%s.fetch", rename.new);
 573        if (git_config_set_multivar(buf.buf, NULL, NULL, 1))
 574                return error("Could not remove config section '%s'", buf.buf);
 575        for (i = 0; i < oldremote->fetch_refspec_nr; i++) {
 576                char *ptr;
 577
 578                strbuf_reset(&buf2);
 579                strbuf_addstr(&buf2, oldremote->fetch_refspec[i]);
 580                ptr = strstr(buf2.buf, rename.old);
 581                if (ptr)
 582                        strbuf_splice(&buf2, ptr-buf2.buf, strlen(rename.old),
 583                                        rename.new, strlen(rename.new));
 584                if (git_config_set_multivar(buf.buf, buf2.buf, "^$", 0))
 585                        return error("Could not append '%s'", buf.buf);
 586        }
 587
 588        read_branches();
 589        for (i = 0; i < branch_list.nr; i++) {
 590                struct string_list_item *item = branch_list.items + i;
 591                struct branch_info *info = item->util;
 592                if (info->remote_name && !strcmp(info->remote_name, rename.old)) {
 593                        strbuf_reset(&buf);
 594                        strbuf_addf(&buf, "branch.%s.remote", item->string);
 595                        if (git_config_set(buf.buf, rename.new)) {
 596                                return error("Could not set '%s'", buf.buf);
 597                        }
 598                }
 599        }
 600
 601        /*
 602         * First remove symrefs, then rename the rest, finally create
 603         * the new symrefs.
 604         */
 605        for_each_ref(read_remote_branches, &rename);
 606        for (i = 0; i < remote_branches.nr; i++) {
 607                struct string_list_item *item = remote_branches.items + i;
 608                int flag = 0;
 609                unsigned char sha1[20];
 610
 611                resolve_ref(item->string, sha1, 1, &flag);
 612                if (!(flag & REF_ISSYMREF))
 613                        continue;
 614                if (delete_ref(item->string, NULL, REF_NODEREF))
 615                        die("deleting '%s' failed", item->string);
 616        }
 617        for (i = 0; i < remote_branches.nr; i++) {
 618                struct string_list_item *item = remote_branches.items + i;
 619
 620                if (item->util)
 621                        continue;
 622                strbuf_reset(&buf);
 623                strbuf_addstr(&buf, item->string);
 624                strbuf_splice(&buf, strlen("refs/remotes/"), strlen(rename.old),
 625                                rename.new, strlen(rename.new));
 626                strbuf_reset(&buf2);
 627                strbuf_addf(&buf2, "remote: renamed %s to %s",
 628                                item->string, buf.buf);
 629                if (rename_ref(item->string, buf.buf, buf2.buf))
 630                        die("renaming '%s' failed", item->string);
 631        }
 632        for (i = 0; i < remote_branches.nr; i++) {
 633                struct string_list_item *item = remote_branches.items + i;
 634
 635                if (!item->util)
 636                        continue;
 637                strbuf_reset(&buf);
 638                strbuf_addstr(&buf, item->string);
 639                strbuf_splice(&buf, strlen("refs/remotes/"), strlen(rename.old),
 640                                rename.new, strlen(rename.new));
 641                strbuf_reset(&buf2);
 642                strbuf_addstr(&buf2, item->util);
 643                strbuf_splice(&buf2, strlen("refs/remotes/"), strlen(rename.old),
 644                                rename.new, strlen(rename.new));
 645                strbuf_reset(&buf3);
 646                strbuf_addf(&buf3, "remote: renamed %s to %s",
 647                                item->string, buf.buf);
 648                if (create_symref(buf.buf, buf2.buf, buf3.buf))
 649                        die("creating '%s' failed", buf.buf);
 650        }
 651        return 0;
 652}
 653
 654static int remove_branches(struct string_list *branches)
 655{
 656        int i, result = 0;
 657        for (i = 0; i < branches->nr; i++) {
 658                struct string_list_item *item = branches->items + i;
 659                const char *refname = item->string;
 660                unsigned char *sha1 = item->util;
 661
 662                if (delete_ref(refname, sha1, 0))
 663                        result |= error("Could not remove branch %s", refname);
 664        }
 665        return result;
 666}
 667
 668static int rm(int argc, const char **argv)
 669{
 670        struct option options[] = {
 671                OPT_END()
 672        };
 673        struct remote *remote;
 674        struct strbuf buf = STRBUF_INIT;
 675        struct known_remotes known_remotes = { NULL, NULL };
 676        struct string_list branches = { NULL, 0, 0, 1 };
 677        struct string_list skipped = { NULL, 0, 0, 1 };
 678        struct branches_for_remote cb_data = {
 679                NULL, &branches, &skipped, &known_remotes
 680        };
 681        int i, result;
 682
 683        if (argc != 2)
 684                usage_with_options(builtin_remote_usage, options);
 685
 686        remote = remote_get(argv[1]);
 687        if (!remote)
 688                die("No such remote: %s", argv[1]);
 689
 690        known_remotes.to_delete = remote;
 691        for_each_remote(add_known_remote, &known_remotes);
 692
 693        strbuf_addf(&buf, "remote.%s", remote->name);
 694        if (git_config_rename_section(buf.buf, NULL) < 1)
 695                return error("Could not remove config section '%s'", buf.buf);
 696
 697        read_branches();
 698        for (i = 0; i < branch_list.nr; i++) {
 699                struct string_list_item *item = branch_list.items + i;
 700                struct branch_info *info = item->util;
 701                if (info->remote_name && !strcmp(info->remote_name, remote->name)) {
 702                        const char *keys[] = { "remote", "merge", NULL }, **k;
 703                        for (k = keys; *k; k++) {
 704                                strbuf_reset(&buf);
 705                                strbuf_addf(&buf, "branch.%s.%s",
 706                                                item->string, *k);
 707                                if (git_config_set(buf.buf, NULL)) {
 708                                        strbuf_release(&buf);
 709                                        return -1;
 710                                }
 711                        }
 712                }
 713        }
 714
 715        /*
 716         * We cannot just pass a function to for_each_ref() which deletes
 717         * the branches one by one, since for_each_ref() relies on cached
 718         * refs, which are invalidated when deleting a branch.
 719         */
 720        cb_data.remote = remote;
 721        result = for_each_ref(add_branch_for_removal, &cb_data);
 722        strbuf_release(&buf);
 723
 724        if (!result)
 725                result = remove_branches(&branches);
 726        string_list_clear(&branches, 1);
 727
 728        if (skipped.nr) {
 729                fprintf(stderr, skipped.nr == 1 ?
 730                        "Note: A non-remote branch was not removed; "
 731                        "to delete it, use:\n" :
 732                        "Note: Non-remote branches were not removed; "
 733                        "to delete them, use:\n");
 734                for (i = 0; i < skipped.nr; i++)
 735                        fprintf(stderr, "  git branch -d %s\n",
 736                                skipped.items[i].string);
 737        }
 738        string_list_clear(&skipped, 0);
 739
 740        return result;
 741}
 742
 743void clear_push_info(void *util, const char *string)
 744{
 745        struct push_info *info = util;
 746        free(info->dest);
 747        free(info);
 748}
 749
 750static void free_remote_ref_states(struct ref_states *states)
 751{
 752        string_list_clear(&states->new, 0);
 753        string_list_clear(&states->stale, 0);
 754        string_list_clear(&states->tracked, 0);
 755        string_list_clear(&states->heads, 0);
 756        string_list_clear_func(&states->push, clear_push_info);
 757}
 758
 759static int append_ref_to_tracked_list(const char *refname,
 760        const unsigned char *sha1, int flags, void *cb_data)
 761{
 762        struct ref_states *states = cb_data;
 763        struct refspec refspec;
 764
 765        if (flags & REF_ISSYMREF)
 766                return 0;
 767
 768        memset(&refspec, 0, sizeof(refspec));
 769        refspec.dst = (char *)refname;
 770        if (!remote_find_tracking(states->remote, &refspec))
 771                string_list_append(abbrev_branch(refspec.src), &states->tracked);
 772
 773        return 0;
 774}
 775
 776static int get_remote_ref_states(const char *name,
 777                                 struct ref_states *states,
 778                                 int query)
 779{
 780        struct transport *transport;
 781        const struct ref *remote_refs;
 782
 783        states->remote = remote_get(name);
 784        if (!states->remote)
 785                return error("No such remote: %s", name);
 786
 787        read_branches();
 788
 789        if (query) {
 790                transport = transport_get(NULL, states->remote->url_nr > 0 ?
 791                        states->remote->url[0] : NULL);
 792                remote_refs = transport_get_remote_refs(transport);
 793                transport_disconnect(transport);
 794
 795                states->queried = 1;
 796                if (query & GET_REF_STATES)
 797                        get_ref_states(remote_refs, states);
 798                if (query & GET_HEAD_NAMES)
 799                        get_head_names(remote_refs, states);
 800                if (query & GET_PUSH_REF_STATES)
 801                        get_push_ref_states(remote_refs, states);
 802        } else {
 803                for_each_ref(append_ref_to_tracked_list, states);
 804                sort_string_list(&states->tracked);
 805                get_push_ref_states_noquery(states);
 806        }
 807
 808        return 0;
 809}
 810
 811struct show_info {
 812        struct string_list *list;
 813        struct ref_states *states;
 814        int width, width2;
 815        int any_rebase;
 816};
 817
 818int add_remote_to_show_info(struct string_list_item *item, void *cb_data)
 819{
 820        struct show_info *info = cb_data;
 821        int n = strlen(item->string);
 822        if (n > info->width)
 823                info->width = n;
 824        string_list_insert(item->string, info->list);
 825        return 0;
 826}
 827
 828int show_remote_info_item(struct string_list_item *item, void *cb_data)
 829{
 830        struct show_info *info = cb_data;
 831        struct ref_states *states = info->states;
 832        const char *name = item->string;
 833
 834        if (states->queried) {
 835                const char *fmt = "%s";
 836                const char *arg = "";
 837                if (string_list_has_string(&states->new, name)) {
 838                        fmt = " new (next fetch will store in remotes/%s)";
 839                        arg = states->remote->name;
 840                } else if (string_list_has_string(&states->tracked, name))
 841                        arg = " tracked";
 842                else if (string_list_has_string(&states->stale, name))
 843                        arg = " stale (use 'git remote prune' to remove)";
 844                else
 845                        arg = " ???";
 846                printf("    %-*s", info->width, name);
 847                printf(fmt, arg);
 848                printf("\n");
 849        } else
 850                printf("    %s\n", name);
 851
 852        return 0;
 853}
 854
 855int add_local_to_show_info(struct string_list_item *branch_item, void *cb_data)
 856{
 857        struct show_info *show_info = cb_data;
 858        struct ref_states *states = show_info->states;
 859        struct branch_info *branch_info = branch_item->util;
 860        struct string_list_item *item;
 861        int n;
 862
 863        if (!branch_info->merge.nr || !branch_info->remote_name ||
 864            strcmp(states->remote->name, branch_info->remote_name))
 865                return 0;
 866        if ((n = strlen(branch_item->string)) > show_info->width)
 867                show_info->width = n;
 868        if (branch_info->rebase)
 869                show_info->any_rebase = 1;
 870
 871        item = string_list_insert(branch_item->string, show_info->list);
 872        item->util = branch_info;
 873
 874        return 0;
 875}
 876
 877int show_local_info_item(struct string_list_item *item, void *cb_data)
 878{
 879        struct show_info *show_info = cb_data;
 880        struct branch_info *branch_info = item->util;
 881        struct string_list *merge = &branch_info->merge;
 882        const char *also;
 883        int i;
 884
 885        if (branch_info->rebase && branch_info->merge.nr > 1) {
 886                error("invalid branch.%s.merge; cannot rebase onto > 1 branch",
 887                        item->string);
 888                return 0;
 889        }
 890
 891        printf("    %-*s ", show_info->width, item->string);
 892        if (branch_info->rebase) {
 893                printf("rebases onto remote %s\n", merge->items[0].string);
 894                return 0;
 895        } else if (show_info->any_rebase) {
 896                printf(" merges with remote %s\n", merge->items[0].string);
 897                also = "    and with remote";
 898        } else {
 899                printf("merges with remote %s\n", merge->items[0].string);
 900                also = "   and with remote";
 901        }
 902        for (i = 1; i < merge->nr; i++)
 903                printf("    %-*s %s %s\n", show_info->width, "", also,
 904                       merge->items[i].string);
 905
 906        return 0;
 907}
 908
 909int add_push_to_show_info(struct string_list_item *push_item, void *cb_data)
 910{
 911        struct show_info *show_info = cb_data;
 912        struct push_info *push_info = push_item->util;
 913        struct string_list_item *item;
 914        int n;
 915        if ((n = strlen(push_item->string)) > show_info->width)
 916                show_info->width = n;
 917        if ((n = strlen(push_info->dest)) > show_info->width2)
 918                show_info->width2 = n;
 919        item = string_list_append(push_item->string, show_info->list);
 920        item->util = push_item->util;
 921        return 0;
 922}
 923
 924/*
 925 * Sorting comparison for a string list that has push_info
 926 * structs in its util field
 927 */
 928static int cmp_string_with_push(const void *va, const void *vb)
 929{
 930        const struct string_list_item *a = va;
 931        const struct string_list_item *b = vb;
 932        const struct push_info *a_push = a->util;
 933        const struct push_info *b_push = b->util;
 934        int cmp = strcmp(a->string, b->string);
 935        return cmp ? cmp : strcmp(a_push->dest, b_push->dest);
 936}
 937
 938int show_push_info_item(struct string_list_item *item, void *cb_data)
 939{
 940        struct show_info *show_info = cb_data;
 941        struct push_info *push_info = item->util;
 942        char *src = item->string, *status = NULL;
 943
 944        switch (push_info->status) {
 945        case PUSH_STATUS_CREATE:
 946                status = "create";
 947                break;
 948        case PUSH_STATUS_DELETE:
 949                status = "delete";
 950                src = "(none)";
 951                break;
 952        case PUSH_STATUS_UPTODATE:
 953                status = "up to date";
 954                break;
 955        case PUSH_STATUS_FASTFORWARD:
 956                status = "fast forwardable";
 957                break;
 958        case PUSH_STATUS_OUTOFDATE:
 959                status = "local out of date";
 960                break;
 961        case PUSH_STATUS_NOTQUERIED:
 962                break;
 963        }
 964        if (status)
 965                printf("    %-*s %s to %-*s (%s)\n", show_info->width, src,
 966                        push_info->forced ? "forces" : "pushes",
 967                        show_info->width2, push_info->dest, status);
 968        else
 969                printf("    %-*s %s to %s\n", show_info->width, src,
 970                        push_info->forced ? "forces" : "pushes",
 971                        push_info->dest);
 972        return 0;
 973}
 974
 975static int show(int argc, const char **argv)
 976{
 977        int no_query = 0, result = 0, query_flag = 0;
 978        struct option options[] = {
 979                OPT_GROUP("show specific options"),
 980                OPT_BOOLEAN('n', NULL, &no_query, "do not query remotes"),
 981                OPT_END()
 982        };
 983        struct ref_states states;
 984        struct string_list info_list = { NULL, 0, 0, 0 };
 985        struct show_info info;
 986
 987        argc = parse_options(argc, argv, NULL, options, builtin_remote_usage,
 988                             0);
 989
 990        if (argc < 1)
 991                return show_all();
 992
 993        if (!no_query)
 994                query_flag = (GET_REF_STATES | GET_HEAD_NAMES | GET_PUSH_REF_STATES);
 995
 996        memset(&states, 0, sizeof(states));
 997        memset(&info, 0, sizeof(info));
 998        info.states = &states;
 999        info.list = &info_list;
1000        for (; argc; argc--, argv++) {
1001                int i;
1002
1003                get_remote_ref_states(*argv, &states, query_flag);
1004
1005                printf("* remote %s\n", *argv);
1006                if (states.remote->url_nr) {
1007                        for (i=0; i < states.remote->url_nr; i++)
1008                                printf("  URL: %s\n", states.remote->url[i]);
1009                } else
1010                        printf("  URL: %s\n", "(no URL)");
1011                if (no_query)
1012                        printf("  HEAD branch: (not queried)\n");
1013                else if (!states.heads.nr)
1014                        printf("  HEAD branch: (unknown)\n");
1015                else if (states.heads.nr == 1)
1016                        printf("  HEAD branch: %s\n", states.heads.items[0].string);
1017                else {
1018                        printf("  HEAD branch (remote HEAD is ambiguous,"
1019                               " may be one of the following):\n");
1020                        for (i = 0; i < states.heads.nr; i++)
1021                                printf("    %s\n", states.heads.items[i].string);
1022                }
1023
1024                /* remote branch info */
1025                info.width = 0;
1026                for_each_string_list(add_remote_to_show_info, &states.new, &info);
1027                for_each_string_list(add_remote_to_show_info, &states.tracked, &info);
1028                for_each_string_list(add_remote_to_show_info, &states.stale, &info);
1029                if (info.list->nr)
1030                        printf("  Remote branch%s:%s\n",
1031                               info.list->nr > 1 ? "es" : "",
1032                                no_query ? " (status not queried)" : "");
1033                for_each_string_list(show_remote_info_item, info.list, &info);
1034                string_list_clear(info.list, 0);
1035
1036                /* git pull info */
1037                info.width = 0;
1038                info.any_rebase = 0;
1039                for_each_string_list(add_local_to_show_info, &branch_list, &info);
1040                if (info.list->nr)
1041                        printf("  Local branch%s configured for 'git pull':\n",
1042                               info.list->nr > 1 ? "es" : "");
1043                for_each_string_list(show_local_info_item, info.list, &info);
1044                string_list_clear(info.list, 0);
1045
1046                /* git push info */
1047                if (states.remote->mirror)
1048                        printf("  Local refs will be mirrored by 'git push'\n");
1049
1050                info.width = info.width2 = 0;
1051                for_each_string_list(add_push_to_show_info, &states.push, &info);
1052                qsort(info.list->items, info.list->nr,
1053                        sizeof(*info.list->items), cmp_string_with_push);
1054                if (info.list->nr)
1055                        printf("  Local ref%s configured for 'git push'%s:\n",
1056                                info.list->nr > 1 ? "s" : "",
1057                                no_query ? " (status not queried)" : "");
1058                for_each_string_list(show_push_info_item, info.list, &info);
1059                string_list_clear(info.list, 0);
1060
1061                free_remote_ref_states(&states);
1062        }
1063
1064        return result;
1065}
1066
1067static int set_head(int argc, const char **argv)
1068{
1069        int i, opt_a = 0, opt_d = 0, result = 0;
1070        struct strbuf buf = STRBUF_INIT, buf2 = STRBUF_INIT;
1071        char *head_name = NULL;
1072
1073        struct option options[] = {
1074                OPT_GROUP("set-head specific options"),
1075                OPT_BOOLEAN('a', "auto", &opt_a,
1076                            "set refs/remotes/<name>/HEAD according to remote"),
1077                OPT_BOOLEAN('d', "delete", &opt_d,
1078                            "delete refs/remotes/<name>/HEAD"),
1079                OPT_END()
1080        };
1081        argc = parse_options(argc, argv, NULL, options, builtin_remote_usage,
1082                             0);
1083        if (argc)
1084                strbuf_addf(&buf, "refs/remotes/%s/HEAD", argv[0]);
1085
1086        if (!opt_a && !opt_d && argc == 2) {
1087                head_name = xstrdup(argv[1]);
1088        } else if (opt_a && !opt_d && argc == 1) {
1089                struct ref_states states;
1090                memset(&states, 0, sizeof(states));
1091                get_remote_ref_states(argv[0], &states, GET_HEAD_NAMES);
1092                if (!states.heads.nr)
1093                        result |= error("Cannot determine remote HEAD");
1094                else if (states.heads.nr > 1) {
1095                        result |= error("Multiple remote HEAD branches. "
1096                                        "Please choose one explicitly with:");
1097                        for (i = 0; i < states.heads.nr; i++)
1098                                fprintf(stderr, "  git remote set-head %s %s\n",
1099                                        argv[0], states.heads.items[i].string);
1100                } else
1101                        head_name = xstrdup(states.heads.items[0].string);
1102                free_remote_ref_states(&states);
1103        } else if (opt_d && !opt_a && argc == 1) {
1104                if (delete_ref(buf.buf, NULL, REF_NODEREF))
1105                        result |= error("Could not delete %s", buf.buf);
1106        } else
1107                usage_with_options(builtin_remote_usage, options);
1108
1109        if (head_name) {
1110                unsigned char sha1[20];
1111                strbuf_addf(&buf2, "refs/remotes/%s/%s", argv[0], head_name);
1112                /* make sure it's valid */
1113                if (!resolve_ref(buf2.buf, sha1, 1, NULL))
1114                        result |= error("Not a valid ref: %s", buf2.buf);
1115                else if (create_symref(buf.buf, buf2.buf, "remote set-head"))
1116                        result |= error("Could not setup %s", buf.buf);
1117                if (opt_a)
1118                        printf("%s/HEAD set to %s\n", argv[0], head_name);
1119                free(head_name);
1120        }
1121
1122        strbuf_release(&buf);
1123        strbuf_release(&buf2);
1124        return result;
1125}
1126
1127static int prune(int argc, const char **argv)
1128{
1129        int dry_run = 0, result = 0;
1130        struct option options[] = {
1131                OPT_GROUP("prune specific options"),
1132                OPT__DRY_RUN(&dry_run),
1133                OPT_END()
1134        };
1135
1136        argc = parse_options(argc, argv, NULL, options, builtin_remote_usage,
1137                             0);
1138
1139        if (argc < 1)
1140                usage_with_options(builtin_remote_usage, options);
1141
1142        for (; argc; argc--, argv++)
1143                result |= prune_remote(*argv, dry_run);
1144
1145        return result;
1146}
1147
1148static int prune_remote(const char *remote, int dry_run)
1149{
1150        int result = 0, i;
1151        struct ref_states states;
1152        const char *dangling_msg = dry_run
1153                ? " %s will become dangling!\n"
1154                : " %s has become dangling!\n";
1155
1156        memset(&states, 0, sizeof(states));
1157        get_remote_ref_states(remote, &states, GET_REF_STATES);
1158
1159        if (states.stale.nr) {
1160                printf("Pruning %s\n", remote);
1161                printf("URL: %s\n",
1162                       states.remote->url_nr
1163                       ? states.remote->url[0]
1164                       : "(no URL)");
1165        }
1166
1167        for (i = 0; i < states.stale.nr; i++) {
1168                const char *refname = states.stale.items[i].util;
1169
1170                if (!dry_run)
1171                        result |= delete_ref(refname, NULL, 0);
1172
1173                printf(" * [%s] %s\n", dry_run ? "would prune" : "pruned",
1174                       abbrev_ref(refname, "refs/remotes/"));
1175                warn_dangling_symref(dangling_msg, refname);
1176        }
1177
1178        free_remote_ref_states(&states);
1179        return result;
1180}
1181
1182static int get_one_remote_for_update(struct remote *remote, void *priv)
1183{
1184        struct string_list *list = priv;
1185        if (!remote->skip_default_update)
1186                string_list_append(remote->name, list);
1187        return 0;
1188}
1189
1190struct remote_group {
1191        const char *name;
1192        struct string_list *list;
1193} remote_group;
1194
1195static int get_remote_group(const char *key, const char *value, void *num_hits)
1196{
1197        if (!prefixcmp(key, "remotes.") &&
1198                        !strcmp(key + 8, remote_group.name)) {
1199                /* split list by white space */
1200                int space = strcspn(value, " \t\n");
1201                while (*value) {
1202                        if (space > 1) {
1203                                string_list_append(xstrndup(value, space),
1204                                                remote_group.list);
1205                                ++*((int *)num_hits);
1206                        }
1207                        value += space + (value[space] != '\0');
1208                        space = strcspn(value, " \t\n");
1209                }
1210        }
1211
1212        return 0;
1213}
1214
1215static int update(int argc, const char **argv)
1216{
1217        int i, result = 0, prune = 0;
1218        struct string_list list = { NULL, 0, 0, 0 };
1219        static const char *default_argv[] = { NULL, "default", NULL };
1220        struct option options[] = {
1221                OPT_GROUP("update specific options"),
1222                OPT_BOOLEAN('p', "prune", &prune,
1223                            "prune remotes after fetching"),
1224                OPT_END()
1225        };
1226
1227        argc = parse_options(argc, argv, NULL, options, builtin_remote_usage,
1228                             PARSE_OPT_KEEP_ARGV0);
1229        if (argc < 2) {
1230                argc = 2;
1231                argv = default_argv;
1232        }
1233
1234        remote_group.list = &list;
1235        for (i = 1; i < argc; i++) {
1236                int groups_found = 0;
1237                remote_group.name = argv[i];
1238                result = git_config(get_remote_group, &groups_found);
1239                if (!groups_found && (i != 1 || strcmp(argv[1], "default"))) {
1240                        struct remote *remote;
1241                        if (!remote_is_configured(argv[i]))
1242                                die("No such remote or remote group: %s",
1243                                    argv[i]);
1244                        remote = remote_get(argv[i]);
1245                        string_list_append(remote->name, remote_group.list);
1246                }
1247        }
1248
1249        if (!result && !list.nr  && argc == 2 && !strcmp(argv[1], "default"))
1250                result = for_each_remote(get_one_remote_for_update, &list);
1251
1252        for (i = 0; i < list.nr; i++) {
1253                int err = fetch_remote(list.items[i].string);
1254                result |= err;
1255                if (!err && prune)
1256                        result |= prune_remote(list.items[i].string, 0);
1257        }
1258
1259        /* all names were strdup()ed or strndup()ed */
1260        list.strdup_strings = 1;
1261        string_list_clear(&list, 0);
1262
1263        return result;
1264}
1265
1266static int get_one_entry(struct remote *remote, void *priv)
1267{
1268        struct string_list *list = priv;
1269
1270        if (remote->url_nr > 0) {
1271                int i;
1272
1273                for (i = 0; i < remote->url_nr; i++)
1274                        string_list_append(remote->name, list)->util = (void *)remote->url[i];
1275        } else
1276                string_list_append(remote->name, list)->util = NULL;
1277
1278        return 0;
1279}
1280
1281static int show_all(void)
1282{
1283        struct string_list list = { NULL, 0, 0 };
1284        int result = for_each_remote(get_one_entry, &list);
1285
1286        if (!result) {
1287                int i;
1288
1289                sort_string_list(&list);
1290                for (i = 0; i < list.nr; i++) {
1291                        struct string_list_item *item = list.items + i;
1292                        if (verbose)
1293                                printf("%s\t%s\n", item->string,
1294                                        item->util ? (const char *)item->util : "");
1295                        else {
1296                                if (i && !strcmp((item - 1)->string, item->string))
1297                                        continue;
1298                                printf("%s\n", item->string);
1299                        }
1300                }
1301        }
1302        return result;
1303}
1304
1305int cmd_remote(int argc, const char **argv, const char *prefix)
1306{
1307        struct option options[] = {
1308                OPT__VERBOSE(&verbose),
1309                OPT_END()
1310        };
1311        int result;
1312
1313        argc = parse_options(argc, argv, prefix, options, builtin_remote_usage,
1314                PARSE_OPT_STOP_AT_NON_OPTION);
1315
1316        if (argc < 1)
1317                result = show_all();
1318        else if (!strcmp(argv[0], "add"))
1319                result = add(argc, argv);
1320        else if (!strcmp(argv[0], "rename"))
1321                result = mv(argc, argv);
1322        else if (!strcmp(argv[0], "rm"))
1323                result = rm(argc, argv);
1324        else if (!strcmp(argv[0], "set-head"))
1325                result = set_head(argc, argv);
1326        else if (!strcmp(argv[0], "show"))
1327                result = show(argc, argv);
1328        else if (!strcmp(argv[0], "prune"))
1329                result = prune(argc, argv);
1330        else if (!strcmp(argv[0], "update"))
1331                result = update(argc, argv);
1332        else {
1333                error("Unknown subcommand: %s", argv[0]);
1334                usage_with_options(builtin_remote_usage, options);
1335        }
1336
1337        return result ? 1 : 0;
1338}