def do_readlocked_repository_request(self, repository, revision_id): """Return the result of repository.get_revision_graph(revision_id). Deprecated as of bzr 1.4, but supported for older clients. :param repository: The repository to query in. :param revision_id: The utf8 encoded revision_id to get a graph from. :return: A smart server response where the body contains an utf8 encoded flattened list of the revision graph. """ if not revision_id: revision_id = None lines = [] graph = repository.get_graph() if revision_id: search_ids = [revision_id] else: search_ids = repository.all_revision_ids() search = graph._make_breadth_first_searcher(search_ids) transitive_ids = set() map(transitive_ids.update, list(search)) parent_map = graph.get_parent_map(transitive_ids) revision_graph = _strip_NULL_ghosts(parent_map) if revision_id and revision_id not in revision_graph: # Note that we return an empty body, rather than omitting the body. # This way the client knows that it can always expect to find a body # in the response for this method, even in the error case. return FailedSmartServerResponse(('nosuchrevision', revision_id), '') for revision, parents in revision_graph.items(): lines.append(' '.join((revision, ) + tuple(parents))) return SuccessfulSmartServerResponse(('ok', ), '\n'.join(lines))
def _expand_annotations(annotations, branch, current_rev=None): """Expand a file's annotations into command line UI ready tuples. Each tuple includes detailed information, such as the author name, and date string for the commit, rather than just the revision id. :param annotations: The annotations to expand. :param revision_id_to_revno: A map from id to revision numbers. :param branch: A locked branch to query for revision details. """ repository = branch.repository if current_rev is not None: # This can probably become a function on MutableTree, get_revno_map # there, or something. last_revision = current_rev.revision_id # XXX: Partially Cloned from branch, uses the old_get_graph, eep. # XXX: The main difficulty is that we need to inject a single new node # (current_rev) into the graph before it gets numbered, etc. # Once KnownGraph gets an 'add_node()' function, we can use # VF.get_known_graph_ancestry(). graph = repository.get_graph() revision_graph = dict(((key, value) for key, value in graph.iter_ancestry(current_rev.parent_ids) if value is not None)) revision_graph = _strip_NULL_ghosts(revision_graph) revision_graph[last_revision] = current_rev.parent_ids merge_sorted_revisions = tsort.merge_sort( revision_graph, last_revision, None, generate_revno=True) revision_id_to_revno = dict((rev_id, revno) for seq_num, rev_id, depth, revno, end_of_merge in merge_sorted_revisions) else: revision_id_to_revno = branch.get_revision_id_to_revno_map() last_origin = None revision_ids = set(o for o, t in annotations) revisions = {} if CURRENT_REVISION in revision_ids: revision_id_to_revno[CURRENT_REVISION] = ( "%d?" % (branch.revno() + 1),) revisions[CURRENT_REVISION] = current_rev revision_ids = [o for o in revision_ids if repository.has_revision(o)] revisions.update((r.revision_id, r) for r in repository.get_revisions(revision_ids)) for origin, text in annotations: text = text.rstrip('\r\n') if origin == last_origin: (revno_str, author, date_str) = ('','','') else: last_origin = origin if origin not in revisions: (revno_str, author, date_str) = ('?','?','?') else: revno_str = '.'.join(str(i) for i in revision_id_to_revno[origin]) rev = revisions[origin] tz = rev.timezone or 0 date_str = time.strftime('%Y%m%d', time.gmtime(rev.timestamp + tz)) # a lazy way to get something like the email address # TODO: Get real email address author = rev.get_apparent_authors()[0] try: author = extract_email_address(author) except errors.NoEmailInUsername: pass # use the whole name yield (revno_str, author, date_str, origin, text)
def _expand_annotations(annotations, branch, current_rev=None): """Expand a file's annotations into command line UI ready tuples. Each tuple includes detailed information, such as the author name, and date string for the commit, rather than just the revision id. :param annotations: The annotations to expand. :param revision_id_to_revno: A map from id to revision numbers. :param branch: A locked branch to query for revision details. """ repository = branch.repository if current_rev is not None: # This can probably become a function on MutableTree, get_revno_map # there, or something. last_revision = current_rev.revision_id # XXX: Partially Cloned from branch, uses the old_get_graph, eep. # XXX: The main difficulty is that we need to inject a single new node # (current_rev) into the graph before it gets numbered, etc. # Once KnownGraph gets an 'add_node()' function, we can use # VF.get_known_graph_ancestry(). graph = repository.get_graph() revision_graph = dict( ((key, value) for key, value in graph.iter_ancestry(current_rev.parent_ids) if value is not None)) revision_graph = _strip_NULL_ghosts(revision_graph) revision_graph[last_revision] = current_rev.parent_ids merge_sorted_revisions = tsort.merge_sort(revision_graph, last_revision, None, generate_revno=True) revision_id_to_revno = dict((rev_id, revno) for seq_num, rev_id, depth, revno, end_of_merge in merge_sorted_revisions) else: revision_id_to_revno = branch.get_revision_id_to_revno_map() last_origin = None revision_ids = set(o for o, t in annotations) revisions = {} if CURRENT_REVISION in revision_ids: revision_id_to_revno[CURRENT_REVISION] = ("%d?" % (branch.revno() + 1), ) revisions[CURRENT_REVISION] = current_rev revision_ids = [o for o in revision_ids if repository.has_revision(o)] revisions.update( (r.revision_id, r) for r in repository.get_revisions(revision_ids)) for origin, text in annotations: text = text.rstrip('\r\n') if origin == last_origin: (revno_str, author, date_str) = ('', '', '') else: last_origin = origin if origin not in revisions: (revno_str, author, date_str) = ('?', '?', '?') else: revno_str = '.'.join( str(i) for i in revision_id_to_revno[origin]) rev = revisions[origin] tz = rev.timezone or 0 date_str = time.strftime('%Y%m%d', osutils.gmtime(rev.timestamp + tz)) # a lazy way to get something like the email address # TODO: Get real email address author = rev.get_apparent_authors()[0] try: author = extract_email_address(author) except errors.NoEmailInUsername: pass # use the whole name yield (revno_str, author, date_str, origin, text)