UPDATE: I seem to have done a far better job of explaining this here http://bazaar-vcs.org/Integrating_with_Bazaar
This is a brief explanation of how to implement Annotate support if software writing against the bzrlib library. Annotate support is useful because its a good demo of finding information held within the repositories history - for each line in a given file find out which commit it was added/last edited in, and then fetch the information for that commit.
First we grab a ‘handle’ to the file we’re interested in, and the working tree containing it.
tree, relpath = workingtree.WorkingTree.open_containing('/path/to/my/file.txt')
fileid = tree.path2id(relpath)
we then need an annotation iterator which allows us to walk the lines of the file, finding information as we go
annotation = list(tree.annotate_iter(fileid))
we then need to retrieve all the revision ids within the file and their associate revisions
revision_ids = set(revision_id for revision_id, text in annotation)
revisions = tree.branch.repository.get_revisions(revision_ids)
To avoid repeatedly reloading the same revision information over and over, we preload the revision information associated with the revisions we’ve already retrieved.
revision_map = dict(izip(revision_ids, revisions))
revno_map = tree.branch.get_revision_id_to_revno_map()
We can then walk over the lines of our file, using the annotation iterator we generated earlier
for revision_id, text in annotation :
rev = revision_map[revision_id]
revno = revno_map[revision_id]
print "%s, %s: %s" % (revno, rev.committer, text)
One point to note is revno actually contains a tuple with a single value, hence the ‘revno’. I’m not sure why this is tuple and if there are actually situations where it might return more than one value.