f9b59b49a55d95d092d4de8cef438660ae65278e
   1/*
   2 * "git push"
   3 */
   4#include "cache.h"
   5#include "refs.h"
   6#include "run-command.h"
   7#include "builtin.h"
   8#include "remote.h"
   9#include "transport.h"
  10#include "parse-options.h"
  11#include "submodule.h"
  12#include "submodule-config.h"
  13#include "send-pack.h"
  14
  15static const char * const push_usage[] = {
  16        N_("git push [<options>] [<repository> [<refspec>...]]"),
  17        NULL,
  18};
  19
  20static int thin = 1;
  21static int deleterefs;
  22static const char *receivepack;
  23static int verbosity;
  24static int progress = -1, recurse_submodules = RECURSE_SUBMODULES_DEFAULT;
  25
  26static struct push_cas_option cas;
  27
  28static const char **refspec;
  29static int refspec_nr;
  30static int refspec_alloc;
  31
  32static void add_refspec(const char *ref)
  33{
  34        refspec_nr++;
  35        ALLOC_GROW(refspec, refspec_nr, refspec_alloc);
  36        refspec[refspec_nr-1] = ref;
  37}
  38
  39static const char *map_refspec(const char *ref,
  40                               struct remote *remote, struct ref *local_refs)
  41{
  42        struct ref *matched = NULL;
  43
  44        /* Does "ref" uniquely name our ref? */
  45        if (count_refspec_match(ref, local_refs, &matched) != 1)
  46                return ref;
  47
  48        if (remote->push) {
  49                struct refspec query;
  50                memset(&query, 0, sizeof(struct refspec));
  51                query.src = matched->name;
  52                if (!query_refspecs(remote->push, remote->push_refspec_nr, &query) &&
  53                    query.dst) {
  54                        struct strbuf buf = STRBUF_INIT;
  55                        strbuf_addf(&buf, "%s%s:%s",
  56                                    query.force ? "+" : "",
  57                                    query.src, query.dst);
  58                        return strbuf_detach(&buf, NULL);
  59                }
  60        }
  61
  62        if (push_default == PUSH_DEFAULT_UPSTREAM &&
  63            starts_with(matched->name, "refs/heads/")) {
  64                struct branch *branch = branch_get(matched->name + 11);
  65                if (branch->merge_nr == 1 && branch->merge[0]->src) {
  66                        struct strbuf buf = STRBUF_INIT;
  67                        strbuf_addf(&buf, "%s:%s",
  68                                    ref, branch->merge[0]->src);
  69                        return strbuf_detach(&buf, NULL);
  70                }
  71        }
  72
  73        return ref;
  74}
  75
  76static void set_refspecs(const char **refs, int nr, const char *repo)
  77{
  78        struct remote *remote = NULL;
  79        struct ref *local_refs = NULL;
  80        int i;
  81
  82        for (i = 0; i < nr; i++) {
  83                const char *ref = refs[i];
  84                if (!strcmp("tag", ref)) {
  85                        struct strbuf tagref = STRBUF_INIT;
  86                        if (nr <= ++i)
  87                                die(_("tag shorthand without <tag>"));
  88                        ref = refs[i];
  89                        if (deleterefs)
  90                                strbuf_addf(&tagref, ":refs/tags/%s", ref);
  91                        else
  92                                strbuf_addf(&tagref, "refs/tags/%s", ref);
  93                        ref = strbuf_detach(&tagref, NULL);
  94                } else if (deleterefs) {
  95                        struct strbuf delref = STRBUF_INIT;
  96                        if (strchr(ref, ':'))
  97                                die(_("--delete only accepts plain target ref names"));
  98                        strbuf_addf(&delref, ":%s", ref);
  99                        ref = strbuf_detach(&delref, NULL);
 100                } else if (!strchr(ref, ':')) {
 101                        if (!remote) {
 102                                /* lazily grab remote and local_refs */
 103                                remote = remote_get(repo);
 104                                local_refs = get_local_heads();
 105                        }
 106                        ref = map_refspec(ref, remote, local_refs);
 107                }
 108                add_refspec(ref);
 109        }
 110}
 111
 112static int push_url_of_remote(struct remote *remote, const char ***url_p)
 113{
 114        if (remote->pushurl_nr) {
 115                *url_p = remote->pushurl;
 116                return remote->pushurl_nr;
 117        }
 118        *url_p = remote->url;
 119        return remote->url_nr;
 120}
 121
 122static NORETURN int die_push_simple(struct branch *branch, struct remote *remote) {
 123        /*
 124         * There's no point in using shorten_unambiguous_ref here,
 125         * as the ambiguity would be on the remote side, not what
 126         * we have locally. Plus, this is supposed to be the simple
 127         * mode. If the user is doing something crazy like setting
 128         * upstream to a non-branch, we should probably be showing
 129         * them the big ugly fully qualified ref.
 130         */
 131        const char *advice_maybe = "";
 132        const char *short_upstream = branch->merge[0]->src;
 133
 134        skip_prefix(short_upstream, "refs/heads/", &short_upstream);
 135
 136        /*
 137         * Don't show advice for people who explicitly set
 138         * push.default.
 139         */
 140        if (push_default == PUSH_DEFAULT_UNSPECIFIED)
 141                advice_maybe = _("\n"
 142                                 "To choose either option permanently, "
 143                                 "see push.default in 'git help config'.");
 144        die(_("The upstream branch of your current branch does not match\n"
 145              "the name of your current branch.  To push to the upstream branch\n"
 146              "on the remote, use\n"
 147              "\n"
 148              "    git push %s HEAD:%s\n"
 149              "\n"
 150              "To push to the branch of the same name on the remote, use\n"
 151              "\n"
 152              "    git push %s %s\n"
 153              "%s"),
 154            remote->name, short_upstream,
 155            remote->name, branch->name, advice_maybe);
 156}
 157
 158static const char message_detached_head_die[] =
 159        N_("You are not currently on a branch.\n"
 160           "To push the history leading to the current (detached HEAD)\n"
 161           "state now, use\n"
 162           "\n"
 163           "    git push %s HEAD:<name-of-remote-branch>\n");
 164
 165static void setup_push_upstream(struct remote *remote, struct branch *branch,
 166                                int triangular, int simple)
 167{
 168        struct strbuf refspec = STRBUF_INIT;
 169
 170        if (!branch)
 171                die(_(message_detached_head_die), remote->name);
 172        if (!branch->merge_nr || !branch->merge || !branch->remote_name)
 173                die(_("The current branch %s has no upstream branch.\n"
 174                    "To push the current branch and set the remote as upstream, use\n"
 175                    "\n"
 176                    "    git push --set-upstream %s %s\n"),
 177                    branch->name,
 178                    remote->name,
 179                    branch->name);
 180        if (branch->merge_nr != 1)
 181                die(_("The current branch %s has multiple upstream branches, "
 182                    "refusing to push."), branch->name);
 183        if (triangular)
 184                die(_("You are pushing to remote '%s', which is not the upstream of\n"
 185                      "your current branch '%s', without telling me what to push\n"
 186                      "to update which remote branch."),
 187                    remote->name, branch->name);
 188
 189        if (simple) {
 190                /* Additional safety */
 191                if (strcmp(branch->refname, branch->merge[0]->src))
 192                        die_push_simple(branch, remote);
 193        }
 194
 195        strbuf_addf(&refspec, "%s:%s", branch->name, branch->merge[0]->src);
 196        add_refspec(refspec.buf);
 197}
 198
 199static void setup_push_current(struct remote *remote, struct branch *branch)
 200{
 201        if (!branch)
 202                die(_(message_detached_head_die), remote->name);
 203        add_refspec(branch->name);
 204}
 205
 206static char warn_unspecified_push_default_msg[] =
 207N_("push.default is unset; its implicit value has changed in\n"
 208   "Git 2.0 from 'matching' to 'simple'. To squelch this message\n"
 209   "and maintain the traditional behavior, use:\n"
 210   "\n"
 211   "  git config --global push.default matching\n"
 212   "\n"
 213   "To squelch this message and adopt the new behavior now, use:\n"
 214   "\n"
 215   "  git config --global push.default simple\n"
 216   "\n"
 217   "When push.default is set to 'matching', git will push local branches\n"
 218   "to the remote branches that already exist with the same name.\n"
 219   "\n"
 220   "Since Git 2.0, Git defaults to the more conservative 'simple'\n"
 221   "behavior, which only pushes the current branch to the corresponding\n"
 222   "remote branch that 'git pull' uses to update the current branch.\n"
 223   "\n"
 224   "See 'git help config' and search for 'push.default' for further information.\n"
 225   "(the 'simple' mode was introduced in Git 1.7.11. Use the similar mode\n"
 226   "'current' instead of 'simple' if you sometimes use older versions of Git)");
 227
 228static void warn_unspecified_push_default_configuration(void)
 229{
 230        static int warn_once;
 231
 232        if (warn_once++)
 233                return;
 234        warning("%s\n", _(warn_unspecified_push_default_msg));
 235}
 236
 237static int is_workflow_triangular(struct remote *remote)
 238{
 239        struct remote *fetch_remote = remote_get(NULL);
 240        return (fetch_remote && fetch_remote != remote);
 241}
 242
 243static void setup_default_push_refspecs(struct remote *remote)
 244{
 245        struct branch *branch = branch_get(NULL);
 246        int triangular = is_workflow_triangular(remote);
 247
 248        switch (push_default) {
 249        default:
 250        case PUSH_DEFAULT_MATCHING:
 251                add_refspec(":");
 252                break;
 253
 254        case PUSH_DEFAULT_UNSPECIFIED:
 255                warn_unspecified_push_default_configuration();
 256                /* fallthru */
 257
 258        case PUSH_DEFAULT_SIMPLE:
 259                if (triangular)
 260                        setup_push_current(remote, branch);
 261                else
 262                        setup_push_upstream(remote, branch, triangular, 1);
 263                break;
 264
 265        case PUSH_DEFAULT_UPSTREAM:
 266                setup_push_upstream(remote, branch, triangular, 0);
 267                break;
 268
 269        case PUSH_DEFAULT_CURRENT:
 270                setup_push_current(remote, branch);
 271                break;
 272
 273        case PUSH_DEFAULT_NOTHING:
 274                die(_("You didn't specify any refspecs to push, and "
 275                    "push.default is \"nothing\"."));
 276                break;
 277        }
 278}
 279
 280static const char message_advice_pull_before_push[] =
 281        N_("Updates were rejected because the tip of your current branch is behind\n"
 282           "its remote counterpart. Integrate the remote changes (e.g.\n"
 283           "'git pull ...') before pushing again.\n"
 284           "See the 'Note about fast-forwards' in 'git push --help' for details.");
 285
 286static const char message_advice_checkout_pull_push[] =
 287        N_("Updates were rejected because a pushed branch tip is behind its remote\n"
 288           "counterpart. Check out this branch and integrate the remote changes\n"
 289           "(e.g. 'git pull ...') before pushing again.\n"
 290           "See the 'Note about fast-forwards' in 'git push --help' for details.");
 291
 292static const char message_advice_ref_fetch_first[] =
 293        N_("Updates were rejected because the remote contains work that you do\n"
 294           "not have locally. This is usually caused by another repository pushing\n"
 295           "to the same ref. You may want to first integrate the remote changes\n"
 296           "(e.g., 'git pull ...') before pushing again.\n"
 297           "See the 'Note about fast-forwards' in 'git push --help' for details.");
 298
 299static const char message_advice_ref_already_exists[] =
 300        N_("Updates were rejected because the tag already exists in the remote.");
 301
 302static const char message_advice_ref_needs_force[] =
 303        N_("You cannot update a remote ref that points at a non-commit object,\n"
 304           "or update a remote ref to make it point at a non-commit object,\n"
 305           "without using the '--force' option.\n");
 306
 307static void advise_pull_before_push(void)
 308{
 309        if (!advice_push_non_ff_current || !advice_push_update_rejected)
 310                return;
 311        advise(_(message_advice_pull_before_push));
 312}
 313
 314static void advise_checkout_pull_push(void)
 315{
 316        if (!advice_push_non_ff_matching || !advice_push_update_rejected)
 317                return;
 318        advise(_(message_advice_checkout_pull_push));
 319}
 320
 321static void advise_ref_already_exists(void)
 322{
 323        if (!advice_push_already_exists || !advice_push_update_rejected)
 324                return;
 325        advise(_(message_advice_ref_already_exists));
 326}
 327
 328static void advise_ref_fetch_first(void)
 329{
 330        if (!advice_push_fetch_first || !advice_push_update_rejected)
 331                return;
 332        advise(_(message_advice_ref_fetch_first));
 333}
 334
 335static void advise_ref_needs_force(void)
 336{
 337        if (!advice_push_needs_force || !advice_push_update_rejected)
 338                return;
 339        advise(_(message_advice_ref_needs_force));
 340}
 341
 342static int push_with_options(struct transport *transport, int flags)
 343{
 344        int err;
 345        unsigned int reject_reasons;
 346
 347        transport_set_verbosity(transport, verbosity, progress);
 348
 349        if (receivepack)
 350                transport_set_option(transport,
 351                                     TRANS_OPT_RECEIVEPACK, receivepack);
 352        transport_set_option(transport, TRANS_OPT_THIN, thin ? "yes" : NULL);
 353
 354        if (!is_empty_cas(&cas)) {
 355                if (!transport->smart_options)
 356                        die("underlying transport does not support --%s option",
 357                            CAS_OPT_NAME);
 358                transport->smart_options->cas = &cas;
 359        }
 360
 361        if (verbosity > 0)
 362                fprintf(stderr, _("Pushing to %s\n"), transport->url);
 363        err = transport_push(transport, refspec_nr, refspec, flags,
 364                             &reject_reasons);
 365        if (err != 0)
 366                error(_("failed to push some refs to '%s'"), transport->url);
 367
 368        err |= transport_disconnect(transport);
 369        if (!err)
 370                return 0;
 371
 372        if (reject_reasons & REJECT_NON_FF_HEAD) {
 373                advise_pull_before_push();
 374        } else if (reject_reasons & REJECT_NON_FF_OTHER) {
 375                advise_checkout_pull_push();
 376        } else if (reject_reasons & REJECT_ALREADY_EXISTS) {
 377                advise_ref_already_exists();
 378        } else if (reject_reasons & REJECT_FETCH_FIRST) {
 379                advise_ref_fetch_first();
 380        } else if (reject_reasons & REJECT_NEEDS_FORCE) {
 381                advise_ref_needs_force();
 382        }
 383
 384        return 1;
 385}
 386
 387static int do_push(const char *repo, int flags)
 388{
 389        int i, errs;
 390        struct remote *remote = pushremote_get(repo);
 391        const char **url;
 392        int url_nr;
 393
 394        if (!remote) {
 395                if (repo)
 396                        die(_("bad repository '%s'"), repo);
 397                die(_("No configured push destination.\n"
 398                    "Either specify the URL from the command-line or configure a remote repository using\n"
 399                    "\n"
 400                    "    git remote add <name> <url>\n"
 401                    "\n"
 402                    "and then push using the remote name\n"
 403                    "\n"
 404                    "    git push <name>\n"));
 405        }
 406
 407        if (remote->mirror)
 408                flags |= (TRANSPORT_PUSH_MIRROR|TRANSPORT_PUSH_FORCE);
 409
 410        if ((flags & TRANSPORT_PUSH_ALL) && refspec) {
 411                if (!strcmp(*refspec, "refs/tags/*"))
 412                        return error(_("--all and --tags are incompatible"));
 413                return error(_("--all can't be combined with refspecs"));
 414        }
 415
 416        if ((flags & TRANSPORT_PUSH_MIRROR) && refspec) {
 417                if (!strcmp(*refspec, "refs/tags/*"))
 418                        return error(_("--mirror and --tags are incompatible"));
 419                return error(_("--mirror can't be combined with refspecs"));
 420        }
 421
 422        if ((flags & (TRANSPORT_PUSH_ALL|TRANSPORT_PUSH_MIRROR)) ==
 423                                (TRANSPORT_PUSH_ALL|TRANSPORT_PUSH_MIRROR)) {
 424                return error(_("--all and --mirror are incompatible"));
 425        }
 426
 427        if (!refspec && !(flags & TRANSPORT_PUSH_ALL)) {
 428                if (remote->push_refspec_nr) {
 429                        refspec = remote->push_refspec;
 430                        refspec_nr = remote->push_refspec_nr;
 431                } else if (!(flags & TRANSPORT_PUSH_MIRROR))
 432                        setup_default_push_refspecs(remote);
 433        }
 434        errs = 0;
 435        url_nr = push_url_of_remote(remote, &url);
 436        if (url_nr) {
 437                for (i = 0; i < url_nr; i++) {
 438                        struct transport *transport =
 439                                transport_get(remote, url[i]);
 440                        if (push_with_options(transport, flags))
 441                                errs++;
 442                }
 443        } else {
 444                struct transport *transport =
 445                        transport_get(remote, NULL);
 446
 447                if (push_with_options(transport, flags))
 448                        errs++;
 449        }
 450        return !!errs;
 451}
 452
 453static int option_parse_recurse_submodules(const struct option *opt,
 454                                   const char *arg, int unset)
 455{
 456        int *recurse_submodules = opt->value;
 457
 458        if (*recurse_submodules != RECURSE_SUBMODULES_DEFAULT)
 459                die("%s can only be used once.", opt->long_name);
 460
 461        if (unset)
 462                *recurse_submodules = RECURSE_SUBMODULES_OFF;
 463        else if (arg)
 464                *recurse_submodules = parse_push_recurse_submodules_arg(opt->long_name, arg);
 465        else
 466                die("%s missing parameter", opt->long_name);
 467
 468        return 0;
 469}
 470
 471static void set_push_cert_flags(int *flags, int v)
 472{
 473        switch (v) {
 474        case SEND_PACK_PUSH_CERT_NEVER:
 475                *flags &= ~(TRANSPORT_PUSH_CERT_ALWAYS | TRANSPORT_PUSH_CERT_IF_ASKED);
 476                break;
 477        case SEND_PACK_PUSH_CERT_ALWAYS:
 478                *flags |= TRANSPORT_PUSH_CERT_ALWAYS;
 479                *flags &= ~TRANSPORT_PUSH_CERT_IF_ASKED;
 480                break;
 481        case SEND_PACK_PUSH_CERT_IF_ASKED:
 482                *flags |= TRANSPORT_PUSH_CERT_IF_ASKED;
 483                *flags &= ~TRANSPORT_PUSH_CERT_ALWAYS;
 484                break;
 485        }
 486}
 487
 488
 489static int git_push_config(const char *k, const char *v, void *cb)
 490{
 491        int *flags = cb;
 492        int status;
 493
 494        status = git_gpg_config(k, v, NULL);
 495        if (status)
 496                return status;
 497
 498        if (!strcmp(k, "push.followtags")) {
 499                if (git_config_bool(k, v))
 500                        *flags |= TRANSPORT_PUSH_FOLLOW_TAGS;
 501                else
 502                        *flags &= ~TRANSPORT_PUSH_FOLLOW_TAGS;
 503                return 0;
 504        } else if (!strcmp(k, "push.gpgsign")) {
 505                const char *value;
 506                if (!git_config_get_value("push.gpgsign", &value)) {
 507                        switch (git_config_maybe_bool("push.gpgsign", value)) {
 508                        case 0:
 509                                set_push_cert_flags(flags, SEND_PACK_PUSH_CERT_NEVER);
 510                                break;
 511                        case 1:
 512                                set_push_cert_flags(flags, SEND_PACK_PUSH_CERT_ALWAYS);
 513                                break;
 514                        default:
 515                                if (value && !strcasecmp(value, "if-asked"))
 516                                        set_push_cert_flags(flags, SEND_PACK_PUSH_CERT_IF_ASKED);
 517                                else
 518                                        return error("Invalid value for '%s'", k);
 519                        }
 520                }
 521        } else if (!strcmp(k, "push.recursesubmodules")) {
 522                const char *value;
 523                if (!git_config_get_value("push.recursesubmodules", &value))
 524                        recurse_submodules = parse_push_recurse_submodules_arg(k, value);
 525        }
 526
 527        return git_default_config(k, v, NULL);
 528}
 529
 530int cmd_push(int argc, const char **argv, const char *prefix)
 531{
 532        int flags = 0;
 533        int tags = 0;
 534        int push_cert = -1;
 535        int recurse_submodules_from_cmdline = RECURSE_SUBMODULES_DEFAULT;
 536        int rc;
 537        const char *repo = NULL;        /* default repository */
 538        struct option options[] = {
 539                OPT__VERBOSITY(&verbosity),
 540                OPT_STRING( 0 , "repo", &repo, N_("repository"), N_("repository")),
 541                OPT_BIT( 0 , "all", &flags, N_("push all refs"), TRANSPORT_PUSH_ALL),
 542                OPT_BIT( 0 , "mirror", &flags, N_("mirror all refs"),
 543                            (TRANSPORT_PUSH_MIRROR|TRANSPORT_PUSH_FORCE)),
 544                OPT_BOOL( 0, "delete", &deleterefs, N_("delete refs")),
 545                OPT_BOOL( 0 , "tags", &tags, N_("push tags (can't be used with --all or --mirror)")),
 546                OPT_BIT('n' , "dry-run", &flags, N_("dry run"), TRANSPORT_PUSH_DRY_RUN),
 547                OPT_BIT( 0,  "porcelain", &flags, N_("machine-readable output"), TRANSPORT_PUSH_PORCELAIN),
 548                OPT_BIT('f', "force", &flags, N_("force updates"), TRANSPORT_PUSH_FORCE),
 549                { OPTION_CALLBACK,
 550                  0, CAS_OPT_NAME, &cas, N_("refname>:<expect"),
 551                  N_("require old value of ref to be at this value"),
 552                  PARSE_OPT_OPTARG, parseopt_push_cas_option },
 553                { OPTION_CALLBACK, 0, "recurse-submodules", &recurse_submodules_from_cmdline, N_("check|on-demand|no"),
 554                        N_("control recursive pushing of submodules"),
 555                        PARSE_OPT_OPTARG, option_parse_recurse_submodules },
 556                OPT_BOOL( 0 , "thin", &thin, N_("use thin pack")),
 557                OPT_STRING( 0 , "receive-pack", &receivepack, "receive-pack", N_("receive pack program")),
 558                OPT_STRING( 0 , "exec", &receivepack, "receive-pack", N_("receive pack program")),
 559                OPT_BIT('u', "set-upstream", &flags, N_("set upstream for git pull/status"),
 560                        TRANSPORT_PUSH_SET_UPSTREAM),
 561                OPT_BOOL(0, "progress", &progress, N_("force progress reporting")),
 562                OPT_BIT(0, "prune", &flags, N_("prune locally removed refs"),
 563                        TRANSPORT_PUSH_PRUNE),
 564                OPT_BIT(0, "no-verify", &flags, N_("bypass pre-push hook"), TRANSPORT_PUSH_NO_HOOK),
 565                OPT_BIT(0, "follow-tags", &flags, N_("push missing but relevant tags"),
 566                        TRANSPORT_PUSH_FOLLOW_TAGS),
 567                { OPTION_CALLBACK,
 568                  0, "signed", &push_cert, "yes|no|if-asked", N_("GPG sign the push"),
 569                  PARSE_OPT_OPTARG, option_parse_push_signed },
 570                OPT_BIT(0, "atomic", &flags, N_("request atomic transaction on remote side"), TRANSPORT_PUSH_ATOMIC),
 571                OPT_END()
 572        };
 573
 574        packet_trace_identity("push");
 575        git_config(git_push_config, &flags);
 576        argc = parse_options(argc, argv, prefix, options, push_usage, 0);
 577        set_push_cert_flags(&flags, push_cert);
 578
 579        if (deleterefs && (tags || (flags & (TRANSPORT_PUSH_ALL | TRANSPORT_PUSH_MIRROR))))
 580                die(_("--delete is incompatible with --all, --mirror and --tags"));
 581        if (deleterefs && argc < 2)
 582                die(_("--delete doesn't make sense without any refs"));
 583
 584        if (recurse_submodules_from_cmdline != RECURSE_SUBMODULES_DEFAULT)
 585                recurse_submodules = recurse_submodules_from_cmdline;
 586
 587        if (recurse_submodules == RECURSE_SUBMODULES_CHECK)
 588                flags |= TRANSPORT_RECURSE_SUBMODULES_CHECK;
 589        else if (recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND)
 590                flags |= TRANSPORT_RECURSE_SUBMODULES_ON_DEMAND;
 591
 592        if (tags)
 593                add_refspec("refs/tags/*");
 594
 595        if (argc > 0) {
 596                repo = argv[0];
 597                set_refspecs(argv + 1, argc - 1, repo);
 598        }
 599
 600        rc = do_push(repo, flags);
 601        if (rc == -1)
 602                usage_with_options(push_usage, options);
 603        else
 604                return rc;
 605}