Show More
@@ -199,6 +199,21 b' elif cmd == "diff":' | |||||
199 |
|
199 | |||
200 | diff(args, *revs) |
|
200 | diff(args, *revs) | |
201 |
|
201 | |||
|
202 | elif cmd == "annotate": | |||
|
203 | aoptions = {} | |||
|
204 | opts = [('r', 'revision', '', 'revision')] | |||
|
205 | args = fancyopts.fancyopts(args, opts, aoptions, | |||
|
206 | 'hg annotate [-r id] [files]') | |||
|
207 | if args: | |||
|
208 | node = repo.current | |||
|
209 | if aoptions['revision']: | |||
|
210 | node = repo.changelog.lookup(aoptions['revision']) | |||
|
211 | change = repo.changelog.read(node) | |||
|
212 | mmap = repo.manifest.read(change[0]) | |||
|
213 | for f in args: | |||
|
214 | for n, l in repo.file(f).annotate(mmap[f]): | |||
|
215 | sys.stdout.write("%s: %s"%(n, l)) | |||
|
216 | ||||
202 | elif cmd == "export": |
|
217 | elif cmd == "export": | |
203 | node = repo.lookup(args[0]) |
|
218 | node = repo.lookup(args[0]) | |
204 | prev, other = repo.changelog.parents(node) |
|
219 | prev, other = repo.changelog.parents(node) |
@@ -10,6 +10,7 b' import urllib' | |||||
10 | from mercurial import byterange |
|
10 | from mercurial import byterange | |
11 | from mercurial.transaction import * |
|
11 | from mercurial.transaction import * | |
12 | from mercurial.revlog import * |
|
12 | from mercurial.revlog import * | |
|
13 | from difflib import SequenceMatcher | |||
13 |
|
14 | |||
14 | class filelog(revlog): |
|
15 | class filelog(revlog): | |
15 | def __init__(self, opener, path): |
|
16 | def __init__(self, opener, path): | |
@@ -65,6 +66,32 b' class filelog(revlog):' | |||||
65 | (o, n) = self.mergedag(other, transaction, linkseq) |
|
66 | (o, n) = self.mergedag(other, transaction, linkseq) | |
66 | return self.resolvedag(o, n, transaction, link) |
|
67 | return self.resolvedag(o, n, transaction, link) | |
67 |
|
68 | |||
|
69 | def annotate(self, node): | |||
|
70 | revs = [] | |||
|
71 | while node != nullid: | |||
|
72 | revs.append(node) | |||
|
73 | node = self.parents(node)[0] | |||
|
74 | revs.reverse() | |||
|
75 | prev = [] | |||
|
76 | annotate = [] | |||
|
77 | for node in revs: | |||
|
78 | curr = self.read(node).splitlines(1) | |||
|
79 | linkrev = self.linkrev(node) | |||
|
80 | sm = SequenceMatcher(None, prev, curr) | |||
|
81 | offset = 0 | |||
|
82 | for o, m, n, s, t in sm.get_opcodes(): | |||
|
83 | if o in ('insert','replace'): | |||
|
84 | annotate[m+offset:n+offset] = \ | |||
|
85 | [ (linkrev, l) for l in curr[s:t]] | |||
|
86 | if o == 'insert': | |||
|
87 | offset += m-n | |||
|
88 | elif o == 'delete': | |||
|
89 | del annotate[m+offset:n+offset] | |||
|
90 | offset -= m-n | |||
|
91 | assert len(annotate) == len(curr) | |||
|
92 | prev = curr | |||
|
93 | return annotate | |||
|
94 | ||||
68 | class manifest(revlog): |
|
95 | class manifest(revlog): | |
69 | def __init__(self, opener): |
|
96 | def __init__(self, opener): | |
70 | self.mapcache = None |
|
97 | self.mapcache = None |
General Comments 0
You need to be logged in to leave comments.
Login now