Rev 5001: (vila) Fix ``log`` to better check ancestors even if merged revisions in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Wed Feb 3 09:35:25 GMT 2010


At file:///home/pqm/archives/thelove/bzr/%2Btrunk/

------------------------------------------------------------
revno: 5001 [merge]
revision-id: pqm at pqm.ubuntu.com-20100203093522-2j28jn5huknayntu
parent: pqm at pqm.ubuntu.com-20100203090438-2qn9wus9kyyfyyek
parent: v.ladeuil+lp at free.fr-20100203083959-ui4gyv58r5eyqh3l
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Wed 2010-02-03 09:35:22 +0000
message:
  (vila) Fix ``log`` to better check ancestors even if merged revisions
  	are involved
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/log.py                  log.py-20050505065812-c40ce11702fe5fb1
  bzrlib/tests/blackbox/test_log.py test_log.py-20060112090212-78f6ea560c868e24
=== modified file 'NEWS'
--- a/NEWS	2010-02-03 08:32:14 +0000
+++ b/NEWS	2010-02-03 09:35:22 +0000
@@ -31,6 +31,9 @@
 * Fix "AttributeError in Inter1and2Helper" during fetch.
   (Martin Pool, #513432)
 
+* Fix ``log`` to better check ancestors even if merged revisions are involved.
+  (Vincent Ladeuil, #476293)
+
 * Set the mtime of files exported to a directory by ``bzr export`` all to
   the same value to avoid confusing ``make`` and other date-based build
   systems. (Robert Collins, #515631)

=== modified file 'bzrlib/log.py'
--- a/bzrlib/log.py	2010-01-23 11:37:40 +0000
+++ b/bzrlib/log.py	2010-02-03 08:17:04 +0000
@@ -534,16 +534,30 @@
 
 
 def _generate_all_revisions(branch, start_rev_id, end_rev_id, direction,
-    delayed_graph_generation):
+                            delayed_graph_generation):
     # On large trees, generating the merge graph can take 30-60 seconds
     # so we delay doing it until a merge is detected, incrementally
     # returning initial (non-merge) revisions while we can.
+
+    # The above is only true for old formats (<= 0.92), for newer formats, a
+    # couple of seconds only should be needed to load the whole graph and the
+    # other graph operations needed are even faster than that -- vila 100201
     initial_revisions = []
     if delayed_graph_generation:
         try:
-            for rev_id, revno, depth in \
-                _linear_view_revisions(branch, start_rev_id, end_rev_id):
+            for rev_id, revno, depth in  _linear_view_revisions(
+                branch, start_rev_id, end_rev_id):
                 if _has_merges(branch, rev_id):
+                    # The end_rev_id can be nested down somewhere. We need an
+                    # explicit ancestry check. There is an ambiguity here as we
+                    # may not raise _StartNotLinearAncestor for a revision that
+                    # is an ancestor but not a *linear* one. But since we have
+                    # loaded the graph to do the check (or calculate a dotted
+                    # revno), we may as well accept to show the log... 
+                    # -- vila 100201
+                    graph = branch.repository.get_graph()
+                    if not graph.is_ancestor(start_rev_id, end_rev_id):
+                        raise _StartNotLinearAncestor()
                     end_rev_id = rev_id
                     break
                 else:

=== modified file 'bzrlib/tests/blackbox/test_log.py'
--- a/bzrlib/tests/blackbox/test_log.py	2010-01-25 17:48:22 +0000
+++ b/bzrlib/tests/blackbox/test_log.py	2010-02-03 08:17:04 +0000
@@ -23,6 +23,7 @@
 
 from bzrlib import (
     branchbuilder,
+    errors,
     log,
     osutils,
     tests,
@@ -158,10 +159,10 @@
         self.assertLogRevnos(['-c1'], ['1'])
 
 
-class TestBug474807(TestLogWithLogCatcher):
+class TestLogMergedLinearAncestry(TestLogWithLogCatcher):
 
     def setUp(self):
-        super(TestBug474807, self).setUp()
+        super(TestLogMergedLinearAncestry, self).setUp()
         # FIXME: Using a MemoryTree would be even better here (but until we
         # stop calling run_bzr, there is no point) --vila 100118.
         builder = branchbuilder.BranchBuilder(self.get_transport())
@@ -202,6 +203,49 @@
                              ['1.1.1', '1.1.2', '1.1.3', '1.1.4'])
 
 
+class Test_GenerateAllRevisions(TestLogWithLogCatcher):
+
+    def make_branch_with_many_merges(self, path='.', format=None):
+        builder = branchbuilder.BranchBuilder(self.get_transport())
+        builder.start_series()
+        # The graph below may look a bit complicated (and it may be but I've
+        # banged my head enough on it) but the bug requires at least dotted
+        # revnos *and* merged revisions below that.
+        builder.build_snapshot('1', None, [
+            ('add', ('', 'root-id', 'directory', ''))])
+        builder.build_snapshot('2', ['1'], [])
+        builder.build_snapshot('1.1.1', ['1'], [])
+        builder.build_snapshot('2.1.1', ['2'], [])
+        builder.build_snapshot('3', ['2', '1.1.1'], [])
+        builder.build_snapshot('2.1.2', ['2.1.1'], [])
+        builder.build_snapshot('2.2.1', ['2.1.1'], [])
+        builder.build_snapshot('2.1.3', ['2.1.2', '2.2.1'], [])
+        builder.build_snapshot('4', ['3', '2.1.3'], [])
+        builder.build_snapshot('5', ['4', '2.1.2'], [])
+        builder.finish_series()
+        return builder
+
+    def test_not_an_ancestor(self):
+        builder = self.make_branch_with_many_merges()
+        b = builder.get_branch()
+        b.lock_read()
+        self.addCleanup(b.unlock)
+        self.assertRaises(errors.BzrCommandError,
+                          log._generate_all_revisions,
+                          b, '1.1.1', '2.1.3', 'reverse',
+                          delayed_graph_generation=True)
+
+    def test_wrong_order(self):
+        builder = self.make_branch_with_many_merges()
+        b = builder.get_branch()
+        b.lock_read()
+        self.addCleanup(b.unlock)
+        self.assertRaises(errors.BzrCommandError,
+                          log._generate_all_revisions,
+                          b, '5', '2.1.3', 'reverse',
+                          delayed_graph_generation=True)
+
+
 class TestLogRevSpecsWithPaths(TestLogWithLogCatcher):
 
     def test_log_revno_n_path_wrong_namespace(self):
@@ -210,7 +254,6 @@
         # There is no guarantee that a path exist between two arbitrary
         # revisions.
         self.run_bzr("log -r revno:2:branch1..revno:3:branch2", retcode=3)
-        # But may be it's worth trying though ? -- vila 100115
 
     def test_log_revno_n_path_correct_order(self):
         self.make_linear_branch('branch2')




More information about the bazaar-commits mailing list