Show More
@@ -326,12 +326,12 b' def annotate(ui, repo, *pats, **opts):' | |||||
326 | hexfn = rootfm.hexfunc |
|
326 | hexfn = rootfm.hexfunc | |
327 | formatrev = formathex = pycompat.bytestr |
|
327 | formatrev = formathex = pycompat.bytestr | |
328 |
|
328 | |||
329 |
opmap = [('user', ' ', lambda x: x |
|
329 | opmap = [('user', ' ', lambda x: x.fctx.user(), ui.shortuser), | |
330 |
('number', ' ', lambda x: x |
|
330 | ('number', ' ', lambda x: x.fctx.rev(), formatrev), | |
331 |
('changeset', ' ', lambda x: hexfn(x |
|
331 | ('changeset', ' ', lambda x: hexfn(x.fctx.node()), formathex), | |
332 |
('date', ' ', lambda x: x |
|
332 | ('date', ' ', lambda x: x.fctx.date(), util.cachefunc(datefunc)), | |
333 |
('file', ' ', lambda x: x |
|
333 | ('file', ' ', lambda x: x.fctx.path(), str), | |
334 |
('line_number', ':', lambda x: x |
|
334 | ('line_number', ':', lambda x: x.lineno, str), | |
335 | ] |
|
335 | ] | |
336 | fieldnamemap = {'number': 'rev', 'changeset': 'node'} |
|
336 | fieldnamemap = {'number': 'rev', 'changeset': 'node'} | |
337 |
|
337 |
@@ -25,6 +25,9 b' from .node import (' | |||||
25 | wdirnodes, |
|
25 | wdirnodes, | |
26 | wdirrev, |
|
26 | wdirrev, | |
27 | ) |
|
27 | ) | |
|
28 | from .thirdparty import ( | |||
|
29 | attr, | |||
|
30 | ) | |||
28 | from . import ( |
|
31 | from . import ( | |
29 | encoding, |
|
32 | encoding, | |
30 | error, |
|
33 | error, | |
@@ -983,10 +986,11 b' class basefilectx(object):' | |||||
983 |
|
986 | |||
984 | if linenumber: |
|
987 | if linenumber: | |
985 | def decorate(text, rev): |
|
988 | def decorate(text, rev): | |
986 | return ([(rev, i) for i in xrange(1, lines(text) + 1)], text) |
|
989 | return ([annotateline(fctx=rev, lineno=i) | |
|
990 | for i in xrange(1, lines(text) + 1)], text) | |||
987 | else: |
|
991 | else: | |
988 | def decorate(text, rev): |
|
992 | def decorate(text, rev): | |
989 |
return ([(rev |
|
993 | return ([annotateline(fctx=rev)] * lines(text), text) | |
990 |
|
994 | |||
991 | getlog = util.lrucachefunc(lambda x: self._repo.file(x)) |
|
995 | getlog = util.lrucachefunc(lambda x: self._repo.file(x)) | |
992 |
|
996 | |||
@@ -1103,6 +1107,11 b' class basefilectx(object):' | |||||
1103 | """ |
|
1107 | """ | |
1104 | return self._repo.wwritedata(self.path(), self.data()) |
|
1108 | return self._repo.wwritedata(self.path(), self.data()) | |
1105 |
|
1109 | |||
|
1110 | @attr.s(slots=True, frozen=True) | |||
|
1111 | class annotateline(object): | |||
|
1112 | fctx = attr.ib() | |||
|
1113 | lineno = attr.ib(default=False) | |||
|
1114 | ||||
1106 | def _annotatepair(parents, childfctx, child, skipchild, diffopts): |
|
1115 | def _annotatepair(parents, childfctx, child, skipchild, diffopts): | |
1107 | r''' |
|
1116 | r''' | |
1108 | Given parent and child fctxes and annotate data for parents, for all lines |
|
1117 | Given parent and child fctxes and annotate data for parents, for all lines | |
@@ -1148,7 +1157,7 b' def _annotatepair(parents, childfctx, ch' | |||||
1148 | for (a1, a2, b1, b2), _t in blocks: |
|
1157 | for (a1, a2, b1, b2), _t in blocks: | |
1149 | if a2 - a1 >= b2 - b1: |
|
1158 | if a2 - a1 >= b2 - b1: | |
1150 | for bk in xrange(b1, b2): |
|
1159 | for bk in xrange(b1, b2): | |
1151 |
if child[0][bk] |
|
1160 | if child[0][bk].fctx == childfctx: | |
1152 | ak = min(a1 + (bk - b1), a2 - 1) |
|
1161 | ak = min(a1 + (bk - b1), a2 - 1) | |
1153 | child[0][bk] = parent[0][ak] |
|
1162 | child[0][bk] = parent[0][ak] | |
1154 | else: |
|
1163 | else: | |
@@ -1159,7 +1168,7 b' def _annotatepair(parents, childfctx, ch' | |||||
1159 | for parent, blocks in remaining: |
|
1168 | for parent, blocks in remaining: | |
1160 | for a1, a2, b1, b2 in blocks: |
|
1169 | for a1, a2, b1, b2 in blocks: | |
1161 | for bk in xrange(b1, b2): |
|
1170 | for bk in xrange(b1, b2): | |
1162 |
if child[0][bk] |
|
1171 | if child[0][bk].fctx == childfctx: | |
1163 | ak = min(a1 + (bk - b1), a2 - 1) |
|
1172 | ak = min(a1 + (bk - b1), a2 - 1) | |
1164 | child[0][bk] = parent[0][ak] |
|
1173 | child[0][bk] = parent[0][ak] | |
1165 | return child |
|
1174 | return child |
@@ -906,7 +906,8 b' def annotate(web, req, tmpl):' | |||||
906 |
|
906 | |||
907 | previousrev = None |
|
907 | previousrev = None | |
908 | blockparitygen = paritygen(1) |
|
908 | blockparitygen = paritygen(1) | |
909 |
for lineno, ( |
|
909 | for lineno, (aline, l) in enumerate(lines): | |
|
910 | f = aline.fctx | |||
910 | rev = f.rev() |
|
911 | rev = f.rev() | |
911 | if rev != previousrev: |
|
912 | if rev != previousrev: | |
912 | blockhead = True |
|
913 | blockhead = True | |
@@ -924,7 +925,7 b' def annotate(web, req, tmpl):' | |||||
924 | "file": f.path(), |
|
925 | "file": f.path(), | |
925 | "blockhead": blockhead, |
|
926 | "blockhead": blockhead, | |
926 | "blockparity": blockparity, |
|
927 | "blockparity": blockparity, | |
927 |
"targetline": |
|
928 | "targetline": aline.lineno, | |
928 | "line": l, |
|
929 | "line": l, | |
929 | "lineno": lineno + 1, |
|
930 | "lineno": lineno + 1, | |
930 | "lineid": "l%d" % (lineno + 1), |
|
931 | "lineid": "l%d" % (lineno + 1), |
@@ -7,6 +7,7 b' from mercurial import (' | |||||
7 | mdiff, |
|
7 | mdiff, | |
8 | ) |
|
8 | ) | |
9 | from mercurial.context import ( |
|
9 | from mercurial.context import ( | |
|
10 | annotateline, | |||
10 | _annotatepair, |
|
11 | _annotatepair, | |
11 | ) |
|
12 | ) | |
12 |
|
13 | |||
@@ -25,50 +26,76 b' class AnnotateTests(unittest.TestCase):' | |||||
25 | diffopts = mdiff.diffopts() |
|
26 | diffopts = mdiff.diffopts() | |
26 |
|
27 | |||
27 | def decorate(text, rev): |
|
28 | def decorate(text, rev): | |
28 | return ([(rev, i) for i in xrange(1, text.count(b'\n') + 1)], text) |
|
29 | return ([annotateline(fctx=rev, lineno=i) | |
|
30 | for i in xrange(1, text.count(b'\n') + 1)], | |||
|
31 | text) | |||
29 |
|
32 | |||
30 | # Basic usage |
|
33 | # Basic usage | |
31 |
|
34 | |||
32 | oldann = decorate(olddata, oldfctx) |
|
35 | oldann = decorate(olddata, oldfctx) | |
33 | p1ann = decorate(p1data, p1fctx) |
|
36 | p1ann = decorate(p1data, p1fctx) | |
34 | p1ann = _annotatepair([oldann], p1fctx, p1ann, False, diffopts) |
|
37 | p1ann = _annotatepair([oldann], p1fctx, p1ann, False, diffopts) | |
35 |
self.assertEqual(p1ann[0], [ |
|
38 | self.assertEqual(p1ann[0], [ | |
|
39 | annotateline('old', 1), | |||
|
40 | annotateline('old', 2), | |||
|
41 | annotateline('p1', 3), | |||
|
42 | ]) | |||
36 |
|
43 | |||
37 | p2ann = decorate(p2data, p2fctx) |
|
44 | p2ann = decorate(p2data, p2fctx) | |
38 | p2ann = _annotatepair([oldann], p2fctx, p2ann, False, diffopts) |
|
45 | p2ann = _annotatepair([oldann], p2fctx, p2ann, False, diffopts) | |
39 |
self.assertEqual(p2ann[0], [ |
|
46 | self.assertEqual(p2ann[0], [ | |
|
47 | annotateline('old', 1), | |||
|
48 | annotateline('p2', 2), | |||
|
49 | annotateline('p2', 3), | |||
|
50 | ]) | |||
40 |
|
51 | |||
41 | # Test with multiple parents (note the difference caused by ordering) |
|
52 | # Test with multiple parents (note the difference caused by ordering) | |
42 |
|
53 | |||
43 | childann = decorate(childdata, childfctx) |
|
54 | childann = decorate(childdata, childfctx) | |
44 | childann = _annotatepair([p1ann, p2ann], childfctx, childann, False, |
|
55 | childann = _annotatepair([p1ann, p2ann], childfctx, childann, False, | |
45 | diffopts) |
|
56 | diffopts) | |
46 | self.assertEqual(childann[0], |
|
57 | self.assertEqual(childann[0], [ | |
47 | [('old', 1), ('c', 2), ('p2', 2), ('c', 4), ('p2', 3)] |
|
58 | annotateline('old', 1), | |
48 | ) |
|
59 | annotateline('c', 2), | |
|
60 | annotateline('p2', 2), | |||
|
61 | annotateline('c', 4), | |||
|
62 | annotateline('p2', 3), | |||
|
63 | ]) | |||
49 |
|
64 | |||
50 | childann = decorate(childdata, childfctx) |
|
65 | childann = decorate(childdata, childfctx) | |
51 | childann = _annotatepair([p2ann, p1ann], childfctx, childann, False, |
|
66 | childann = _annotatepair([p2ann, p1ann], childfctx, childann, False, | |
52 | diffopts) |
|
67 | diffopts) | |
53 | self.assertEqual(childann[0], |
|
68 | self.assertEqual(childann[0], [ | |
54 | [('old', 1), ('c', 2), ('p1', 3), ('c', 4), ('p2', 3)] |
|
69 | annotateline('old', 1), | |
55 | ) |
|
70 | annotateline('c', 2), | |
|
71 | annotateline('p1', 3), | |||
|
72 | annotateline('c', 4), | |||
|
73 | annotateline('p2', 3), | |||
|
74 | ]) | |||
56 |
|
75 | |||
57 | # Test with skipchild (note the difference caused by ordering) |
|
76 | # Test with skipchild (note the difference caused by ordering) | |
58 |
|
77 | |||
59 | childann = decorate(childdata, childfctx) |
|
78 | childann = decorate(childdata, childfctx) | |
60 | childann = _annotatepair([p1ann, p2ann], childfctx, childann, True, |
|
79 | childann = _annotatepair([p1ann, p2ann], childfctx, childann, True, | |
61 | diffopts) |
|
80 | diffopts) | |
62 | self.assertEqual(childann[0], |
|
81 | self.assertEqual(childann[0], [ | |
63 | [('old', 1), ('old', 2), ('p2', 2), ('p2', 2), ('p2', 3)] |
|
82 | annotateline('old', 1), | |
64 | ) |
|
83 | annotateline('old', 2), | |
|
84 | annotateline('p2', 2), | |||
|
85 | annotateline('p2', 2), | |||
|
86 | annotateline('p2', 3), | |||
|
87 | ]) | |||
65 |
|
88 | |||
66 | childann = decorate(childdata, childfctx) |
|
89 | childann = decorate(childdata, childfctx) | |
67 | childann = _annotatepair([p2ann, p1ann], childfctx, childann, True, |
|
90 | childann = _annotatepair([p2ann, p1ann], childfctx, childann, True, | |
68 | diffopts) |
|
91 | diffopts) | |
69 | self.assertEqual(childann[0], |
|
92 | self.assertEqual(childann[0], [ | |
70 | [('old', 1), ('old', 2), ('p1', 3), ('p1', 3), ('p2', 3)] |
|
93 | annotateline('old', 1), | |
71 | ) |
|
94 | annotateline('old', 2), | |
|
95 | annotateline('p1', 3), | |||
|
96 | annotateline('p1', 3), | |||
|
97 | annotateline('p2', 3), | |||
|
98 | ]) | |||
72 |
|
99 | |||
73 | if __name__ == '__main__': |
|
100 | if __name__ == '__main__': | |
74 | import silenttestrunner |
|
101 | import silenttestrunner |
General Comments 0
You need to be logged in to leave comments.
Login now