Rev 120: A new revision specifier ``below:`` has been added. (Robert Collins, #195282) in http://bazaar.launchpad.net/~bzr-loom-devs/bzr-loom/trunk/

Robert Collins robertc at robertcollins.net
Thu Jul 1 05:18:19 BST 2010


At http://bazaar.launchpad.net/~bzr-loom-devs/bzr-loom/trunk/

------------------------------------------------------------
revno: 120
revision-id: robertc at robertcollins.net-20100701041808-swb8fvzbh2d1aj74
parent: robertc at robertcollins.net-20100630015611-3442pf2uf5ogrk5k
fixes bug(s): https://launchpad.net/bugs/231283 https://launchpad.net/bugs/195282
committer: Robert Collins <robertc at robertcollins.net>
branch nick: trunk
timestamp: Thu 2010-07-01 14:18:08 +1000
message:
  A new revision specifier ``below:`` has been added. (Robert Collins, #195282)
  
  The ``thread:`` revision specifier will no longer throw an attribute error
  when used on a normal branch. (Robert Collins, #231283)
=== modified file 'HOWTO'
--- a/HOWTO	2008-02-21 19:25:46 +0000
+++ b/HOWTO	2010-07-01 04:18:08 +0000
@@ -177,7 +177,7 @@
 When you are doing an update to upstream and they have merged a patch, your
 thread will suddenly lose all its changes. Lets say in the example above that
 upstream have merged the autoconf update. When you are updating that thread,
-add in a call to ``diff -r thread:`` and you will see no changes.
+add in a call to ``diff -r below:`` and you will see no changes.
 
     % bzr up-thread
     All changes applied successfully.
@@ -201,3 +201,16 @@
       debian
     =>fix 64-bit compilation
       upstream
+
+
+Showing a single patch
+----------------------
+
+You can show a single patch without knowing the names of other threads by using
+the below: and thread: revision specifiers::
+
+    % bzr show-loom
+      debian
+    =>update-configure
+      upstream
+    % bzr diff -r below:update-configure..thread:update-configure

=== modified file 'NEWS'
--- a/NEWS	2010-06-29 07:25:49 +0000
+++ b/NEWS	2010-07-01 04:18:08 +0000
@@ -26,6 +26,8 @@
 FEATURES
 --------
 
+* A new revision specifier ``below:`` has been added. (Robert Collins, #195282)
+
 IMPROVEMENTS
 ------------
 
@@ -42,6 +44,9 @@
 
 * ``switch`` now accepts the ``--directory`` option. (Vincent Ladeuil, #595563)
 
+* The ``thread:`` revision specifier will no longer throw an attribute error
+  when used on a normal branch. (Robert Collins, #231283)
+
 API BREAKS
 ----------
 

=== modified file 'README'
--- a/README	2008-03-26 00:59:57 +0000
+++ b/README	2010-07-01 04:18:08 +0000
@@ -77,9 +77,11 @@
 branch will pull into the current thread of a loom. This assymetry makes it easy
 to work with developers who are not using looms.
 
-Loom also adds a new revision specifier 'thread:'. You can use this to diff
-against threads in the current loom. For example: 'bzr diff -r thread:' will
-show you the difference between the current thread and the thread below it.
+Loom also adds new revision specifiers 'thread:' and 'below:'. You can use these
+to diff against threads in the current Loom. For instance, 'bzr diff -r
+thread:' will show you the different between the thread below yours, and your
+thread. See ``bzr help revisionspec`` for the detailed help on these two
+revision specifiers.
 
 
 Documentation

=== modified file '__init__.py'
--- a/__init__.py	2010-06-30 01:56:11 +0000
+++ b/__init__.py	2010-07-01 04:18:08 +0000
@@ -48,9 +48,11 @@
    to remove a thread which has been merged into upstream. 
 
 
-Loom also adds a new revision specifier 'thread:'. You can use this to diff
-against threads in the current Loom. For instance, 'bzr diff -r thread:' will
-show you the different between the thread below yours, and your thread.
+Loom also adds new revision specifiers 'thread:' and 'below:'. You can use these
+to diff against threads in the current Loom. For instance, 'bzr diff -r
+thread:' will show you the different between the thread below yours, and your
+thread. See ``bzr help revisionspec`` for the detailed help on these two
+revision specifiers.
 """
 
 from version import bzr_plugin_version as version_info
@@ -94,9 +96,12 @@
 if revspec_registry is not None:
     revspec_registry.register_lazy('thread:', 'bzrlib.plugins.loom.revspec',
                                    'RevisionSpecThread')
+    revspec_registry.register_lazy('below:', 'bzrlib.plugins.loom.revspec',
+                                   'RevisionSpecBelow')
 else:
     import revspec
     bzrlib.revisionspec.SPEC_TYPES.append(revspec.RevisionSpecThread)
+    bzrlib.revisionspec.SPEC_TYPES.append(revspec.RevisionSpecBelow)
 
 #register loom formats
 formats.register_formats()

=== modified file 'revspec.py'
--- a/revspec.py	2009-02-12 13:15:03 +0000
+++ b/revspec.py	2010-07-01 04:18:08 +0000
@@ -19,46 +19,86 @@
 
 
 from bzrlib.plugins.loom.branch import NoLowerThread
+from bzrlib.plugins.loom.formats import require_loom_branch
 from bzrlib.revisionspec import RevisionSpec, RevisionInfo
 
 
-class RevisionSpecThread(RevisionSpec):
-    """The thread: revision specifier."""
-
-    help_txt = """Selects the tip of a revision from a loom.
-
-    Selects the tip of a thread in a loom.  
-
-    Examples::
-
-      thread:                   -> return the tip of the next lower thread.
-      thread:foo                -> return the tip of the thread named 'foo'
-
-    see also: loom
-    """
-
-    prefix = 'thread:'
+class LoomRevisionSpec(RevisionSpec):
+    """A revision spec that needs a loom."""
 
     def _match_on(self, branch, revs):
          return RevisionInfo(branch, None, self._as_revision_id(branch))
 
     def _as_revision_id(self, branch):
-        # '' -> next lower
-        # foo -> named
+        require_loom_branch(branch)
         branch.lock_read()
         try:
             state = branch.get_loom_state()
             threads = state.get_threads()
-            if len(self.spec):
-                index = state.thread_index(self.spec)
-            else:
-                current_thread = branch.nick
-                index = state.thread_index(current_thread) - 1
-                if index < 0:
-                    raise NoLowerThread()
-            return threads[index][1]
+            return self._as_thread_revision_id(branch, state, threads)
         finally:
             branch.unlock()
 
 
+class RevisionSpecBelow(LoomRevisionSpec):
+    """The below: revision specifier."""
+
+    help_txt = """Selects the tip of the thread below a thread from a loom.
+
+    Selects the tip of the thread below a thread in a loom.  
+
+    Examples::
+
+      below:                   -> return the tip of the next lower thread.
+      below:foo                -> return the tip of the thread under the one
+                                  named 'foo'
+
+    see also: loom, the thread: revision specifier
+    """
+
+    prefix = 'below:'
+
+    def _as_thread_revision_id(self, branch, state, threads):
+        # '' -> next lower
+        # foo -> thread under foo
+        if len(self.spec):
+            index = state.thread_index(self.spec)
+        else:
+            current_thread = branch.nick
+            index = state.thread_index(current_thread)
+        if index < 1:
+            raise NoLowerThread()
+        return threads[index - 1][1]
+
+
+class RevisionSpecThread(LoomRevisionSpec):
+    """The thread: revision specifier."""
+
+    help_txt = """Selects the tip of a thread from a loom.
+
+    Selects the tip of a thread in a loom.  
+
+    Examples::
+
+      thread:                   -> return the tip of the next lower thread.
+      thread:foo                -> return the tip of the thread named 'foo'
+
+    see also: loom, the below: revision specifier
+    """
+
+    prefix = 'thread:'
+
+    def _as_thread_revision_id(self, branch, state, threads):
+        # '' -> next lower
+        # foo -> named
+        if len(self.spec):
+            index = state.thread_index(self.spec)
+        else:
+            current_thread = branch.nick
+            index = state.thread_index(current_thread) - 1
+            if index < 0:
+                raise NoLowerThread()
+        return threads[index][1]
+
+
 

=== modified file 'tests/test_revspec.py'
--- a/tests/test_revspec.py	2008-04-24 19:24:24 +0000
+++ b/tests/test_revspec.py	2010-07-01 04:18:08 +0000
@@ -19,16 +19,15 @@
 """Tests of the loom revision-specifiers."""
 
 
-import bzrlib
+import bzrlib.errors
 from bzrlib.plugins.loom.branch import NoLowerThread, NoSuchThread
 from bzrlib.plugins.loom.tests import TestCaseWithLoom
 import bzrlib.plugins.loom.tree
 from bzrlib.revisionspec import RevisionSpec
 
 
-class TestThreadRevSpec(TestCaseWithLoom):
-    """Tests of the ThreadRevisionSpecifier."""
-    
+class TestRevSpec(TestCaseWithLoom):
+
     def get_two_thread_loom(self):
         tree = self.get_tree_with_loom('source')
         tree.branch.new_thread('bottom')
@@ -39,6 +38,10 @@
         loom_tree.up_thread()
         rev_id_top = tree.commit('change top')
         return tree, loom_tree, rev_id_bottom, rev_id_top
+
+
+class TestThreadRevSpec(TestRevSpec):
+    """Tests of the ThreadRevisionSpecifier."""
     
     def test_thread_colon_at_bottom_errors(self):
         tree, loom_tree, rev_id, _ = self.get_two_thread_loom()
@@ -69,3 +72,44 @@
         loom_tree.down_thread()
         spec = RevisionSpec.from_string('thread:top')
         self.assertEqual(rev_id, spec.as_revision_id(tree.branch))
+
+    def test_thread_on_non_loom_gives_BzrError(self):
+        tree = self.make_branch_and_tree('.')
+        spec = RevisionSpec.from_string('thread:')
+        err = self.assertRaises(bzrlib.errors.BzrError, spec.as_revision_id,
+            tree.branch)
+        self.assertFalse(err.internal_error)
+
+
+class TestBelowRevSpec(TestRevSpec):
+    """Tests of the below: revision specifier."""
+
+    def test_below_gets_tip_of_thread_below(self):
+        tree, loom_tree, _, rev_id = self.get_two_thread_loom()
+        loom_tree.down_thread()
+        expected_id = tree.branch.last_revision()
+        loom_tree.up_thread()
+        spec = RevisionSpec.from_string('below:')
+        self.assertEqual(expected_id, spec.as_revision_id(tree.branch))
+
+    def test_below_on_bottom_thread_gives_BzrError(self):
+        tree, loom_tree, _, rev_id = self.get_two_thread_loom()
+        loom_tree.down_thread()
+        spec = RevisionSpec.from_string('below:')
+        err = self.assertRaises(bzrlib.errors.BzrError, spec.as_revision_id,
+            tree.branch)
+        self.assertFalse(err.internal_error)
+
+    def test_below_named_thread(self):
+        tree, loom_tree, _, rev_id = self.get_two_thread_loom()
+        loom_tree.down_thread()
+        expected_id = tree.branch.last_revision()
+        spec = RevisionSpec.from_string('below:top')
+        self.assertEqual(expected_id, spec.as_revision_id(tree.branch))
+
+    def test_below_on_non_loom_gives_BzrError(self):
+        tree = self.make_branch_and_tree('.')
+        spec = RevisionSpec.from_string('below:')
+        err = self.assertRaises(bzrlib.errors.BzrError, spec.as_revision_id,
+            tree.branch)
+        self.assertFalse(err.internal_error)




More information about the bazaar-commits mailing list