def cloudhide()

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


def cloudhide(ui, repo, *revs, **opts):
    """remove commits or bookmarks from the cloud workspace"""
    reponame = ccutil.getreponame(repo)
    workspacename = workspace.parseworkspace(ui, opts)
    if workspacename is None:
        workspacename = workspace.currentworkspace(repo)
    if workspacename is None:
        workspacename = workspace.defaultworkspace(ui)

    with progress.spinner(ui, _("fetching commit cloud workspace")):
        serv = service.get(ui, tokenmod.TokenLocator(ui).token)
        slinfo = serv.getsmartlog(reponame, workspacename, repo, 0)
        firstpublic, revdag = serv.makedagwalker(slinfo, repo)
        cloudrefs = serv.getreferences(reponame, workspacename, 0)

    nodeinfos = slinfo.nodeinfos
    dag = slinfo.dag
    drafts = set(slinfo.draft)
    hexdrafts = set(nodemod.hex(d) for d in slinfo.draft)

    removenodes = set()

    for rev in list(revs) + opts.get("rev", []):
        if rev in hexdrafts:
            removenodes.add(nodemod.bin(rev))
        else:
            candidate = None
            for hexdraft in hexdrafts:
                if hexdraft.startswith(rev):
                    if candidate is None:
                        candidate = hexdraft
                    else:
                        raise error.Abort(_("ambiguous commit hash prefix: %s") % rev)
            if candidate is None:
                raise error.Abort(_("commit not in workspace: %s") % rev)
            removenodes.add(nodemod.bin(candidate))

    # Find the bookmarks we need to remove
    removebookmarks = set()
    for bookmark in opts.get("bookmark", []):
        kind, pattern, matcher = util.stringmatcher(bookmark)
        if kind == "literal":
            if pattern not in cloudrefs.bookmarks:
                raise error.Abort(_("bookmark not in workspace: %s") % pattern)
            removebookmarks.add(pattern)
        else:
            for bookmark in cloudrefs.bookmarks:
                if matcher(bookmark):
                    removebookmarks.add(bookmark)

    # Find the remote bookmarks we need to remove
    removeremotes = set()
    for remote in opts.get("remotebookmark", []):
        kind, pattern, matcher = util.stringmatcher(remote)
        if kind == "literal":
            if pattern not in cloudrefs.remotebookmarks:
                raise error.Abort(_("remote bookmark not in workspace: %s") % pattern)
            removeremotes.add(remote)
        else:
            for remote in cloudrefs.remotebookmarks:
                if matcher(remote):
                    removeremotes.add(remote)

    # Find the heads and bookmarks we need to remove
    allremovenodes = dag.descendants(removenodes)
    removeheads = set(allremovenodes & map(nodemod.bin, cloudrefs.heads))
    for node in allremovenodes:
        removebookmarks.update(nodeinfos[node].bookmarks)

    # Find the heads we need to remove because we are removing the last bookmark
    # to it.
    remainingheads = set(
        set(map(nodemod.bin, cloudrefs.heads)) & dag.all() - removeheads
    )
    for bookmark in removebookmarks:
        node = nodemod.bin(cloudrefs.bookmarks[bookmark])
        info = nodeinfos.get(node)
        if node in remainingheads and info:
            if removebookmarks.issuperset(set(info.bookmarks)):
                remainingheads.discard(node)
                removeheads.add(node)

    # Find the heads we need to add to keep other commits visible
    addheads = (
        dag.parents(removenodes) - allremovenodes - dag.ancestors(remainingheads)
    ) & drafts

    if removeheads:
        ui.status(_("removing heads:\n"))
        for head in sorted(removeheads):
            hexhead = nodemod.hex(head)
            ui.status(
                "    %s  %s\n"
                % (hexhead[:12], templatefilters.firstline(nodeinfos[head].message))
            )
    if addheads:
        ui.status(_("adding heads:\n"))
        for head in sorted(addheads):
            hexhead = nodemod.hex(head)
            ui.status(
                "    %s  %s\n"
                % (hexhead[:12], templatefilters.firstline(nodeinfos[head].message))
            )
    if removebookmarks:
        ui.status(_("removing bookmarks:\n"))
        for bookmark in sorted(removebookmarks):
            ui.status("    %s: %s\n" % (bookmark, cloudrefs.bookmarks[bookmark][:12]))
    if removeremotes:
        ui.status(_("removing remote bookmarks:\n"))
        for remote in sorted(removeremotes):
            ui.status("    %s: %s\n" % (remote, cloudrefs.remotebookmarks[remote][:12]))

    # Hexify all the head, as cloudrefs works with hex strings.
    removeheads = list(map(nodemod.hex, removeheads))
    addheads = list(map(nodemod.hex, addheads))

    if removeheads or addheads or removebookmarks or removeremotes:
        if opts.get("dry_run"):
            ui.status(_("not updating cloud workspace: --dry-run specified\n"))
            return 0
        with progress.spinner(ui, _("updating commit cloud workspace")):
            serv.updatereferences(
                reponame,
                workspacename,
                cloudrefs.version,
                oldheads=list(removeheads),
                newheads=list(addheads),
                oldbookmarks=list(removebookmarks),
                oldremotebookmarks=list(removeremotes),
            )
    else:
        ui.status(_("nothing to change\n"))