Example #1
0
    def get_diffs(self):
        from mercurial import mdiff, util, patch
        from repo_browser.integration import Diff

        ctx = self.ctx

        parent = ctx.parents()[0]
        parent_date = util.datestr(parent.date())
        this_date = util.datestr(ctx.date())
        diffopts = patch.diffopts(self.repo.repo.ui, untrusted=True)

        # Returns a tuple of modified, added, removed, deleted, unknown
        # TODO: look up in the api what FIXME* are
        modified, added, removed, deleted, unknown, FIXME, FIXME2 = \
            self.repo.repo.status(
            parent.node(),
            ctx.node(),)

        for modified_file in modified:
            filectx = ctx.filectx(modified_file)
            parent_filectx = parent.filectx(modified_file)
            this_data = filectx.data()
            parent_data = parent_filectx.data()
            yield Diff(
                mdiff.unidiff(parent_data,
                              parent_date,
                              this_data,
                              this_date,
                              modified_file,
                              modified_file,
                              opts=diffopts))

        for added_file in added:
            filectx = ctx.filectx(added_file)
            this_data = filectx.data()
            yield Diff(
                mdiff.unidiff(None,
                              parent_date,
                              this_data,
                              this_date,
                              added_file,
                              added_file,
                              opts=diffopts))

        for removed_file in removed:
            parent_filectx = parent.filectx(removed_file)
            parent_data = parent_filectx.data()
            yield Diff(
                mdiff.unidiff(parent_data,
                              parent_date,
                              None,
                              ctx.date(),
                              removed_file,
                              removed_file,
                              opts=diffopts))
Example #2
0
    def get_diffs(self):
        from mercurial import mdiff, util, patch
        from repo_browser.integration import Diff

        ctx = self.ctx

        parent = ctx.parents()[0]
        parent_date = util.datestr(parent.date())
        this_date = util.datestr(ctx.date())
        diffopts = patch.diffopts(self.repo.repo.ui, untrusted=True)

        # Returns a tuple of modified, added, removed, deleted, unknown
        # TODO: look up in the api what FIXME* are
        modified, added, removed, deleted, unknown, FIXME, FIXME2 = \
            self.repo.repo.status(
            parent.node(),
            ctx.node(),)

        for modified_file in modified:
            filectx = ctx.filectx(modified_file)
            parent_filectx = parent.filectx(modified_file)
            this_data = filectx.data()
            parent_data = parent_filectx.data()
            yield Diff(mdiff.unidiff(parent_data, parent_date,
                                this_data,this_date,
                                modified_file, modified_file,
                                opts=diffopts))

        for added_file in added:
            filectx = ctx.filectx(added_file)
            this_data = filectx.data()
            yield Diff(mdiff.unidiff(
                None, parent_date, this_data, this_date,
                added_file, added_file, opts=diffopts))

        for removed_file in removed:
            parent_filectx = parent.filectx(removed_file)
            parent_data = parent_filectx.data()
            yield Diff(mdiff.unidiff(
                parent_data, parent_date, None, ctx.date(),
                removed_file, removed_file, opts=diffopts))
Example #3
0
 def showDiff(self, index):
     'User selected a row in the candidate tree'
     indexes = index.indexes()
     if not indexes:
         return
     index = indexes[0]
     ctx = self.repo['.']
     hu = htmlui.htmlui()
     row = self.matchtv.model().getRow(index)
     src, dest, percent = self.matchtv.model().getRow(index)
     aa = self.repo.wread(dest)
     rr = ctx.filectx(src).data()
     date = hglib.displaytime(ctx.date())
     difftext = mdiff.unidiff(rr, date, aa, date, src, dest, None)
     if not difftext:
         t = _('%s and %s have identical contents\n\n') % \
                 (hglib.tounicode(src), hglib.tounicode(dest))
         hu.write(t, label='ui.error')
     else:
         for t, l in patch.difflabel(difftext.splitlines, True):
             hu.write(t, label=l)
     self.difftb.setHtml(hu.getdata()[0])
Example #4
0
    def dirtywork(f, mmap1, mmap2):
        lines = 0

        to = mmap1 and repo.file(f).read(mmap1[f]) or None
        tn = mmap2 and repo.file(f).read(mmap2[f]) or None

        diff = mdiff.unidiff(to, "", tn, "", f, f).split("\n")

        for line in diff:
            if not line:
                continue  # skip EOF
            if line.startswith(" "):
                continue  # context line
            if line.startswith("--- ") or line.startswith("+++ "):
                continue  # begining of diff
            if line.startswith("@@ "):
                continue  # info line

            # changed lines
            lines += 1

        return lines
Example #5
0
 def showDiff(self, index):
     'User selected a row in the candidate tree'
     indexes = index.indexes()
     if not indexes:
         return
     index = indexes[0]
     ctx = self.repo['.']
     hu = htmlui.htmlui()
     row = self.matchtv.model().getRow(index)
     src, dest, percent = self.matchtv.model().getRow(index)
     aa = self.repo.wread(dest)
     rr = ctx.filectx(src).data()
     date = hglib.displaytime(ctx.date())
     difftext = mdiff.unidiff(rr, date, aa, date, src, dest, None)
     if not difftext:
         t = _('%s and %s have identical contents\n\n') % \
                 (hglib.tounicode(src), hglib.tounicode(dest))
         hu.write(t, label='ui.error')
     else:
         for t, l in patch.difflabel(difftext.splitlines, True):
             hu.write(t, label=l)
     self.difftb.setHtml(hu.getdata()[0])
Example #6
0
    def dirtywork(f, mmap1, mmap2):
        lines = 0

        to = mmap1 and repo.file(f).read(mmap1[f]) or None
        tn = mmap2 and repo.file(f).read(mmap2[f]) or None

        diff = mdiff.unidiff(to, "", tn, "", f, f).split("\n")

        for line in diff:
            if not line:
                continue # skip EOF
            if line.startswith(" "):
                continue # context line
            if line.startswith("--- ") or line.startswith("+++ "):
                continue # begining of diff
            if line.startswith("@@ "):
                continue # info line

            # changed lines
            lines += 1

        return lines
Example #7
0
    def show_diff(self, selection):
        'User selected a row in the candidate tree'
        hglib.invalidaterepo(self.repo)
        model, cpaths = selection.get_selected_rows()
        sensitive = cpaths and True or False
        self.acceptbtn.set_sensitive(sensitive)

        self.buf.set_text('')
        bufiter = self.buf.get_start_iter()
        for path in cpaths:
            row = model[path]
            src, usrc, dest, udest, percent, sensitive = row
            if not sensitive:
                continue
            ctx = self.repo['.']
            aa = self.repo.wread(dest)
            rr = ctx.filectx(src).data()
            opts = mdiff.defaultopts
            difftext = mdiff.unidiff(rr, '', aa, '', src, dest, None, opts=opts)
            if not difftext:
                l = _('== %s and %s have identical contents ==\n\n') % (src, dest)
                self.buf.insert(bufiter, l)
                continue
            difflines = difftext.splitlines(True)
            for line in difflines:
                line = hglib.toutf(line)
                if line.startswith('---') or line.startswith('+++'):
                    self.buf.insert_with_tags_by_name(bufiter, line, 'header')
                elif line.startswith('-'):
                    line = hglib.diffexpand(line)
                    self.buf.insert_with_tags_by_name(bufiter, line, 'removed')
                elif line.startswith('+'):
                    line = hglib.diffexpand(line)
                    self.buf.insert_with_tags_by_name(bufiter, line, 'added')
                elif line.startswith('@@'):
                    self.buf.insert_with_tags_by_name(bufiter, line, 'position')
                else:
                    line = hglib.diffexpand(line)
                    self.buf.insert(bufiter, line)
Example #8
0
def unidifftext(a, ad, b, bd, fn1, fn2, opts=mdiff.defaultopts):
    headers, hunks = mdiff.unidiff(a, ad, b, bd, fn1, fn2, opts)
    text = ''.join(sum((list(hlines) for _hrange, hlines in hunks), []))
    return '\n'.join(headers) + '\n' + text
Example #9
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 = 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.changectx(node1)
        c2 = r.changectx(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))

        diffopts = patch.diffopts(self.repo.ui, untrusted=True)
        for f in modified:
            to = c1.filectx(f).data()
            tn = c2.filectx(f).data()
            yield diffblock(mdiff.unidiff(to, date1, tn, date2, f, f,
                                          opts=diffopts), f, tn)
        for f in added:
            to = None
            tn = c2.filectx(f).data()
            yield diffblock(mdiff.unidiff(to, date1, tn, date2, f, f,
                                          opts=diffopts), f, tn)
        for f in removed:
            to = c1.filectx(f).data()
            tn = None
            yield diffblock(mdiff.unidiff(to, date1, tn, date2, f, f,
                                          opts=diffopts), f, tn)
Example #10
0
            renamed = fctx.renamed()
            if not renamed:
                self.flabel += _(' <i>(was added)</i>')
                return

            oldname, node = renamed
            fr = hglib.tounicode(oldname)
            self.flabel += _(' <i>(renamed from %s)</i>') % fr
            olddata = repo.filectx(oldname, fileid=node).data()
        elif status == 'M':
            if wfile not in ctx2:
                # merge situation where file was added in other branch
                self.flabel += _(' <i>(was added)</i>')
                return
            oldname = wfile
            olddata = ctx2[wfile].data()
        else:
            return

        self.olddata = olddata
        newdate = util.datestr(ctx.date())
        olddate = util.datestr(ctx2.date())
        revs = [str(ctx), str(ctx2)]
        diffopts = patch.diffopts(repo.ui, {})
        diffopts.git = False
        if isbfile:
            olddata += '\0'
            newdata += '\0'
        self.diff = mdiff.unidiff(olddata, olddate, newdata, newdate, oldname,
                                  wfile, revs, diffopts)
Example #11
0
                self.diff = ''
                return
            self.changes.excludecount = 0
            values = []
            lines = 0
            for chunk in self.changes.hunks:
                buf = cStringIO.StringIO()
                chunk.write(buf)
                chunk.excluded = False
                val = buf.getvalue()
                values.append(val)
                chunk.lineno = lines
                chunk.linecount = len(val.splitlines())
                lines += chunk.linecount
            self.diff = ''.join(values)
        else:
            diffopts = patch.diffopts(repo.ui, {})
            diffopts.git = False
            newdate = util.datestr(ctx.date())
            olddate = util.datestr(ctx2.date())
            if isbfile:
                olddata += '\0'
                newdata += '\0'
            difftext = mdiff.unidiff(olddata, olddate, newdata, newdate,
                                     oldname, wfile, opts=diffopts)
            if difftext:
                self.diff = ('diff -r %s -r %s %s\n' % (ctx, ctx2, oldname)
                             + difftext)
            else:
                self.diff = ''
Example #12
0
            renamed = fctx.renamed()
            if not renamed:
                self.flabel += _(' <i>(was added)</i>')
                return

            oldname, node = renamed
            fr = hglib.tounicode(oldname)
            self.flabel += _(' <i>(renamed from %s)</i>') % fr
            olddata = repo.filectx(oldname, fileid=node).data()
        elif status == 'M':
            if wfile not in ctx2:
                # merge situation where file was added in other branch
                self.flabel += _(' <i>(was added)</i>')
                return
            oldname = wfile
            olddata = ctx2[wfile].data()
        else:
            return

        self.olddata = olddata
        newdate = util.datestr(ctx.date())
        olddate = util.datestr(ctx2.date())
        revs = [str(ctx), str(ctx2)]
        diffopts = patch.diffopts(repo.ui, {})
        diffopts.git = False
        if isbfile:
            olddata += '\0'
            newdata += '\0'
        self.diff = mdiff.unidiff(olddata, olddate, newdata, newdate,
                                  oldname, wfile, revs, diffopts)
Example #13
0
    def _readStatus(self, ctx, ctx2, wfile, status, changeselect, force):
        def getstatus(repo, n1, n2, wfile):
            m = match.exact(repo.root, repo.getcwd(), [wfile])
            modified, added, removed = repo.status(n1, n2, match=m)[:3]
            if wfile in modified:
                return 'M'
            if wfile in added:
                return 'A'
            if wfile in removed:
                return 'R'
            if wfile in ctx:
                return 'C'
            return None

        isbfile = False
        repo = ctx._repo
        maxdiff = repo.maxdiff
        self.flabel = u'<b>%s</b>' % self.filePath()

        if ctx2:
            # If a revision to compare to was provided, we must put it in
            # the context of the subrepo as well
            if ctx2._repo.root != ctx._repo.root:
                wsub2, wfileinsub2, sctx2 = \
                    hglib.getDeepestSubrepoContainingFile(wfile, ctx2)
                if wsub2:
                    ctx2 = sctx2

        absfile = repo.wjoin(wfile)
        if (wfile in ctx and 'l' in ctx.flags(wfile)) or \
           os.path.islink(absfile):
            if wfile in ctx:
                data = ctx[wfile].data()
            else:
                data = os.readlink(absfile)
            self.contents = data
            self.flabel += _(' <i>(is a symlink)</i>')
            return

        if ctx2 is None:
            ctx2 = ctx.p1()
        if status is None:
            status = getstatus(repo, ctx2.node(), ctx.node(), wfile)

        mde = _('File or diffs not displayed: '
                'File is larger than the specified max size.\n'
                'maxdiff = %s KB') % (maxdiff // 1024)

        if status in ('R', '!'):
            if wfile in ctx.p1():
                fctx = ctx.p1()[wfile]
                if fctx._filelog.rawsize(fctx.filerev()) > maxdiff:
                    self.error = mde
                else:
                    olddata = fctx.data()
                    if '\0' in olddata:
                        self.error = 'binary file'
                    else:
                        self.contents = olddata
                self.flabel += _(' <i>(was deleted)</i>')
            elif hasattr(ctx.p1(), 'hasStandin') and ctx.p1().hasStandin(wfile):
                self.error = 'binary file'
                self.flabel += _(' <i>(was deleted)</i>')
            else:
                self.flabel += _(' <i>(was added, now missing)</i>')
            return

        if status in ('I', '?'):
            assert ctx.rev() is None
            self.flabel += _(' <i>(is unversioned)</i>')
            if os.path.getsize(absfile) > maxdiff:
                self.error = mde
                return
            data = util.posixfile(absfile, 'r').read()
            if not force and '\0' in data:
                self.error = 'binary file'
            else:
                self.contents = data
            return

        if status in ('M', 'A', 'C'):
            if ctx.hasStandin(wfile):
                wfile = ctx.findStandin(wfile)
                isbfile = True
            try:
                fctx, newdata = self._checkMaxDiff(ctx, wfile, maxdiff, force)
            except _BadContent:
                if status == 'A':
                    self._checkRenamed(repo, ctx, ctx2, wfile)
                raise
            self.contents = newdata
            if status == 'C':
                # no further comparison is necessary
                return
            for pctx in ctx.parents():
                if 'x' in fctx.flags() and 'x' not in pctx.flags(wfile):
                    self.elabel = _("exec mode has been "
                                    "<font color='red'>set</font>")
                elif 'x' not in fctx.flags() and 'x' in pctx.flags(wfile):
                    self.elabel = _("exec mode has been "
                                    "<font color='red'>unset</font>")

        if status == 'A':
            oldname = self._checkRenamed(repo, ctx, ctx2, wfile)
            if not oldname:
                return
            olddata = ctx2[oldname].data()
        elif status == 'M':
            if wfile not in ctx2:
                # merge situation where file was added in other branch
                self.flabel += _(' <i>(was added)</i>')
                return
            oldname = wfile
            olddata = ctx2[wfile].data()
        else:
            return

        self.olddata = olddata
        if changeselect:
            diffopts = patch.diffopts(repo.ui, {})
            diffopts.git = True
            m = match.exact(repo.root, repo.root, [wfile])
            fp = cStringIO.StringIO()
            for c in patch.diff(repo, ctx.node(), None, match=m, opts=diffopts):
                fp.write(c)
            fp.seek(0)

            # feed diffs through parsepatch() for more fine grained
            # chunk selection
            filediffs = patch.parsepatch(fp)
            if filediffs and filediffs[0].hunks:
                self.changes = filediffs[0]
            else:
                self.diff = ''
                return
            self.changes.excludecount = 0
            values = []
            lines = 0
            for chunk in self.changes.hunks:
                buf = cStringIO.StringIO()
                chunk.write(buf)
                chunk.excluded = False
                val = buf.getvalue()
                values.append(val)
                chunk.lineno = lines
                chunk.linecount = len(val.splitlines())
                lines += chunk.linecount
            self.diff = ''.join(values)
        else:
            diffopts = patch.diffopts(repo.ui, {})
            diffopts.git = False
            newdate = util.datestr(ctx.date())
            olddate = util.datestr(ctx2.date())
            if isbfile:
                olddata += '\0'
                newdata += '\0'
            difftext = mdiff.unidiff(olddata, olddate, newdata, newdate,
                                     oldname, wfile, opts=diffopts)
            if difftext:
                self.diff = ('diff -r %s -r %s %s\n' % (ctx, ctx2, oldname)
                             + difftext)
            else:
                self.diff = ''