Beispiel #1
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 #2
0
def recordfilter(ui, headers, operation=None):

    if ui.interface("chunkselector") != "editor":
        return originalrecordfilter(ui, headers, operation)

    # construct diff string from headers
    if len(headers) == 0:
        return [], {}

    patch = stringio()
    patch.write(crecordmod.diffhelptext)

    specials = {}

    for header in headers:
        patch.write("#\n")
        if header.special():
            # this is useful for special changes, we are able to get away with
            # only including the parts of headers that offer useful info
            specials[header.filename()] = header
            for h in header.header:
                if h.startswith("index "):
                    # starting at 'index', the headers for binary files tend to
                    # stop offering useful info for the viewer
                    patch.write(
                        _("""\
# this modifies a binary file (all or nothing)
"""))
                    break
                if not h.startswith("diff "):
                    # For specials, we only care about the filename header.
                    # The rest can be displayed as comments
                    patch.write("# ")
                patch.write(h)
        else:
            header.write(patch)
            for hunk in header.hunks:
                hunk.write(patch)

    patcheditor = ui.config("ui", "editor.chunkselector")
    if patcheditor is not None:
        override = {("ui", "editor"): patcheditor}
    else:
        override = {}

    with ui.configoverride(override):
        patch = ui.edit(patch.getvalue(), "", action=(operation or "edit"))

    # remove comments from patch
    # if there's an empty line, add a space to it
    patch = [(line if len(line) > 0 else " ") + "\n"
             for line in patch.splitlines() if not line.startswith("#")]

    headers = patchmod.parsepatch(patch)

    applied = {}
    for h in headers:
        if h.filename() in specials:
            h = specials[h.filename()]
        applied[h.filename()] = [h] + h.hunks

    return (
        sum([i for i in applied.itervalues() if i[0].special() or len(i) > 1],
            []),
        {},
    )