Rev 6047: Fix loading branch history for each tag to make `bzr tags -rX..Y` faster in file:///home/vila/src/bzr/bugs/857335-tags-revs-slow-2.4/

Vincent Ladeuil v.ladeuil+lp at free.fr
Mon Sep 26 08:48:21 UTC 2011


At file:///home/vila/src/bzr/bugs/857335-tags-revs-slow-2.4/

------------------------------------------------------------
revno: 6047
revision-id: v.ladeuil+lp at free.fr-20110926084820-l7z71upgfj5bnan3
parent: pqm at pqm.ubuntu.com-20110912123520-avjojdd1q64hjxe3
committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
branch nick: 857335-tags-revs-slow-2.4
timestamp: Mon 2011-09-26 10:48:20 +0200
message:
  Fix loading branch history for each tag to make `bzr tags -rX..Y` faster
-------------- next part --------------
=== modified file 'bzrlib/builtins.py'
--- a/bzrlib/builtins.py	2011-08-30 10:45:40 +0000
+++ b/bzrlib/builtins.py	2011-09-26 08:48:20 +0000
@@ -5615,12 +5615,8 @@
 
         self.add_cleanup(branch.lock_read().unlock)
         if revision:
-            graph = branch.repository.get_graph()
-            rev1, rev2 = _get_revision_range(revision, branch, self.name())
-            revid1, revid2 = rev1.rev_id, rev2.rev_id
-            # only show revisions between revid1 and revid2 (inclusive)
-            tags = [(tag, revid) for tag, revid in tags if
-                graph.is_between(revid, revid1, revid2)]
+            # Restrict to the specified range
+            tags = self._tags_for_range(branch, revision)
         if sort is None:
             sort = tag_sort_methods.get()
         sort(branch, tags)
@@ -5640,6 +5636,32 @@
         for tag, revspec in tags:
             self.outf.write('%-20s %s\n' % (tag, revspec))
 
+    def _tags_for_range(self, branch, revision):
+        range_valid = True
+        rev1, rev2 = _get_revision_range(revision, branch, self.name())
+        revid1, revid2 = rev1.rev_id, rev2.rev_id
+        # _get_revision_range will always set revid2 if it's not specified.
+        # If revid1 is None, it means we want to start from the branch
+        # origin which is always a valid ancestor. If revid1 == revid2, the
+        # ancestry check is useless.
+        if revid1 and revid1 != revid2:
+            # FIXME: We really want to use the same graph than
+            # branch.iter_merge_sorted_revisions below, but this is not
+            # easily available -- vila 2011-09-23
+            if branch.repository.get_graph().is_ancestor(revid2, revid1):
+                # We don't want to output anything in this case...
+                return []
+        # only show revisions between revid1 and revid2 (inclusive)
+        tagged_revids = branch.tags.get_reverse_tag_dict()
+        found = []
+        for r in branch.iter_merge_sorted_revisions(
+            start_revision_id=revid2, stop_revision_id=revid1,
+            stop_rule='include'):
+            revid_tags = tagged_revids.get(r[0], None)
+            if revid_tags:
+                found.extend([(tag, r[0]) for tag in revid_tags])
+        return found
+
 
 class cmd_reconfigure(Command):
     __doc__ = """Reconfigure the type of a bzr directory.

=== modified file 'doc/en/release-notes/bzr-2.4.txt'
--- a/doc/en/release-notes/bzr-2.4.txt	2011-09-09 12:43:14 +0000
+++ b/doc/en/release-notes/bzr-2.4.txt	2011-09-26 08:48:20 +0000
@@ -26,6 +26,9 @@
 .. Improvements to existing commands, especially improved performance 
    or memory usage, or better results.
 
+* Fixed a bug where ``bzr tags -r x..y`` loaded the branch history once for
+  every revision in the range; it's now much faster. (Vincent Ladeuil, #857335)
+
 Bug Fixes
 *********
 



More information about the bazaar-commits mailing list