Help needed with implementing annotate
John Arbash Meinel
john at arbash-meinel.com
Thu Nov 29 20:28:09 GMT 2007
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Jeremy Wilkins wrote:
> Hi All,
>
> I've been doing some work on the TextMate integration with Bazaar.
> I've been trying to implement annotate support, the approach is to
> iterate over each line in the file and spit out a HTML table, which
> TextMate can render with an embedded webkit window.
>
> The code I've got at the minute, only works if the file your trying to
> annotate had changes in the most recent commit, this is using
> annotate._annotate_file, eg
>
> annotate_file =
> os.environ['TM_FILEPATH'].lstrip(os.environ['TM_PROJECT_DIRECTORY'])
> tree, relpath = workingtree.WorkingTree.open_containing(annotate_file)
> b = tree.branch
> revid = b.last_revision()
> fileid = tree.path2id(annotate_file)
> annotation = annotate._annotate_file(b, revid, fileid)
>
> for (revno_str, author, date_str, line_rev_id, text) in annotation :
> print "%s: %s<br />" % ( revno_str, text )
>
> the other approach I've been playing with is below, using
> workingtree.annotate_iter
>
> tree, relpath = workingtree.WorkingTree.open_containing('filea.txt')
> fileid = tree.path2id('filea.txt')
> annotation = tree.annotate_iter(fileid)
"annotate_iter()" is the preferred api, as it will also show you which lines
have been modified from the last commit. (I believe annotate._annotate_file()
annotates the last committed version.)
>
> for (revno_str, text) in annotation :
> print "%s: %s<br />" % ( revno_str, text )
>
>
> This seems more reliable but only gives a long string containing what
> I presume is a unique identified for the file. Is there anyway to get
> author and rev no information from this identifier? Or is there an
> alternative approach I should be using.
>
> Thanks
>
> jebw
>
>
I don't believe it is a 'revno_str' it is a 'revision_id'. Which you can pass into:
rev = tree.branch.repository.get_revision(revision_id)
Which will give you things like
rev.committer
rev.timestamp
rev.timezone
rev.message
etc.
However, it isn't a particularly cheap call, so you probably want to save them
in a cache, and maybe even pull them in ahead of time. For example:
tree, relpath = workingtree.WorkingTree.open_containing('filea.txt')
fileid = tree.path2id('filea.txt')
annotation = list(tree.annotate_iter(fileid))
revision_ids = set(revision_id for revision_id, text in annotation)
revisions = tree.branch.repository.get_revisions(revision_ids)
revision_map = dict(izip(revision_ids, revisions))
revno_map = tree.branch.get_revision_id_to_revno_map()
for revision_id, text in annotation:
rev = revision_map[revision_id]
revno = revno_map[revision_id]
# What would you like to do now?
print "%s, %s: %s<br />" % (rev.committer, revno, text)
Also, you'll probably want to make sure you wrap the whole thing in a:
tree.lock_read()
try:
... # Do stuff
finally:
tree.unlock()
We only cache data in memory for the length of a lock, so holding a lock will
allow us to not have to re-read indexes, etc.
John
=:->
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (Darwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iD8DBQFHTyDZJdeBCYSNAAMRAm/pAKCnsR6ZxQJMdHINQNX9z5Sed2UnygCdEjDV
sDBz3Xw9oyodSyqQBAMUetA=
=Pi/I
-----END PGP SIGNATURE-----
More information about the bazaar
mailing list