示例#1
0
    def diff(self, tmpl, node1, node2, files):
        def filterfiles(filters, files):
            l = [x for x in files if x in filters]

            for t in filters:
                if t and t[-1] != os.sep:
                    t += os.sep
                l += [x for x in files if x.startswith(t)]
            return l

        parity = paritygen(self.stripecount)

        def diffblock(diff, f, fn):
            yield tmpl(
                "diffblock", lines=prettyprintlines(diff), parity=parity.next(), file=f, filenode=hex(fn or nullid)
            )

        blockcount = webutil.countgen()

        def prettyprintlines(diff):
            blockno = blockcount.next()
            for lineno, l in enumerate(diff.splitlines(1)):
                if blockno == 0:
                    lineno = lineno + 1
                else:
                    lineno = "%d.%d" % (blockno, lineno + 1)
                if l.startswith("+"):
                    ltype = "difflineplus"
                elif l.startswith("-"):
                    ltype = "difflineminus"
                elif l.startswith("@"):
                    ltype = "difflineat"
                else:
                    ltype = "diffline"
                yield tmpl(ltype, line=l, lineid="l%s" % lineno, linenumber="% 8s" % lineno)

        r = self.repo
        c1 = r[node1]
        c2 = r[node2]
        date1 = util.datestr(c1.date())
        date2 = util.datestr(c2.date())

        modified, added, removed, deleted, unknown = r.status(node1, node2)[:5]
        if files:
            modified, added, removed = map(lambda x: filterfiles(files, x), (modified, added, removed))

        for f in modified:
            to = c1.filectx(f).data()
            tn = c2.filectx(f).data()
            yield diffblock(mdiff.unidiff(to, date1, tn, date2, f, f), f, tn)
        for f in added:
            to = None
            tn = c2.filectx(f).data()
            yield diffblock(mdiff.unidiff(to, date1, tn, date2, f, f), f, tn)
        for f in removed:
            to = c1.filectx(f).data()
            tn = None
            yield diffblock(mdiff.unidiff(to, date1, tn, date2, f, f), f, tn)
示例#2
0
文件: patch.py 项目: as/9front-work
def diff(repo, node1=None, node2=None, match=None, changes=None, opts=None):
    '''yields diff of changes to files between two nodes, or node and
    working directory.

    if node1 is None, use first dirstate parent instead.
    if node2 is None, compare node1 with working directory.'''

    if opts is None:
        opts = mdiff.defaultopts

    if not node1:
        node1 = repo.dirstate.parents()[0]

    def lrugetfilectx():
        cache = {}
        order = []
        def getfilectx(f, ctx):
            fctx = ctx.filectx(f, filelog=cache.get(f))
            if f not in cache:
                if len(cache) > 20:
                    del cache[order.pop(0)]
                cache[f] = fctx._filelog
            else:
                order.remove(f)
            order.append(f)
            return fctx
        return getfilectx
    getfilectx = lrugetfilectx()

    ctx1 = repo[node1]
    ctx2 = repo[node2]

    if not changes:
        changes = repo.status(ctx1, ctx2, match=match)
    modified, added, removed = changes[:3]

    if not modified and not added and not removed:
        return

    date1 = util.datestr(ctx1.date())
    man1 = ctx1.manifest()

    if repo.ui.quiet:
        r = None
    else:
        hexfunc = repo.ui.debugflag and hex or short
        r = [hexfunc(node) for node in [node1, node2] if node]

    if opts.git:
        copy, diverge = copies.copies(repo, ctx1, ctx2, repo[nullid])
        copy = copy.copy()
        for k, v in copy.items():
            copy[v] = k

    gone = set()
    gitmode = {'l': '120000', 'x': '100755', '': '100644'}

    for f in sorted(modified + added + removed):
        to = None
        tn = None
        dodiff = True
        header = []
        if f in man1:
            to = getfilectx(f, ctx1).data()
        if f not in removed:
            tn = getfilectx(f, ctx2).data()
        a, b = f, f
        if opts.git:
            if f in added:
                mode = gitmode[ctx2.flags(f)]
                if f in copy:
                    a = copy[f]
                    omode = gitmode[man1.flags(a)]
                    _addmodehdr(header, omode, mode)
                    if a in removed and a not in gone:
                        op = 'rename'
                        gone.add(a)
                    else:
                        op = 'copy'
                    header.append('%s from %s\n' % (op, a))
                    header.append('%s to %s\n' % (op, f))
                    to = getfilectx(a, ctx1).data()
                else:
                    header.append('new file mode %s\n' % mode)
                if util.binary(tn):
                    dodiff = 'binary'
            elif f in removed:
                # have we already reported a copy above?
                if f in copy and copy[f] in added and copy[copy[f]] == f:
                    dodiff = False
                else:
                    header.append('deleted file mode %s\n' %
                                  gitmode[man1.flags(f)])
            else:
                omode = gitmode[man1.flags(f)]
                nmode = gitmode[ctx2.flags(f)]
                _addmodehdr(header, omode, nmode)
                if util.binary(to) or util.binary(tn):
                    dodiff = 'binary'
            r = None
            header.insert(0, mdiff.diffline(r, a, b, opts))
        if dodiff:
            if dodiff == 'binary':
                text = b85diff(to, tn)
            else:
                text = mdiff.unidiff(to, date1,
                                    # ctx2 date may be dynamic
                                    tn, util.datestr(ctx2.date()),
                                    a, b, r, opts=opts)
            if header and (text or len(header) > 1):
                yield ''.join(header)
            if text:
                yield text
示例#3
0
文件: patch.py 项目: c0ns0le/cygwin
def diff(repo, node1=None, node2=None, files=None, match=util.always,
         fp=None, changes=None, opts=None):
    '''print diff of changes to files between two nodes, or node and
    working directory.

    if node1 is None, use first dirstate parent instead.
    if node2 is None, compare node1 with working directory.'''

    if opts is None:
        opts = mdiff.defaultopts
    if fp is None:
        fp = repo.ui

    if not node1:
        node1 = repo.dirstate.parents()[0]

    ccache = {}
    def getctx(r):
        if r not in ccache:
            ccache[r] = context.changectx(repo, r)
        return ccache[r]

    flcache = {}
    def getfilectx(f, ctx):
        flctx = ctx.filectx(f, filelog=flcache.get(f))
        if f not in flcache:
            flcache[f] = flctx._filelog
        return flctx

    # reading the data for node1 early allows it to play nicely
    # with repo.status and the revlog cache.
    ctx1 = context.changectx(repo, node1)
    # force manifest reading
    man1 = ctx1.manifest()
    date1 = util.datestr(ctx1.date())

    if not changes:
        changes = repo.status(node1, node2, files, match=match)[:5]
    modified, added, removed, deleted, unknown = changes

    if not modified and not added and not removed:
        return

    if node2:
        ctx2 = context.changectx(repo, node2)
        execf2 = ctx2.manifest().execf
        linkf2 = ctx2.manifest().linkf
    else:
        ctx2 = context.workingctx(repo)
        execf2 = util.execfunc(repo.root, None)
        linkf2 = util.linkfunc(repo.root, None)
        if execf2 is None:
            mc = ctx2.parents()[0].manifest().copy()
            execf2 = mc.execf
            linkf2 = mc.linkf

    if repo.ui.quiet:
        r = None
    else:
        hexfunc = repo.ui.debugflag and hex or short
        r = [hexfunc(node) for node in [node1, node2] if node]

    if opts.git:
        copy, diverge = copies.copies(repo, ctx1, ctx2, repo.changectx(nullid))
        for k, v in copy.items():
            copy[v] = k

    all = modified + added + removed
    all.sort()
    gone = {}

    for f in all:
        to = None
        tn = None
        dodiff = True
        header = []
        if f in man1:
            to = getfilectx(f, ctx1).data()
        if f not in removed:
            tn = getfilectx(f, ctx2).data()
        a, b = f, f
        if opts.git:
            def gitmode(x, l):
                return l and '120000' or (x and '100755' or '100644')
            def addmodehdr(header, omode, nmode):
                if omode != nmode:
                    header.append('old mode %s\n' % omode)
                    header.append('new mode %s\n' % nmode)

            if f in added:
                mode = gitmode(execf2(f), linkf2(f))
                if f in copy:
                    a = copy[f]
                    omode = gitmode(man1.execf(a), man1.linkf(a))
                    addmodehdr(header, omode, mode)
                    if a in removed and a not in gone:
                        op = 'rename'
                        gone[a] = 1
                    else:
                        op = 'copy'
                    header.append('%s from %s\n' % (op, a))
                    header.append('%s to %s\n' % (op, f))
                    to = getfilectx(a, ctx1).data()
                else:
                    header.append('new file mode %s\n' % mode)
                if util.binary(tn):
                    dodiff = 'binary'
            elif f in removed:
                # have we already reported a copy above?
                if f in copy and copy[f] in added and copy[copy[f]] == f:
                    dodiff = False
                else:
                    mode = gitmode(man1.execf(f), man1.linkf(f))
                    header.append('deleted file mode %s\n' % mode)
            else:
                omode = gitmode(man1.execf(f), man1.linkf(f))
                nmode = gitmode(execf2(f), linkf2(f))
                addmodehdr(header, omode, nmode)
                if util.binary(to) or util.binary(tn):
                    dodiff = 'binary'
            r = None
            header.insert(0, 'diff --git a/%s b/%s\n' % (a, b))
        if dodiff:
            if dodiff == 'binary':
                text = b85diff(to, tn)
            else:
                text = mdiff.unidiff(to, date1,
                                    # ctx2 date may be dynamic
                                    tn, util.datestr(ctx2.date()),
                                    a, b, r, opts=opts)
            if text or len(header) > 1:
                fp.write(''.join(header))
            fp.write(text)
示例#4
0
def diff(repo,
         node1=None,
         node2=None,
         files=None,
         match=util.always,
         fp=None,
         changes=None,
         opts=None):
    '''print diff of changes to files between two nodes, or node and
    working directory.

    if node1 is None, use first dirstate parent instead.
    if node2 is None, compare node1 with working directory.'''

    if opts is None:
        opts = mdiff.defaultopts
    if fp is None:
        fp = repo.ui

    if not node1:
        node1 = repo.dirstate.parents()[0]

    ccache = {}

    def getctx(r):
        if r not in ccache:
            ccache[r] = context.changectx(repo, r)
        return ccache[r]

    flcache = {}

    def getfilectx(f, ctx):
        flctx = ctx.filectx(f, filelog=flcache.get(f))
        if f not in flcache:
            flcache[f] = flctx._filelog
        return flctx

    # reading the data for node1 early allows it to play nicely
    # with repo.status and the revlog cache.
    ctx1 = context.changectx(repo, node1)
    # force manifest reading
    man1 = ctx1.manifest()
    date1 = util.datestr(ctx1.date())

    if not changes:
        changes = repo.status(node1, node2, files, match=match)[:5]
    modified, added, removed, deleted, unknown = changes

    if not modified and not added and not removed:
        return

    if node2:
        ctx2 = context.changectx(repo, node2)
        execf2 = ctx2.manifest().execf
        linkf2 = ctx2.manifest().linkf
    else:
        ctx2 = context.workingctx(repo)
        execf2 = util.execfunc(repo.root, None)
        linkf2 = util.linkfunc(repo.root, None)
        if execf2 is None:
            mc = ctx2.parents()[0].manifest().copy()
            execf2 = mc.execf
            linkf2 = mc.linkf

    if repo.ui.quiet:
        r = None
    else:
        hexfunc = repo.ui.debugflag and hex or short
        r = [hexfunc(node) for node in [node1, node2] if node]

    if opts.git:
        copy, diverge = copies.copies(repo, ctx1, ctx2, repo.changectx(nullid))
        for k, v in copy.items():
            copy[v] = k

    all = modified + added + removed
    all.sort()
    gone = {}

    for f in all:
        to = None
        tn = None
        dodiff = True
        header = []
        if f in man1:
            to = getfilectx(f, ctx1).data()
        if f not in removed:
            tn = getfilectx(f, ctx2).data()
        a, b = f, f
        if opts.git:

            def gitmode(x, l):
                return l and '120000' or (x and '100755' or '100644')

            def addmodehdr(header, omode, nmode):
                if omode != nmode:
                    header.append('old mode %s\n' % omode)
                    header.append('new mode %s\n' % nmode)

            if f in added:
                mode = gitmode(execf2(f), linkf2(f))
                if f in copy:
                    a = copy[f]
                    omode = gitmode(man1.execf(a), man1.linkf(a))
                    addmodehdr(header, omode, mode)
                    if a in removed and a not in gone:
                        op = 'rename'
                        gone[a] = 1
                    else:
                        op = 'copy'
                    header.append('%s from %s\n' % (op, a))
                    header.append('%s to %s\n' % (op, f))
                    to = getfilectx(a, ctx1).data()
                else:
                    header.append('new file mode %s\n' % mode)
                if util.binary(tn):
                    dodiff = 'binary'
            elif f in removed:
                # have we already reported a copy above?
                if f in copy and copy[f] in added and copy[copy[f]] == f:
                    dodiff = False
                else:
                    mode = gitmode(man1.execf(f), man1.linkf(f))
                    header.append('deleted file mode %s\n' % mode)
            else:
                omode = gitmode(man1.execf(f), man1.linkf(f))
                nmode = gitmode(execf2(f), linkf2(f))
                addmodehdr(header, omode, nmode)
                if util.binary(to) or util.binary(tn):
                    dodiff = 'binary'
            r = None
            header.insert(0, 'diff --git a/%s b/%s\n' % (a, b))
        if dodiff:
            if dodiff == 'binary':
                text = b85diff(to, tn)
            else:
                text = mdiff.unidiff(
                    to,
                    date1,
                    # ctx2 date may be dynamic
                    tn,
                    util.datestr(ctx2.date()),
                    a,
                    b,
                    r,
                    opts=opts)
            if text or len(header) > 1:
                fp.write(''.join(header))
            fp.write(text)
示例#5
0
def diff(repo, node1=None, node2=None, match=None, changes=None, opts=None):
    """yields diff of changes to files between two nodes, or node and
    working directory.

    if node1 is None, use first dirstate parent instead.
    if node2 is None, compare node1 with working directory."""

    if opts is None:
        opts = mdiff.defaultopts

    if not node1:
        node1 = repo.dirstate.parents()[0]

    flcache = {}

    def getfilectx(f, ctx):
        flctx = ctx.filectx(f, filelog=flcache.get(f))
        if f not in flcache:
            flcache[f] = flctx._filelog
        return flctx

    ctx1 = repo[node1]
    ctx2 = repo[node2]

    if not changes:
        changes = repo.status(ctx1, ctx2, match=match)
    modified, added, removed = changes[:3]

    if not modified and not added and not removed:
        return

    date1 = util.datestr(ctx1.date())
    man1 = ctx1.manifest()

    if repo.ui.quiet:
        r = None
    else:
        hexfunc = repo.ui.debugflag and hex or short
        r = [hexfunc(node) for node in [node1, node2] if node]

    if opts.git:
        copy, diverge = copies.copies(repo, ctx1, ctx2, repo[nullid])
        for k, v in copy.items():
            copy[v] = k

    gone = {}
    gitmode = {"l": "120000", "x": "100755", "": "100644"}

    for f in util.sort(modified + added + removed):
        to = None
        tn = None
        dodiff = True
        header = []
        if f in man1:
            to = getfilectx(f, ctx1).data()
        if f not in removed:
            tn = getfilectx(f, ctx2).data()
        a, b = f, f
        if opts.git:
            if f in added:
                mode = gitmode[ctx2.flags(f)]
                if f in copy:
                    a = copy[f]
                    omode = gitmode[man1.flags(a)]
                    _addmodehdr(header, omode, mode)
                    if a in removed and a not in gone:
                        op = "rename"
                        gone[a] = 1
                    else:
                        op = "copy"
                    header.append("%s from %s\n" % (op, a))
                    header.append("%s to %s\n" % (op, f))
                    to = getfilectx(a, ctx1).data()
                else:
                    header.append("new file mode %s\n" % mode)
                if util.binary(tn):
                    dodiff = "binary"
            elif f in removed:
                # have we already reported a copy above?
                if f in copy and copy[f] in added and copy[copy[f]] == f:
                    dodiff = False
                else:
                    header.append("deleted file mode %s\n" % gitmode[man1.flags(f)])
            else:
                omode = gitmode[man1.flags(f)]
                nmode = gitmode[ctx2.flags(f)]
                _addmodehdr(header, omode, nmode)
                if util.binary(to) or util.binary(tn):
                    dodiff = "binary"
            r = None
            header.insert(0, mdiff.diffline(r, a, b, opts))
        if dodiff:
            if dodiff == "binary":
                text = b85diff(to, tn)
            else:
                text = mdiff.unidiff(
                    to,
                    date1,
                    # ctx2 date may be dynamic
                    tn,
                    util.datestr(ctx2.date()),
                    a,
                    b,
                    r,
                    opts=opts,
                )
            if header and (text or len(header) > 1):
                yield "".join(header)
            if text:
                yield text