Add basic annotation support

filelog.annotate() will get the change number on each line.

Singed-Off-by: Christopher Li<hg@chrisli.org>
This commit is contained in:
mpm@selenic.com 2005-05-17 01:12:30 -08:00
parent f16efef9d1
commit 08e7e95781
2 changed files with 42 additions and 0 deletions

15
hg
View File

@ -199,6 +199,21 @@ elif cmd == "diff":
diff(args, *revs)
elif cmd == "annotate":
aoptions = {}
opts = [('r', 'revision', '', 'revision')]
args = fancyopts.fancyopts(args, opts, aoptions,
'hg annotate [-r id] [files]')
if args:
node = repo.current
if aoptions['revision']:
node = repo.changelog.lookup(aoptions['revision'])
change = repo.changelog.read(node)
mmap = repo.manifest.read(change[0])
for f in args:
for n, l in repo.file(f).annotate(mmap[f]):
sys.stdout.write("%s: %s"%(n, l))
elif cmd == "export":
node = repo.lookup(args[0])
prev, other = repo.changelog.parents(node)

View File

@ -10,6 +10,7 @@ import urllib
from mercurial import byterange
from mercurial.transaction import *
from mercurial.revlog import *
from difflib import SequenceMatcher
class filelog(revlog):
def __init__(self, opener, path):
@ -65,6 +66,32 @@ class filelog(revlog):
(o, n) = self.mergedag(other, transaction, linkseq)
return self.resolvedag(o, n, transaction, link)
def annotate(self, node):
revs = []
while node != nullid:
revs.append(node)
node = self.parents(node)[0]
revs.reverse()
prev = []
annotate = []
for node in revs:
curr = self.read(node).splitlines(1)
linkrev = self.linkrev(node)
sm = SequenceMatcher(None, prev, curr)
offset = 0
for o, m, n, s, t in sm.get_opcodes():
if o in ('insert','replace'):
annotate[m+offset:n+offset] = \
[ (linkrev, l) for l in curr[s:t]]
if o == 'insert':
offset += m-n
elif o == 'delete':
del annotate[m+offset:n+offset]
offset -= m-n
assert len(annotate) == len(curr)
prev = curr
return annotate
class manifest(revlog):
def __init__(self, opener):
self.mapcache = None