diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -326,12 +326,12 @@ hexfn = rootfm.hexfunc formatrev = formathex = pycompat.bytestr - opmap = [('user', ' ', lambda x: x[0].user(), ui.shortuser), - ('number', ' ', lambda x: x[0].rev(), formatrev), - ('changeset', ' ', lambda x: hexfn(x[0].node()), formathex), - ('date', ' ', lambda x: x[0].date(), util.cachefunc(datefunc)), - ('file', ' ', lambda x: x[0].path(), str), - ('line_number', ':', lambda x: x[1], str), + opmap = [('user', ' ', lambda x: x.fctx.user(), ui.shortuser), + ('number', ' ', lambda x: x.fctx.rev(), formatrev), + ('changeset', ' ', lambda x: hexfn(x.fctx.node()), formathex), + ('date', ' ', lambda x: x.fctx.date(), util.cachefunc(datefunc)), + ('file', ' ', lambda x: x.fctx.path(), str), + ('line_number', ':', lambda x: x.lineno, str), ] fieldnamemap = {'number': 'rev', 'changeset': 'node'} diff --git a/mercurial/context.py b/mercurial/context.py --- a/mercurial/context.py +++ b/mercurial/context.py @@ -25,6 +25,9 @@ wdirnodes, wdirrev, ) +from .thirdparty import ( + attr, +) from . import ( encoding, error, @@ -983,10 +986,11 @@ if linenumber: def decorate(text, rev): - return ([(rev, i) for i in xrange(1, lines(text) + 1)], text) + return ([annotateline(fctx=rev, lineno=i) + for i in xrange(1, lines(text) + 1)], text) else: def decorate(text, rev): - return ([(rev, False)] * lines(text), text) + return ([annotateline(fctx=rev)] * lines(text), text) getlog = util.lrucachefunc(lambda x: self._repo.file(x)) @@ -1103,6 +1107,11 @@ """ return self._repo.wwritedata(self.path(), self.data()) +@attr.s(slots=True, frozen=True) +class annotateline(object): + fctx = attr.ib() + lineno = attr.ib(default=False) + def _annotatepair(parents, childfctx, child, skipchild, diffopts): r''' Given parent and child fctxes and annotate data for parents, for all lines @@ -1148,7 +1157,7 @@ for (a1, a2, b1, b2), _t in blocks: if a2 - a1 >= b2 - b1: for bk in xrange(b1, b2): - if child[0][bk][0] == childfctx: + if child[0][bk].fctx == childfctx: ak = min(a1 + (bk - b1), a2 - 1) child[0][bk] = parent[0][ak] else: @@ -1159,7 +1168,7 @@ for parent, blocks in remaining: for a1, a2, b1, b2 in blocks: for bk in xrange(b1, b2): - if child[0][bk][0] == childfctx: + if child[0][bk].fctx == childfctx: ak = min(a1 + (bk - b1), a2 - 1) child[0][bk] = parent[0][ak] return child diff --git a/mercurial/hgweb/webcommands.py b/mercurial/hgweb/webcommands.py --- a/mercurial/hgweb/webcommands.py +++ b/mercurial/hgweb/webcommands.py @@ -906,7 +906,8 @@ previousrev = None blockparitygen = paritygen(1) - for lineno, ((f, targetline), l) in enumerate(lines): + for lineno, (aline, l) in enumerate(lines): + f = aline.fctx rev = f.rev() if rev != previousrev: blockhead = True @@ -924,7 +925,7 @@ "file": f.path(), "blockhead": blockhead, "blockparity": blockparity, - "targetline": targetline, + "targetline": aline.lineno, "line": l, "lineno": lineno + 1, "lineid": "l%d" % (lineno + 1), diff --git a/tests/test-annotate.py b/tests/test-annotate.py --- a/tests/test-annotate.py +++ b/tests/test-annotate.py @@ -7,6 +7,7 @@ mdiff, ) from mercurial.context import ( + annotateline, _annotatepair, ) @@ -25,50 +26,76 @@ diffopts = mdiff.diffopts() def decorate(text, rev): - return ([(rev, i) for i in xrange(1, text.count(b'\n') + 1)], text) + return ([annotateline(fctx=rev, lineno=i) + for i in xrange(1, text.count(b'\n') + 1)], + text) # Basic usage oldann = decorate(olddata, oldfctx) p1ann = decorate(p1data, p1fctx) p1ann = _annotatepair([oldann], p1fctx, p1ann, False, diffopts) - self.assertEqual(p1ann[0], [('old', 1), ('old', 2), ('p1', 3)]) + self.assertEqual(p1ann[0], [ + annotateline('old', 1), + annotateline('old', 2), + annotateline('p1', 3), + ]) p2ann = decorate(p2data, p2fctx) p2ann = _annotatepair([oldann], p2fctx, p2ann, False, diffopts) - self.assertEqual(p2ann[0], [('old', 1), ('p2', 2), ('p2', 3)]) + self.assertEqual(p2ann[0], [ + annotateline('old', 1), + annotateline('p2', 2), + annotateline('p2', 3), + ]) # Test with multiple parents (note the difference caused by ordering) childann = decorate(childdata, childfctx) childann = _annotatepair([p1ann, p2ann], childfctx, childann, False, diffopts) - self.assertEqual(childann[0], - [('old', 1), ('c', 2), ('p2', 2), ('c', 4), ('p2', 3)] - ) + self.assertEqual(childann[0], [ + annotateline('old', 1), + annotateline('c', 2), + annotateline('p2', 2), + annotateline('c', 4), + annotateline('p2', 3), + ]) childann = decorate(childdata, childfctx) childann = _annotatepair([p2ann, p1ann], childfctx, childann, False, diffopts) - self.assertEqual(childann[0], - [('old', 1), ('c', 2), ('p1', 3), ('c', 4), ('p2', 3)] - ) + self.assertEqual(childann[0], [ + annotateline('old', 1), + annotateline('c', 2), + annotateline('p1', 3), + annotateline('c', 4), + annotateline('p2', 3), + ]) # Test with skipchild (note the difference caused by ordering) childann = decorate(childdata, childfctx) childann = _annotatepair([p1ann, p2ann], childfctx, childann, True, diffopts) - self.assertEqual(childann[0], - [('old', 1), ('old', 2), ('p2', 2), ('p2', 2), ('p2', 3)] - ) + self.assertEqual(childann[0], [ + annotateline('old', 1), + annotateline('old', 2), + annotateline('p2', 2), + annotateline('p2', 2), + annotateline('p2', 3), + ]) childann = decorate(childdata, childfctx) childann = _annotatepair([p2ann, p1ann], childfctx, childann, True, diffopts) - self.assertEqual(childann[0], - [('old', 1), ('old', 2), ('p1', 3), ('p1', 3), ('p2', 3)] - ) + self.assertEqual(childann[0], [ + annotateline('old', 1), + annotateline('old', 2), + annotateline('p1', 3), + annotateline('p1', 3), + annotateline('p2', 3), + ]) if __name__ == '__main__': import silenttestrunner