Beispiel #1
0
def changedlines(ui, repo, ctx1, ctx2, fns):
    added, removed = 0, 0
    fmatch = scmutil.matchfiles(repo, fns)
    diff = "".join(patch.diff(repo, ctx1.node(), ctx2.node(), fmatch))
    for l in diff.split("\n"):
        if l.startswith("+") and not l.startswith("+++ "):
            added += 1
        elif l.startswith("-") and not l.startswith("--- "):
            removed += 1
    return (added, removed)
Beispiel #2
0
def diffstat(ui, repo, **kwargs):
    """Example usage:

    [hooks]
    commit.diffstat = python:/path/to/this/file.py:diffstat
    changegroup.diffstat = python:/path/to/this/file.py:diffstat
    """
    if kwargs.get("parent2"):
        return
    node = kwargs["node"]
    first = repo[node].p1().node()
    if "url" in kwargs:
        last = repo["tip"].node()
    else:
        last = node
    diff = patch.diff(repo, first, last)
    ui.write(patch.diffstat(util.iterlines(diff)))
Beispiel #3
0
def autodiff(ui, repo, *pats, **opts):
    diffopts = patch.difffeatureopts(ui, opts)
    git = opts.get("git", "no")
    brokenfiles = set()
    losedatafn = None
    if git in ("yes", "no"):
        diffopts.git = git == "yes"
        diffopts.upgrade = False
    elif git == "auto":
        diffopts.git = False
        diffopts.upgrade = True
    elif git == "warn":
        diffopts.git = False
        diffopts.upgrade = True

        def losedatafn(fn=None, **kwargs):
            brokenfiles.add(fn)
            return True

    elif git == "abort":
        diffopts.git = False
        diffopts.upgrade = True

        def losedatafn(fn=None, **kwargs):
            raise error.Abort("losing data for %s" % fn)

    else:
        raise error.Abort("--git must be yes, no or auto")

    node1, node2 = scmutil.revpair(repo, [])
    m = scmutil.match(repo[node2], pats, opts)
    it = patch.diff(repo,
                    repo[node1],
                    repo[node2],
                    match=m,
                    opts=diffopts,
                    losedatafn=losedatafn)
    for chunk in it:
        ui.writebytes(chunk)
    for fn in sorted(brokenfiles):
        ui.write(("data lost for: %s\n" % fn))
Beispiel #4
0
def absorb(ui, repo, stack=None, targetctx=None, pats=None, opts=None):
    """pick fixup chunks from targetctx, apply them to stack.

    if targetctx is None, the working copy context will be used.
    if stack is None, the current draft stack will be used.
    return fixupstate.
    """
    if stack is None:
        limit = ui.configint("absorb", "maxstacksize", 50)
        stack = getdraftstack(repo["."], limit)
        if limit and len(stack) >= limit:
            ui.warn(
                _("absorb: only the recent %d changesets will "
                  "be analysed\n") % limit)
    if not stack:
        raise error.Abort(_("no changeset to change"))
    if targetctx is None:  # default to working copy
        targetctx = repo[None]
    if pats is None:
        pats = ()
    if opts is None:
        opts = {}
    state = fixupstate(stack, ui=ui, opts=opts)
    matcher = scmutil.match(targetctx, pats, opts)
    if opts.get("interactive"):
        diff = patch.diff(repo, stack[-1], targetctx, matcher)
        origchunks = patch.parsepatch(diff)
        chunks = cmdutil.recordfilter(ui, origchunks)[0]
        targetctx = overlaydiffcontext(stack[-1], chunks)
    fm = None
    if not (ui.quiet
            and opts.get("apply_changes")) and not opts.get("edit_lines"):
        fm = ui.formatter("absorb", opts)
    state.diffwith(targetctx, matcher, fm)
    if fm is not None and state.ctxaffected:
        fm.startitem()
        count = len(state.ctxaffected)
        fm.write(
            "count",
            _n("\n%d changeset affected\n", "\n%d changesets affected\n",
               count),
            count,
        )
        fm.data(linetype="summary")
        for ctx in reversed(stack):
            if ctx not in state.ctxaffected:
                continue
            fm.startitem()
            fm.context(ctx=ctx)
            fm.data(linetype="changeset")
            fm.write("node", "%-7.7s ", ctx.hex(), label="absorb.node")
            descfirstline = ctx.description().splitlines()[0]
            fm.write("descfirstline",
                     "%s\n",
                     descfirstline,
                     label="absorb.description")
        fm.end()
    if not opts.get("edit_lines") and not any(
            f.fixups for f in state.fixupmap.values()):
        ui.write(_("nothing to absorb\n"))
    elif not opts.get("dry_run"):
        if not opts.get("apply_changes"):
            if ui.promptchoice("apply changes (yn)? $$ &Yes $$ &No",
                               default=0):
                raise error.Abort(_("absorb cancelled\n"))
        state.apply()
        state.commit()
        state.printchunkstats()
    return state
Beispiel #5
0
def debugfillinfinitepushmetadata(ui, repo, **opts):
    """Special command that fills infinitepush metadata for a node"""

    nodes = opts["node"]
    if not nodes:
        raise error.Abort(_("nodes are not specified"))

    filelimit = ui.configint("infinitepush", "metadatafilelimit", 100)
    nodesmetadata = {}
    for node in nodes:
        index = repo.bundlestore.index
        if not bool(index.getbundle(node)):
            raise error.Abort(_("node %s is not found") % node)

        if node not in repo:
            newbundlefile = server.downloadbundle(repo, bin(node))
            bundlepath = "bundle:%s+%s" % (repo.root, newbundlefile)
            bundlerepo = hg.repository(ui, bundlepath)
            repo = bundlerepo

        p1 = repo[node].p1().node()
        diffopts = patch.diffallopts(ui, {})
        match = scmutil.matchall(repo)
        chunks = patch.diff(repo, p1, node, match, None, diffopts, relroot="")
        difflines = util.iterlines(chunks)

        states = "modified added removed deleted unknown ignored clean".split()
        status = repo.status(p1, node)
        status = zip(states, status)

        filestatus = {}
        for state, files in status:
            for f in files:
                filestatus[f] = state

        diffstat = patch.diffstatdata(difflines)
        changed_files = {}
        copies = copiesmod.pathcopies(repo[p1], repo[node])
        for filename, adds, removes, isbinary in diffstat[:filelimit]:
            # use special encoding that allows non-utf8 filenames
            filename = pycompat.decodeutf8(
                encoding.jsonescape(pycompat.encodeutf8(filename), paranoid=True)
            )
            changed_files[filename] = {
                "adds": adds,
                "removes": removes,
                "isbinary": isbinary,
                "status": filestatus.get(filename, "unknown"),
            }
            if filename in copies:
                changed_files[filename]["copies"] = copies[filename]

        output = {}
        output["changed_files"] = changed_files
        if len(diffstat) > filelimit:
            output["changed_files_truncated"] = True
        nodesmetadata[node] = output

    with index:
        for node, metadata in pycompat.iteritems(nodesmetadata):
            dumped = json.dumps(metadata, sort_keys=True)
            index.saveoptionaljsonmetadata(node, pycompat.encodeutf8(dumped))