def expushcmd()

in eden/scm/edenscm/hgext/remotenames.py [0:0]


def expushcmd(orig, ui, repo, dest=None, **opts):
    if git.isgitpeer(repo):
        if dest is None:
            dest = "default"
        force = opts.get("force")
        delete = opts.get("delete")
        if delete:
            pushnode = None
            to = delete
        else:
            revspec = (["."] + opts.get("bookmark", []) + opts.get("rev", []))[-1]
            pushnode = scmutil.revsingle(repo, revspec).node()
            remotename = ui.config("remotenames", "rename.%s" % dest) or dest
            to = opts.get("to") or _guesspushtobookmark(repo, pushnode, remotename)
            if not to:
                raise error.Abort(_("use '--to' to specify destination bookmark"))
        return git.push(repo, dest, pushnode, to, force=force)

    # during the upgrade from old to new remotenames, tooling that uses --force
    # will continue working if remotenames.forcecompat is enabled
    forcecompat = ui.configbool("remotenames", "forcecompat")

    # needed for discovery method
    opargs = {
        "delete": opts.get("delete"),
        "to": opts.get("to"),
        "create": opts.get("create") or (opts.get("force") and forcecompat),
        "allowanon": opts.get("allow_anon")
        or repo.ui.configbool("remotenames", "pushanonheads")
        or (opts.get("force") and forcecompat),
        "nonforwardmove": opts.get("non_forward_move")
        or repo.ui.configbool("remotenames", "allownonfastforward")
        or (opts.get("force") and forcecompat),
    }

    if opargs["delete"]:
        flag = None
        for f in ("to", "bookmark", "branch", "rev"):
            if opts.get(f):
                flag = f
                break
        if flag:
            msg = _("do not specify --delete and " "--%s at the same time") % flag
            raise error.Abort(msg)
        # we want to skip pushing any changesets while deleting a remote
        # bookmark, so we send the null revision
        opts["rev"] = ["null"]
        return orig(ui, repo, dest, opargs=opargs, **opts)

    revs = opts.get("rev")

    paths = dict((path, url) for path, url in ui.configitems("paths"))
    # XXX T58629567: The following line triggers an infinite loop in pyre, let's disable it for now.
    if not typing.TYPE_CHECKING:
        revrenames = dict((v, k) for k, v in pycompat.iteritems(_getrenames(ui)))

    origdest = dest
    defaultpush = ui.paths.get("default-push") or ui.paths.get("default")
    if defaultpush:
        defaultpush = defaultpush.loc
    if (
        (not dest or dest == defaultpush)
        and not opargs["to"]
        and not revs
        and _tracking(ui)
    ):
        current = repo._activebookmark
        tracking = _readtracking(repo)
        ui.debug("tracking on %s %s\n" % (current, tracking))
        if current and current in tracking:
            track = tracking[current]
            path, book = splitremotename(track)
            # un-rename a path, if needed
            path = revrenames.get(path, path)
            if book and path in paths:
                dest = path
                opargs["to"] = book

    # un-rename passed path
    dest = revrenames.get(dest, dest)

    # if dest was renamed to default but we aren't specifically requesting
    # to push to default, change dest to default-push, if available
    if not origdest and dest == "default" and "default-push" in paths:
        dest = "default-push"

    # get the actual path we will push to so we can do some url sniffing
    for check in [
        # dest may be a path name, or an actual url
        paths.get(dest, dest),
        paths.get("default-push"),
        paths.get("default"),
    ]:
        if check:
            # hggit does funky things on push. Just call direct.
            if check.startswith("git+"):
                return orig(ui, repo, dest, opargs=opargs, **opts)
            # Once we have found the path where we are pushing, do not continue
            # checking for places we are not pushing.
            break

    if not opargs["to"]:
        if ui.configbool("remotenames", "forceto"):
            msg = _("must specify --to when pushing")
            hint = _("see configuration option %s") % "remotenames.forceto"
            raise error.Abort(msg, hint=hint)

        if not revs:
            opts["rev"] = _pushrevs(repo, ui, None)

        return orig(ui, repo, dest, opargs=opargs, **opts)

    if opts.get("bookmark"):
        msg = _("do not specify --to/-t and --bookmark/-B at the same time")
        raise error.Abort(msg)
    if opts.get("branch"):
        msg = _("do not specify --to/-t and --branch/-b at the same time")
        raise error.Abort(msg)

    # if we are not using the original push command implementation, make sure
    # pushvars is included in opargs
    pushvars = opts.get("pushvars")
    if pushvars:
        opargs["pushvars"] = pushvars

    if revs:
        revs = [repo.lookup(r) for r in repo.anyrevs(revs, user=True)]
    else:
        revs = _pushrevs(repo, ui, ".")
    if len(revs) != 1:
        msg = _("--to requires exactly one rev to push")
        hint = _("use --rev BOOKMARK or omit --rev for current commit (.)")
        raise error.Abort(msg, hint=hint)
    rev = revs[0]

    # big can o' copypasta from commands.push
    dest = ui.expandpath(dest or "default-push", dest or "default")
    dest, branches = hg.parseurl(dest, opts.get("branch"))
    try:
        other = hg.peer(repo, opts, dest)
    except error.RepoError:
        if dest == "default-push":
            hint = _('see the "path" section in "hg help config"')
            raise error.Abort(_("default repository not configured!"), hint=hint)
        else:
            raise

    # all checks pass, go for it!
    node = repo.lookup(rev)
    ui.status_err(
        _("pushing rev %s to destination %s bookmark %s\n")
        % (short(node), dest, opargs["to"])
    )

    force = opts.get("force")
    bookmark = opargs["to"]
    pattern = ui.config("remotenames", "disallowedto")
    if pattern and re.match(pattern, bookmark):
        msg = _("this remote bookmark name is not allowed")
        hint = ui.config("remotenames", "disallowedhint") or _(
            "use another bookmark name"
        )
        raise error.Abort(msg, hint=hint)

    # Force "rev % onto" drafts to be missing for pushrebase use-case.
    onto = ui.config("experimental", "server-rebase-onto")
    fullonto = "%s/%s" % (repo.ui.paths.getname(dest), onto)
    if onto and not opts.get("create") and fullonto in repo:
        opargs["forcedmissing"] = list(
            repo.nodes("draft() & only(%n, %s)", node, fullonto)
        )

    # NB: despite the name, 'revs' doesn't work if it's a numeric rev
    pushop = exchange.push(
        repo, other, force, revs=[node], bookmarks=(opargs["to"],), opargs=opargs
    )

    result = int(not pushop.cgresult)
    if pushop.bkresult is not None:
        if pushop.bkresult == 2:
            result = 2
        elif not result and pushop.bkresult:
            result = 2
    # Fixing up the exit code. If a bookmark is changed or created,
    # use exit code 0 (success) instead of 1 (success, no change).
    if result == 1 and (pushop.outbookmarks or pushop.create):
        result = 0

    return result