Esempio n. 1
0
def getrevs(ui, repo, masterstring, **opts):
    global hiddenchanges
    hiddenchanges = 0

    global commit_info
    commit_info = opts.get("commit_info")

    headrevs = opts.get("rev")
    if headrevs:
        headspec = revsetlang.formatspec("%lr", headrevs)
    else:
        if opts.get("all"):
            datefilter = "_all()"
        else:
            before = ui.config("smartlog", "hide-before")
            if before:
                datefilter = revsetlang.formatspec("date(%s)", ">%s" % before)
            else:
                # last 2 weeks
                datefilter = "date(-14)"
            # Calculate hiddenchanges
            allheads = repo.revs("heads(draft()) - . - interestingbookmarks()")
            visibleheads = repo.revs("%ld & %r", allheads, datefilter)
            hiddenchanges = len(allheads) - len(visibleheads)

        headspec = revsetlang.formatspec(
            "interestingbookmarks() + (heads(draft()) & %r) + .", datefilter
        )

    revstring = revsetlang.formatspec(
        "smartlog(heads=%r, master=%r)", headspec, masterstring
    )

    return set(repo.anyrevs([revstring], user=True))
Esempio n. 2
0
def getrevs(ui, repo, masterstring, **opts):
    global commit_info
    commit_info = opts.get("commit_info")

    headrevs = opts.get("rev")
    if headrevs:
        headspec = revsetlang.formatspec("%lr", headrevs)
    else:
        headspec = "interestingbookmarks() + heads(draft()) + ."

    revstring = revsetlang.formatspec("smartlog(heads=%r, master=%r)",
                                      headspec, masterstring)

    return set(repo.anyrevs([revstring], user=True))
Esempio n. 3
0
def _cachedgetoldworkingcopyparent(repo, wkpnode):
    if not util.safehasattr(repo, "_undooldworkingparentcache"):
        repo._undooldworkingparentcache = {}
    cache = repo._undooldworkingparentcache
    key = wkpnode
    if key not in cache:
        oldworkingparent = _readnode(repo, "workingparent.i", wkpnode)
        oldworkingparent = filter(None, oldworkingparent.split("\n"))
        oldwkprevstring = revsetlang.formatspec("%ls", oldworkingparent)
        urepo = repo.unfiltered()
        cache[key] = smartset.baseset(urepo.revs(oldwkprevstring))
    return cache[key]
Esempio n. 4
0
def _localbranch(repo, subset, x):
    """``_localbranch(changectx)``
    localbranch changesets

    Returns all commits within the same localbranch as the changeset(s). A local
    branch is all draft changesets that are connected, uninterupted by public
    changesets.  Any draft commit within a branch, or a public commit at the
    base of the branch, can be used to identify localbranches.
    """
    # executed on an filtered repo
    args = revset.getargsdict(x, "branchrevset", "changectx")
    revstring = revsetlang.getstring(
        args.get("changectx"), _("localbranch argument must be a changectx"))
    revs = repo.revs(revstring)
    # we assume that there is only a single rev
    if repo[revs.first()].phase() == phases.public:
        querystring = revsetlang.formatspec("(children(%d) & draft())::",
                                            revs.first())
    else:
        querystring = revsetlang.formatspec("((::%ld) & draft())::", revs)
    return subset & smartset.baseset(repo.revs(querystring))
Esempio n. 5
0
def debugbruterebase(ui, repo, source, dest):
    """for every non-empty subset of source, run rebase -r subset -d dest

    Print one line summary for each subset. Assume obsstore is enabled.
    """
    srevs = list(repo.revs(source))

    with repo.wlock(), repo.lock():
        repolen = len(repo)
        cl = repo.changelog
        newrevs = []

        def getdesc(rev):
            result = cl.changelogrevision(rev).description
            if rev in newrevs:
                result += "'"
            return result

        for i in xrange(1, 2**len(srevs)):
            subset = [rev for j, rev in enumerate(srevs) if i & (1 << j) != 0]
            spec = revsetlang.formatspec("%ld", subset)
            tr = repo.transaction("rebase")
            tr.report = lambda x: 0  # hide "transaction abort"

            oldnodes = set(repo.nodes("all()"))
            ui.pushbuffer()
            try:
                rebase.rebase(ui, repo, dest=dest, rev=[spec])
            except error.Abort as ex:
                summary = "ABORT: %s" % ex
            except Exception as ex:
                summary = "CRASH: %s" % ex
            else:
                # short summary about new nodes
                cl = repo.changelog
                descs = []
                newnodes = set(repo.nodes("all()"))
                newrevs = list(map(cl.rev, newnodes - oldnodes))
                for rev in sorted(newrevs):
                    desc = "%s:" % getdesc(rev)
                    for prev in cl.parentrevs(rev):
                        if prev > -1:
                            desc += getdesc(prev)
                    descs.append(desc)
                descs.sort()
                summary = " ".join(descs)
            ui.popbuffer()
            repo.localvfs.tryunlink("rebasestate")

            subsetdesc = "".join(getdesc(rev) for rev in subset)
            ui.write(("%s: %s\n") % (subsetdesc.rjust(len(srevs)), summary))
            tr.abort()
Esempio n. 6
0
def oldworkingparenttemplate(context, mapping, args):
    """String. Workingcopyparent reverseindex repo states ago."""
    reverseindex = templater.evalinteger(
        context, mapping, args[0],
        _("undonecommits needs an integer argument"))
    repo = mapping["ctx"]._repo
    ctx = mapping["ctx"]
    revstring = revsetlang.formatspec("oldworkingcopyparent(%d)", reverseindex)
    nodes = list(repo.nodes(revstring))
    if ctx.node() in nodes:
        result = ctx.hex()
    else:
        result = None
    return result
Esempio n. 7
0
def _cachedgetolddrafts(repo, nodedict):
    if not util.safehasattr(repo, "_undoolddraftcache"):
        repo._undoolddraftcache = {}
    cache = repo._undoolddraftcache
    if repo.ui.configbool("experimental", "narrow-heads"):
        headnode = key = nodedict["visibleheads"]
        if key not in cache:
            oldheads = _readnode(repo, "visibleheads.i", headnode).split("\n")
            cache[key] = repo.revs("(not public()) & ::%ls", oldheads)
    else:
        draftnode = nodedict["draftheads"]
        obsnode = nodedict["draftobsolete"]
        key = draftnode + obsnode
        if key not in cache:
            olddraftheads = _readnode(repo, "draftheads.i", draftnode)
            oldheadslist = olddraftheads.split("\n")
            oldobs = _readnode(repo, "draftobsolete.i", obsnode)
            oldobslist = filter(None, oldobs.split("\n"))
            oldlogrevstring = revsetlang.formatspec(
                "(draft() & ancestors(%ls)) - %ls", oldheadslist, oldobslist)
            urepo = repo.unfiltered()
            cache[key] = smartset.baseset(urepo.revs(oldlogrevstring))
    return cache[key]
Esempio n. 8
0
def _donehexnodes(repo, reverseindex):
    repo = repo.unfiltered()
    revstring = revsetlang.formatspec("olddraft(%d)", reverseindex)
    revs = repo.revs(revstring)
    tonode = repo.changelog.node
    return [tonode(x) for x in revs]
Esempio n. 9
0
def _logdraftobsolete(repo, tr):
    spec = revsetlang.formatspec("draft() & obsolete()")
    hexnodes = tohexnode(repo, spec)
    revstring = "\n".join(sorted(hexnodes))
    return writelog(repo, tr, "draftobsolete.i", revstring)
Esempio n. 10
0
def _preview(ui, repo, reverseindex):
    # Print smartlog like preview of undo
    # Input:
    #   ui:
    #   repo: mercurial.localrepo
    # Output:
    #   returns 1 on index error, 0 otherwise

    # override "UNDOINDEX" as a variable usable in template
    if not _gapcheck(ui, repo, reverseindex):
        repo.ui.status(
            _("WARN: missing history between present and this"
              " state\n"))
    overrides = {("templates", "UNDOINDEX"): str(reverseindex)}

    opts = {}
    opts["template"] = "{undopreview}"
    repo = repo.unfiltered()

    try:
        nodedict = _readindex(repo, reverseindex)
        curdict = _readindex(repo, reverseindex)
    except IndexError:
        return 1

    bookstring = _readnode(repo, "bookmarks.i", nodedict["bookmarks"])
    oldmarks = bookstring.split("\n")
    oldpairs = set()
    for mark in oldmarks:
        kv = mark.rsplit(" ", 1)
        if len(kv) == 2:
            oldpairs.update(kv)
    bookstring = _readnode(repo, "bookmarks.i", curdict["bookmarks"])
    curmarks = bookstring.split("\n")
    curpairs = set()
    for mark in curmarks:
        kv = mark.rsplit(" ", 1)
        if len(kv) == 2:
            curpairs.update(kv)

    diffpairs = oldpairs.symmetric_difference(curpairs)
    # extract hashes from diffpairs

    bookdiffs = []
    for kv in diffpairs:
        bookdiffs += kv[0]

    revstring = revsetlang.formatspec(
        "ancestor(olddraft(0), olddraft(%s)) +"
        "(draft() & ::((olddraft(0) - olddraft(%s)) + "
        "(olddraft(%s) - olddraft(0)) + %ls + '.' + "
        "oldworkingcopyparent(%s)))",
        reverseindex,
        reverseindex,
        reverseindex,
        bookdiffs,
        reverseindex,
    )

    opts["rev"] = [revstring]
    try:
        with ui.configoverride(overrides):
            cmdutil.graphlog(ui, repo, None, opts)
        # informative output
        nodedict = _readindex(repo, reverseindex)
        time = _readnode(repo, "date.i", nodedict["date"])
        time = util.datestr([float(x) for x in time.split(" ")])
    except IndexError:
        # don't print anything
        return 1

    try:
        nodedict = _readindex(repo, reverseindex - 1)
        commandstr = _readnode(repo, "command.i", nodedict["command"])
        commandlist = commandstr.split("\0")[1:]
        commandstr = " ".join(commandlist)
        uimessage = _("undo to %s, before %s\n") % (time, commandstr)
        repo.ui.status((uimessage))
    except IndexError:
        repo.ui.status(
            _("most recent state: undoing here won't change"
              " anything\n"))
    return 0
Esempio n. 11
0
def _findnextdelta(repo, reverseindex, branch, direction):
    # finds closest repos state making changes to branch in direction
    # input:
    #   repo: mercurial.localrepo
    #   reverseindex: positive int for index.i
    #   branch: string changectx (commit hash)
    #   direction: positive or negative int
    # output:
    #   int index with next branch delta
    #   this is the first repo state that makes a changectx, bookmark or working
    #   copy parent change that effects the given branch
    if 0 == direction:  # no infinite cycles guarantee
        raise error.ProgrammingError
    repo = repo.unfiltered()
    # current state
    try:
        nodedict = _readindex(repo, reverseindex)
    except IndexError:
        raise error.Abort(_("index out of bounds"))
    alphaworkingcopyparent = _readnode(repo, "workingparent.i",
                                       nodedict["workingparent"])
    alphabookstring = _readnode(repo, "bookmarks.i", nodedict["bookmarks"])
    incrementalindex = reverseindex

    spec = revsetlang.formatspec("_localbranch(%s)", branch)
    hexnodes = tohexnode(repo, spec)

    done = False
    while not done:
        # move index
        incrementalindex += direction
        # check this index
        try:
            nodedict = _readindex(repo, incrementalindex)
        except IndexError:
            raise error.Abort(_("index out of bounds"))
        # skip interupted commands
        if "True" == nodedict["unfinished"]:
            break
        # check wkp, commits, bookmarks
        workingcopyparent = _readnode(repo, "workingparent.i",
                                      nodedict["workingparent"])
        bookstring = _readnode(repo, "bookmarks.i", nodedict["bookmarks"])
        # local changes in respect to visible changectxs
        # disjunctive union of present and old = changes
        # intersection of changes and local = localchanges
        localctxchanges = revsetlang.formatspec(
            "((olddraft(%d) + olddraft(%d)) -"
            "(olddraft(%d) and olddraft(%d)))"
            " and _localbranch(%s)",
            incrementalindex,
            reverseindex,
            incrementalindex,
            reverseindex,
            branch,
        )
        done = done or repo.revs(localctxchanges)
        if done:  # perf boost
            break
        # bookmark changes
        if alphabookstring != bookstring:
            diff = set(alphabookstring.split("\n")) ^ set(
                bookstring.split("\n"))
            for mark in diff:
                if mark:
                    kv = mark.rsplit(" ", 1)
                    # was or will the mark be in the localbranch
                    if kv[1] in hexnodes:
                        done = True
                        break

        # working copy parent changes
        # for workingcopyparent, only changes within the scope are interesting
        if alphaworkingcopyparent != workingcopyparent:
            done = done or (workingcopyparent in hexnodes
                            and alphaworkingcopyparent in hexnodes)

    return incrementalindex
Esempio n. 12
0
def _computerelative(repo, reverseindex, absolute=False, branch=""):
    # allows for relative undos using
    # redonode storage
    # allows for branch undos using
    # findnextdelta logic
    if reverseindex != 0:
        sign = reverseindex / abs(reverseindex)
    else:
        sign = None
    if not absolute:
        try:  # attempt to get relative shift
            nodebranch = repo.localvfs.read("undolog/redonode").split("\0")
            hexnode = nodebranch[0]
            try:
                oldbranch = nodebranch[1]
            except IndexError:
                oldbranch = ""
            rlog = _getrevlog(repo, "index.i")
            rev = rlog.rev(bin(hexnode))
            shiftedindex = _invertindex(rlog, rev)
        except (IOError, error.RevlogError):
            # no shift
            shiftedindex = 0
            oldbranch = ""
    else:
        shiftedindex = 0
        oldbranch = ""

    if not branch:
        if not oldbranch:
            reverseindex = shiftedindex + reverseindex
        # else: previous command was branch undo
        # perform absolute undo (no shift)
    else:
        # check if relative branch
        if (branch != oldbranch) and (oldbranch != ""):
            rootdelta = revsetlang.formatspec(
                "roots(_localbranch(%s)) - roots(_localbranch(%s))", branch,
                oldbranch)
            if repo.revs(rootdelta):
                # different group of commits
                shiftedindex = 0

        # from shifted index, find reverse index # of states that change
        # branch
        # remember that reverseindex can be negative
        sign = reverseindex / abs(reverseindex)
        for count in range(abs(reverseindex)):
            shiftedindex = _findnextdelta(repo,
                                          shiftedindex,
                                          branch,
                                          direction=sign)
        reverseindex = shiftedindex
    # skip interupted commands
    if sign:
        done = False
        rlog = _getrevlog(repo, "index.i")
        while not done:
            indexdict = _readindex(repo, reverseindex, rlog)
            if "True" == indexdict["unfinished"]:
                reverseindex += sign
            else:
                done = True
    return reverseindex
Esempio n. 13
0
def _undoto(ui, repo, reverseindex, keep=False, branch=None):
    # undo to specific reverseindex
    # branch is a changectx hash (potentially short form)
    # which identifies its branch via localbranch revset

    if branch and repo.ui.configbool("experimental", "narrow-heads"):
        raise error.Abort(
            _("'undo --branch' is no longer supported in the current setup"))

    if repo != repo.unfiltered():
        raise error.ProgrammingError(_("_undoto expects unfilterd repo"))
    try:
        nodedict = _readindex(repo, reverseindex)
    except IndexError:
        raise error.Abort(_("index out of bounds"))

    # bookmarks
    bookstring = _readnode(repo, "bookmarks.i", nodedict["bookmarks"])
    booklist = bookstring.split("\n")
    if branch:
        spec = revsetlang.formatspec("_localbranch(%s)", branch)
        branchcommits = tohexnode(repo, spec)
    else:
        branchcommits = False

    # copy implementation for bookmarks
    itercopy = []
    for mark in pycompat.iteritems(repo._bookmarks):
        itercopy.append(mark)
    bmremove = []
    for mark in itercopy:
        if not branchcommits or hex(mark[1]) in branchcommits:
            bmremove.append((mark[0], None))
    repo._bookmarks.applychanges(repo, repo.currenttransaction(), bmremove)
    bmchanges = []
    for mark in booklist:
        if mark:
            kv = mark.rsplit(" ", 1)
            if not branchcommits or kv[1] in branchcommits or (
                    kv[0], None) in bmremove:
                bmchanges.append((kv[0], bin(kv[1])))
    repo._bookmarks.applychanges(repo, repo.currenttransaction(), bmchanges)

    # working copy parent
    workingcopyparent = _readnode(repo, "workingparent.i",
                                  nodedict["workingparent"])
    if not keep:
        if not branchcommits or workingcopyparent in branchcommits:
            # bailifchanged is run, so this should be safe
            hg.clean(repo, workingcopyparent, show_stats=False)
    elif not branchcommits or workingcopyparent in branchcommits:
        # keeps working copy files
        prednode = bin(workingcopyparent)
        predctx = repo[prednode]

        changedfiles = []
        wctx = repo[None]
        wctxmanifest = wctx.manifest()
        predctxmanifest = predctx.manifest()
        dirstate = repo.dirstate
        diff = predctxmanifest.diff(wctxmanifest)
        changedfiles.extend(pycompat.iterkeys(diff))

        with dirstate.parentchange():
            dirstate.rebuild(prednode, predctxmanifest, changedfiles)
            # we want added and removed files to be shown
            # properly, not with ? and ! prefixes
            for filename, data in pycompat.iteritems(diff):
                if data[0][0] is None:
                    dirstate.add(filename)
                if data[1][0] is None:
                    dirstate.remove(filename)

    # visible changesets
    addedrevs = revsetlang.formatspec("olddraft(0) - olddraft(%d)",
                                      reverseindex)
    removedrevs = revsetlang.formatspec("olddraft(%d) - olddraft(0)",
                                        reverseindex)
    if not branch:
        if repo.ui.configbool("experimental", "narrow-heads"):
            # Assuming mutation and visibility are used. Restore visibility heads
            # directly.
            _restoreheads(repo, reverseindex)
        else:
            # Legacy path.
            smarthide(repo, addedrevs, removedrevs)
            revealcommits(repo, removedrevs)
    else:
        localadds = revsetlang.formatspec(
            "(olddraft(0) - olddraft(%d)) and"
            " _localbranch(%s)", reverseindex, branch)
        localremoves = revsetlang.formatspec(
            "(olddraft(%d) - olddraft(0)) and"
            " _localbranch(%s)", reverseindex, branch)
        smarthide(repo, localadds, removedrevs)
        smarthide(repo, addedrevs, localremoves, local=True)
        revealcommits(repo, localremoves)

    # informative output
    time = _readnode(repo, "date.i", nodedict["date"])
    time = util.datestr([float(x) for x in time.split(" ")])

    nodedict = _readindex(repo, reverseindex - 1)
    commandstr = _readnode(repo, "command.i", nodedict["command"])
    commandlist = commandstr.split("\0")[1:]
    commandstr = " ".join(commandlist)
    uimessage = _("undone to %s, before %s\n") % (time, commandstr)
    if reverseindex == 1 and commandlist[0] in ("commit", "amend"):
        command = commandlist[0]
        if command == "commit" and "--amend" in commandlist:
            command = "amend"
        oldcommithash = _readnode(repo, "workingparent.i",
                                  nodedict["workingparent"])
        shorthash = short(bin(oldcommithash))
        hintutil.trigger("undo-uncommit-unamend", command, shorthash)
    repo.ui.status((uimessage))
Esempio n. 14
0
File: undo.py Progetto: x414e54/eden
def _donehexnodes(repo, reverseindex):
    repo = repo.unfiltered()
    revstring = revsetlang.formatspec("olddraft(%d)", reverseindex)
    return list(repo.nodes(revstring))
Esempio n. 15
0
File: undo.py Progetto: x414e54/eden
def _undonehexnodes(repo, reverseindex):
    revstring = revsetlang.formatspec("olddraft(0) - olddraft(%d)",
                                      reverseindex)
    return list(repo.nodes(revstring))
Esempio n. 16
0
def _smartlogrevset(orig, repo, subset, x):
    revs = orig(repo, subset, x)
    snapshotstring = revsetlang.formatspec("snapshot()")
    return smartset.addset(
        revs,
        repo.unfiltered().anyrevs([snapshotstring], user=True))
Esempio n. 17
0
def _getscratchbranchpartsimpl(
    repo, peer, outgoing, confignonforwardmove, ui, bookmark, create, bookmarknode=None
):
    _validaterevset(repo, revsetlang.formatspec("%ln", outgoing.missing), bookmark)

    supportedversions = changegroup.supportedoutgoingversions(repo)
    # Explicitly avoid using '01' changegroup version in infinitepush to
    # support general delta
    supportedversions.discard("01")
    cgversion = min(supportedversions)
    _handlelfs(repo, outgoing.missing)
    cg = changegroup.makestream(repo, outgoing, cgversion, "push")

    params = {}
    params["cgversion"] = cgversion
    if bookmark:
        params["bookmark"] = bookmark
        if bookmarknode:
            params["bookmarknode"] = bookmarknode
        if create:
            params["create"] = "1"
    if confignonforwardmove:
        params["force"] = "1"

    parts = []

    # .upper() marks this as a mandatory part: server will abort if there's no
    #  handler
    parts.append(
        bundle2.bundlepart(
            constants.scratchbranchparttype.upper(),
            advisoryparams=pycompat.iteritems(params),
            data=cg,
        )
    )

    if mutation.enabled(repo):
        entries = mutation.entriesforbundle(repo, outgoing.missing)
        if entries:
            if constants.scratchmutationparttype not in bundle2.bundle2caps(peer):
                repo.ui.warn(
                    _("no server support for %r - skipping\n")
                    % constants.scratchmutationparttype
                )
            else:
                parts.append(
                    bundle2.bundlepart(
                        constants.scratchmutationparttype,
                        data=mutation.bundleentries(entries),
                    )
                )

    try:
        treemod = extensions.find("treemanifest")
        remotefilelog = extensions.find("remotefilelog")
        sendtrees = remotefilelog.shallowbundle.cansendtrees(repo, outgoing.missing)
        if sendtrees != remotefilelog.shallowbundle.NoTrees:
            parts.append(
                treemod.createtreepackpart(
                    repo, outgoing, treemod.TREEGROUP_PARTTYPE2, sendtrees=sendtrees
                )
            )
    except KeyError:
        pass

    try:
        snapshot = extensions.find("snapshot")
    except KeyError:
        pass
    else:
        snapshot.bundleparts.appendsnapshotmetadatabundlepart(
            repo, outgoing.missing, parts
        )

    return parts
Esempio n. 18
0
def _logdraftheads(repo, tr):
    spec = revsetlang.formatspec("heads(draft())")
    hexnodes = tohexnode(repo, spec)
    revstring = "\n".join(sorted(hexnodes))
    return writelog(repo, tr, "draftheads.i", revstring)