Rev 5767: (spiv) log no longer raises NoSuchRevision against revisions in the in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Fri Apr 8 05:16:34 UTC 2011


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

------------------------------------------------------------
revno: 5767 [merge]
revision-id: pqm at pqm.ubuntu.com-20110408051630-wlk2z0cv73walyz0
parent: pqm at pqm.ubuntu.com-20110407120406-74kdkstr862qm9cv
parent: andrew.bennetts at canonical.com-20110408034734-7d9bdoiw1h9zegci
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Fri 2011-04-08 05:16:30 +0000
message:
  (spiv) log no longer raises NoSuchRevision against revisions in the
   repository which are not in the current branch (#241998). Such revisions
   have no revno,
   so display the revision-id instead. It is now possible for a LogRevision to
   have a revno of None. (Matt Giuca) (Andrew Bennetts)
modified:
  bzrlib/log.py                  log.py-20050505065812-c40ce11702fe5fb1
  bzrlib/tests/test_log.py       testlog.py-20050728115707-1a514809d7d49309
  doc/en/release-notes/bzr-2.4.txt bzr2.4.txt-20110114053217-k7ym9jfz243fddjm-1
=== modified file 'bzrlib/log.py'
--- a/bzrlib/log.py	2011-04-07 10:36:24 +0000
+++ b/bzrlib/log.py	2011-04-08 03:31:54 +0000
@@ -539,8 +539,7 @@
         # It's the tip
         return [(br_rev_id, br_revno, 0)]
     else:
-        revno = branch.revision_id_to_dotted_revno(rev_id)
-        revno_str = '.'.join(str(n) for n in revno)
+        revno_str = _compute_revno_str(branch, rev_id)
         return [(rev_id, revno_str, 0)]
 
 
@@ -626,11 +625,30 @@
     return len(parents) > 1
 
 
+def _compute_revno_str(branch, rev_id):
+    """Compute the revno string from a rev_id.
+
+    :return: The revno string, or None if the revision is not in the supplied
+        branch.
+    """
+    try:
+        revno = branch.revision_id_to_dotted_revno(rev_id)
+    except errors.NoSuchRevision:
+        # The revision must be outside of this branch
+        return None
+    else:
+        return '.'.join(str(n) for n in revno)
+
+
 def _is_obvious_ancestor(branch, start_rev_id, end_rev_id):
     """Is start_rev_id an obvious ancestor of end_rev_id?"""
     if start_rev_id and end_rev_id:
-        start_dotted = branch.revision_id_to_dotted_revno(start_rev_id)
-        end_dotted = branch.revision_id_to_dotted_revno(end_rev_id)
+        try:
+            start_dotted = branch.revision_id_to_dotted_revno(start_rev_id)
+            end_dotted = branch.revision_id_to_dotted_revno(end_rev_id)
+        except errors.NoSuchRevision:
+            # one or both is not in the branch; not obvious
+            return False
         if len(start_dotted) == 1 and len(end_dotted) == 1:
             # both on mainline
             return start_dotted[0] <= end_dotted[0]
@@ -670,8 +688,7 @@
             end_rev_id = br_rev_id
         found_start = start_rev_id is None
         for revision_id in repo.iter_reverse_revision_history(end_rev_id):
-            revno = branch.revision_id_to_dotted_revno(revision_id)
-            revno_str = '.'.join(str(n) for n in revno)
+            revno_str = _compute_revno_str(branch, revision_id)
             if not found_start and revision_id == start_rev_id:
                 if not exclude_common_ancestry:
                     yield revision_id, revno_str, 0
@@ -1299,7 +1316,10 @@
     def __init__(self, rev=None, revno=None, merge_depth=0, delta=None,
                  tags=None, diff=None):
         self.rev = rev
-        self.revno = str(revno)
+        if revno is None:
+            self.revno = None
+        else:
+            self.revno = str(revno)
         self.merge_depth = merge_depth
         self.delta = delta
         self.tags = tags
@@ -1556,8 +1576,9 @@
                 self.merge_marker(revision)))
         if revision.tags:
             lines.append('tags: %s' % (', '.join(revision.tags)))
-        if self.show_ids:
+        if self.show_ids or revision.revno is None:
             lines.append('revision-id: %s' % (revision.rev.revision_id,))
+        if self.show_ids:
             for parent_id in revision.rev.parent_ids:
                 lines.append('parent: %s' % (parent_id,))
         lines.extend(self.custom_properties(revision.rev))
@@ -1626,7 +1647,7 @@
         indent = '    ' * depth
         revno_width = self.revno_width_by_depth.get(depth)
         if revno_width is None:
-            if revision.revno.find('.') == -1:
+            if revision.revno is None or revision.revno.find('.') == -1:
                 # mainline revno, e.g. 12345
                 revno_width = 5
             else:
@@ -1640,14 +1661,14 @@
         if revision.tags:
             tags = ' {%s}' % (', '.join(revision.tags))
         to_file.write(indent + "%*s %s\t%s%s%s\n" % (revno_width,
-                revision.revno, self.short_author(revision.rev),
+                revision.revno or "", self.short_author(revision.rev),
                 format_date(revision.rev.timestamp,
                             revision.rev.timezone or 0,
                             self.show_timezone, date_fmt="%Y-%m-%d",
                             show_offset=False),
                 tags, self.merge_marker(revision)))
         self.show_properties(revision.rev, indent+offset)
-        if self.show_ids:
+        if self.show_ids or revision.revno is None:
             to_file.write(indent + offset + 'revision-id:%s\n'
                           % (revision.rev.revision_id,))
         if not revision.rev.message:

=== modified file 'bzrlib/tests/test_log.py'
--- a/bzrlib/tests/test_log.py	2011-03-23 10:34:54 +0000
+++ b/bzrlib/tests/test_log.py	2011-04-08 03:47:34 +0000
@@ -1531,6 +1531,124 @@
         self.assertNotContainsRe(s.getvalue(), 'Added Revisions:')
 
 
+class TestRevisionNotInBranch(TestCaseForLogFormatter):
+
+    def setup_a_tree(self):
+        tree = self.make_branch_and_tree('tree')
+        tree.lock_write()
+        self.addCleanup(tree.unlock)
+        kwargs = {
+            'committer': 'Joe Foo <joe at foo.com>',
+            'timestamp': 1132617600, # Mon 2005-11-22 00:00:00 +0000
+            'timezone': 0, # UTC
+        }
+        tree.commit('commit 1a', rev_id='1a', **kwargs)
+        tree.commit('commit 2a', rev_id='2a', **kwargs)
+        tree.commit('commit 3a', rev_id='3a', **kwargs)
+        return tree
+
+    def setup_ab_tree(self):
+        tree = self.setup_a_tree()
+        tree.set_last_revision('1a')
+        tree.branch.set_last_revision_info(1, '1a')
+        kwargs = {
+            'committer': 'Joe Foo <joe at foo.com>',
+            'timestamp': 1132617600, # Mon 2005-11-22 00:00:00 +0000
+            'timezone': 0, # UTC
+        }
+        tree.commit('commit 2b', rev_id='2b', **kwargs)
+        tree.commit('commit 3b', rev_id='3b', **kwargs)
+        return tree
+
+    def test_one_revision(self):
+        tree = self.setup_ab_tree()
+        lf = LogCatcher()
+        rev = revisionspec.RevisionInfo(tree.branch, None, '3a')
+        log.show_log(tree.branch, lf, verbose=True, start_revision=rev,
+                     end_revision=rev)
+        self.assertEqual(1, len(lf.revisions))
+        self.assertEqual(None, lf.revisions[0].revno)   # Out-of-branch
+        self.assertEqual('3a', lf.revisions[0].rev.revision_id)
+
+    def test_many_revisions(self):
+        tree = self.setup_ab_tree()
+        lf = LogCatcher()
+        start_rev = revisionspec.RevisionInfo(tree.branch, None, '1a')
+        end_rev = revisionspec.RevisionInfo(tree.branch, None, '3a')
+        log.show_log(tree.branch, lf, verbose=True, start_revision=start_rev,
+                     end_revision=end_rev)
+        self.assertEqual(3, len(lf.revisions))
+        self.assertEqual(None, lf.revisions[0].revno)   # Out-of-branch
+        self.assertEqual('3a', lf.revisions[0].rev.revision_id)
+        self.assertEqual(None, lf.revisions[1].revno)   # Out-of-branch
+        self.assertEqual('2a', lf.revisions[1].rev.revision_id)
+        self.assertEqual('1', lf.revisions[2].revno)    # In-branch
+
+    def test_long_format(self):
+        tree = self.setup_ab_tree()
+        start_rev = revisionspec.RevisionInfo(tree.branch, None, '1a')
+        end_rev = revisionspec.RevisionInfo(tree.branch, None, '3a')
+        self.assertFormatterResult("""\
+------------------------------------------------------------
+revision-id: 3a
+committer: Joe Foo <joe at foo.com>
+branch nick: tree
+timestamp: Tue 2005-11-22 00:00:00 +0000
+message:
+  commit 3a
+------------------------------------------------------------
+revision-id: 2a
+committer: Joe Foo <joe at foo.com>
+branch nick: tree
+timestamp: Tue 2005-11-22 00:00:00 +0000
+message:
+  commit 2a
+------------------------------------------------------------
+revno: 1
+committer: Joe Foo <joe at foo.com>
+branch nick: tree
+timestamp: Tue 2005-11-22 00:00:00 +0000
+message:
+  commit 1a
+""",
+            tree.branch, log.LongLogFormatter, show_log_kwargs={
+                'start_revision': start_rev, 'end_revision': end_rev
+            })
+
+    def test_short_format(self):
+        tree = self.setup_ab_tree()
+        start_rev = revisionspec.RevisionInfo(tree.branch, None, '1a')
+        end_rev = revisionspec.RevisionInfo(tree.branch, None, '3a')
+        self.assertFormatterResult("""\
+      Joe Foo\t2005-11-22
+      revision-id:3a
+      commit 3a
+
+      Joe Foo\t2005-11-22
+      revision-id:2a
+      commit 2a
+
+    1 Joe Foo\t2005-11-22
+      commit 1a
+
+""",
+            tree.branch, log.ShortLogFormatter, show_log_kwargs={
+                'start_revision': start_rev, 'end_revision': end_rev
+            })
+
+    def test_line_format(self):
+        tree = self.setup_ab_tree()
+        start_rev = revisionspec.RevisionInfo(tree.branch, None, '1a')
+        end_rev = revisionspec.RevisionInfo(tree.branch, None, '3a')
+        self.assertFormatterResult("""\
+Joe Foo 2005-11-22 commit 3a
+Joe Foo 2005-11-22 commit 2a
+1: Joe Foo 2005-11-22 commit 1a
+""",
+            tree.branch, log.LineLogFormatter, show_log_kwargs={
+                'start_revision': start_rev, 'end_revision': end_rev
+            })
+
 
 class TestLogWithBugs(TestCaseForLogFormatter, TestLogMixin):
 

=== modified file 'doc/en/release-notes/bzr-2.4.txt'
--- a/doc/en/release-notes/bzr-2.4.txt	2011-04-07 10:36:24 +0000
+++ b/doc/en/release-notes/bzr-2.4.txt	2011-04-08 03:31:54 +0000
@@ -47,6 +47,9 @@
   these default values aren't relied on very often so this probably
   wasn't causing any trouble.  (Andrew Bennetts)
 
+* ``bzr log`` now works on revisions which are not in the current branch.
+  (Matt Giuca, #241998)
+
 * Lazy hooks are now reset between test runs. (Jelmer Vernooij, #745566)
 
 * Standalone bzr.exe installation on Windows: user can put additional python 
@@ -83,6 +86,10 @@
 
 * New method ``Hooks.uninstall_named_hook``. (Jelmer Vernooij, #301472)
 
+* The ``revno`` parameter of ``log.LogRevision`` may now be None,
+  representing a revision which is not in the current branch.
+  (Matt Giuca, #241998)
+
 Internals
 *********
 




More information about the bazaar-commits mailing list