Esempio n. 1
0
def inmemorymerge(ui, repo, src, dest, base):
    """Return memctx representing three way merge of src, dest, and base

    src is "remote" and dest is "local".
    """
    mergeresult = nativecheckout.mergeresult(src.manifest(), dest.manifest(),
                                             base.manifest())

    manifestbuilder = mergeresult.manifestbuilder()
    if manifestbuilder is None:
        raise error.Abort(
            _("amend would conflict in %s") %
            ", ".join(mergeresult.conflict_paths()))

    try:
        resolved = rebasemod._simplemerge(ui, base, src, dest, manifestbuilder)
    except error.InMemoryMergeConflictsError as ex:
        raise error.Abort(
            _("amend would conflict in %s") % ", ".join(ex.paths))

    mergedctx = mirrorwithmetadata(src, "rebase")

    for path in manifestbuilder.removed():
        mergedctx[path] = None

    for path, merged in resolved.items():
        mergedctx[path] = context.overlayfilectx(
            src[path],
            datafunc=lambda data=merged: data,
            ctx=mergedctx,
        )

    return mergedctx
Esempio n. 2
0
def overlaycontext(
    memworkingcopy, ctx, parents=None, extra=None, loginfo=None, mutinfo=None
):
    """({path: content}, ctx, (p1node, p2node)?, {}?) -> memctx
    memworkingcopy overrides file contents.
    """
    mctx = context.memctx.mirror(
        ctx, parentnodes=parents, extra=extra, loginfo=loginfo, mutinfo=mutinfo
    )
    for path, data in memworkingcopy.items():
        fctx = context.overlayfilectx(ctx[path], datafunc=lambda data=data: data)
        mctx[path] = fctx
    return mctx
Esempio n. 3
0
def dirsyncctx(ctx, matcher=None):
    """for changes in ctx that matches matcher, apply dirsync rules

    Return:

        (newctx, {path})

    This function does not change working copy or dirstate.
    """
    maps = getconfigs(ctx)
    resultmirrored = set()
    resultctx = ctx

    # Do not dirsync if there is nothing to sync.
    # Do not dirsync metaedit commits, because they might break assertions in
    # metadataonlyctx (manifest is unchanged).
    if not maps or (ctx.mutinfo() or {}).get("mutop") == "metaedit":
        return resultctx, resultmirrored

    needsync = configstomatcher(maps)
    repo = ctx.repo()
    mctx, status = _mctxstatus(ctx)

    added = set(status.added)
    modified = set(status.modified)
    removed = set(status.removed)

    if matcher is None:
        matcher = lambda path: True

    for action, paths in (
        ("a", status.added),
        ("m", status.modified),
        ("r", status.removed),
    ):
        for src in paths:
            if not needsync.matches(src) or not matcher(src):
                continue
            srcmirror, mirrors = getmirrors(maps, src)
            if not mirrors:
                continue

            dstpaths = []  # [(dstpath, dstmirror)]
            for dstmirror in (m for m in mirrors if m != srcmirror):
                dst = _mirrorpath(srcmirror, dstmirror, src)
                dstpaths.append((dst, dstmirror))

            if action == "r":
                fsrc = None
            else:
                fsrc = ctx[src]
            for dst, dstmirror in dstpaths:
                # changed: whether ctx[dst] is changed, according to status.
                # conflict: whether the dst change conflicts with src change.
                if dst in removed:
                    conflict, changed = (action != "r"), True
                elif dst in modified or dst in added:
                    conflict, changed = (fsrc is None
                                         or ctx[dst].cmp(fsrc)), True
                else:
                    conflict = changed = False
                if conflict:
                    raise error.Abort(
                        _("path '%s' needs to be mirrored to '%s', but "
                          "the target already has pending changes") %
                        (src, dst))
                if changed:
                    if action == "r":
                        fmt = _(
                            "not mirroring remove of '%s' to '%s'; it is already removed\n"
                        )
                    else:
                        fmt = _(
                            "not mirroring '%s' to '%s'; it already matches\n")
                    repo.ui.note(fmt % (src, dst))
                    continue

                # Mirror copyfrom, too.
                renamed = fsrc and fsrc.renamed()
                fmirror = fsrc
                msg = None
                if renamed:
                    copyfrom, copynode = renamed
                    newcopyfrom = _mirrorpath(srcmirror, dstmirror, copyfrom)
                    if newcopyfrom:
                        if action == "a":
                            msg = _(
                                "mirrored copy '%s -> %s' to '%s -> %s'\n") % (
                                    copyfrom,
                                    src,
                                    newcopyfrom,
                                    dst,
                                )
                        fmirror = context.overlayfilectx(fsrc,
                                                         copied=(newcopyfrom,
                                                                 copynode))

                mctx[dst] = fmirror
                resultmirrored.add(dst)

                if msg is None:
                    if action == "a":
                        fmt = _("mirrored adding '%s' to '%s'\n")
                    elif action == "m":
                        fmt = _("mirrored changes in '%s' to '%s'\n")
                    else:
                        fmt = _("mirrored remove of '%s' to '%s'\n")
                    msg = fmt % (src, dst)
                repo.ui.status(msg)

    if resultmirrored:
        resultctx = mctx

    return resultctx, resultmirrored
Esempio n. 4
0
 def getfctx(repo, memctx, path):
     if path not in ctx:
         return None
     return context.overlayfilectx(ctx[path])