Rev 83: Merge numerous fixes from Aaron Bentley. in http://bazaar.launchpad.net/~bzr-loom-devs/bzr-loom/trunk/

Robert Collins robertc at robertcollins.net
Thu Jun 12 03:25:32 BST 2008


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

------------------------------------------------------------
revno: 83
revision-id: robertc at robertcollins.net-20080612022531-f6g0ieng6zmyz2ni
parent: robertc at robertcollins.net-20080415022706-ya0nnza5o71i13c1
parent: aaron at aaronbentley.com-20080523030433-nndfed93a46i23mm
committer: Robert Collins <robertc at robertcollins.net>
branch nick: trunk
timestamp: Thu 2008-06-12 12:25:31 +1000
message:
  Merge numerous fixes from Aaron Bentley.
modified:
  branch.py                      branch.py-20060620084702-jnrwijq76kg45klj-5
  commands.py                    commands.py-20060620084702-jnrwijq76kg45klj-6
  loom_state.py                  loom_state.py-20060707132826-p7h51ovrc4lqkxgq-1
  revspec.py                     revspec.py-20060721061235-iqvjh55zlksmv53u-1
  tests/blackbox.py              blackbox.py-20060620084702-jnrwijq76kg45klj-7
  tests/test_loom_state.py       test_loom_state.py-20060707132826-p7h51ovrc4lqkxgq-2
  tests/test_revspec.py          test_revspec.py-20060721061235-iqvjh55zlksmv53u-2
  tree.py                        tree.py-20060701085538-3ajq87mglfa5ryqa-1
    ------------------------------------------------------------
    revno: 81.2.7
    revision-id: aaron at aaronbentley.com-20080523030433-nndfed93a46i23mm
    parent: aaron at aaronbentley.com-20080425204918-w5plag480h6gm8a6
    committer: Aaron Bentley <aaron at aaronbentley.com>
    branch nick: loom
    timestamp: Thu 2008-05-22 23:04:33 -0400
    message:
      Fix deprecation warnings
    modified:
      branch.py                      branch.py-20060620084702-jnrwijq76kg45klj-5
    ------------------------------------------------------------
    revno: 81.2.6
    revision-id: aaron at aaronbentley.com-20080425204918-w5plag480h6gm8a6
    parent: aaron at aaronbentley.com-20080424192424-qj9uiuleb9aa08dt
    committer: Aaron Bentley <aaron at aaronbentley.com>
    branch nick: loom
    timestamp: Fri 2008-04-25 16:49:18 -0400
    message:
      Add --base option to loomify, to set the branch nick
    modified:
      commands.py                    commands.py-20060620084702-jnrwijq76kg45klj-6
      tests/blackbox.py              blackbox.py-20060620084702-jnrwijq76kg45klj-7
    ------------------------------------------------------------
    revno: 81.2.5
    revision-id: aaron at aaronbentley.com-20080424192424-qj9uiuleb9aa08dt
    parent: aaron at aaronbentley.com-20080424161351-r62d3kwug0lbsthz
    committer: Aaron Bentley <aaron at aaronbentley.com>
    branch nick: loom
    timestamp: Thu 2008-04-24 15:24:24 -0400
    message:
      Implement as_revision_id for thread revision spec
    modified:
      revspec.py                     revspec.py-20060721061235-iqvjh55zlksmv53u-1
      tests/test_revspec.py          test_revspec.py-20060721061235-iqvjh55zlksmv53u-2
    ------------------------------------------------------------
    revno: 81.2.4
    revision-id: aaron at aaronbentley.com-20080424161351-r62d3kwug0lbsthz
    parent: aaron at aaronbentley.com-20080424161306-097q2zh3qcppae92
    parent: robertc at robertcollins.net-20080415022706-ya0nnza5o71i13c1
    committer: Aaron Bentley <aaron at aaronbentley.com>
    branch nick: loom
    timestamp: Thu 2008-04-24 12:13:51 -0400
    message:
      Merge bzr-loom
    modified:
      NEWS                           news-20080228111444-miryhm4hma987q57-1
      branch.py                      branch.py-20060620084702-jnrwijq76kg45klj-5
      tests/test_branch.py           test_branch.py-20060620084702-jnrwijq76kg45klj-9
    ------------------------------------------------------------
    revno: 81.2.3
    revision-id: aaron at aaronbentley.com-20080424161306-097q2zh3qcppae92
    parent: aaron at aaronbentley.com-20080424150232-giw83186x4qeta9r
    committer: Aaron Bentley <aaron at aaronbentley.com>
    branch nick: loom
    timestamp: Thu 2008-04-24 12:13:06 -0400
    message:
      Allow combine-thread to delete the bottom thread (#194274)
    modified:
      branch.py                      branch.py-20060620084702-jnrwijq76kg45klj-5
      commands.py                    commands.py-20060620084702-jnrwijq76kg45klj-6
      loom_state.py                  loom_state.py-20060707132826-p7h51ovrc4lqkxgq-1
      revspec.py                     revspec.py-20060721061235-iqvjh55zlksmv53u-1
      tests/blackbox.py              blackbox.py-20060620084702-jnrwijq76kg45klj-7
      tests/test_loom_state.py       test_loom_state.py-20060707132826-p7h51ovrc4lqkxgq-2
      tree.py                        tree.py-20060701085538-3ajq87mglfa5ryqa-1
    ------------------------------------------------------------
    revno: 81.2.2
    revision-id: aaron at aaronbentley.com-20080424150232-giw83186x4qeta9r
    parent: aaron at aaronbentley.com-20080404155225-et8fes2cbae8benl
    committer: Aaron Bentley <aaron at aaronbentley.com>
    branch nick: loom
    timestamp: Thu 2008-04-24 11:02:32 -0400
    message:
      Refactor, producing get_previous_thread and moving thread_index to LoomState
    modified:
      branch.py                      branch.py-20060620084702-jnrwijq76kg45klj-5
      commands.py                    commands.py-20060620084702-jnrwijq76kg45klj-6
      loom_state.py                  loom_state.py-20060707132826-p7h51ovrc4lqkxgq-1
      revspec.py                     revspec.py-20060721061235-iqvjh55zlksmv53u-1
      tree.py                        tree.py-20060701085538-3ajq87mglfa5ryqa-1
    ------------------------------------------------------------
    revno: 81.2.1
    revision-id: aaron at aaronbentley.com-20080404155225-et8fes2cbae8benl
    parent: aaron at aaronbentley.com-20080404045624-9sdd2b3u2ff388fn
    committer: Aaron Bentley <aaron at aaronbentley.com>
    branch nick: loom
    timestamp: Fri 2008-04-04 11:52:25 -0400
    message:
      Fix out-of-date error, refactor slightly
    modified:
      tree.py                        tree.py-20060701085538-3ajq87mglfa5ryqa-1
=== modified file 'branch.py'
--- a/branch.py	2008-04-10 00:38:37 +0000
+++ b/branch.py	2008-05-23 03:04:33 +0000
@@ -1,5 +1,5 @@
 # Loom, a plugin for bzr to assist in developing focused patches.
-# Copyright (C) 2006 Canonical Limited.
+# Copyright (C) 2006 - 2008 Canonical Limited.
 # 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License version 2 as published
@@ -321,7 +321,7 @@
     def get_loom_state(self):
         """Get the current loom state object."""
         # TODO: cache the loom state during the transaction lifetime.
-        current_content = self.control_files.get('last-loom')
+        current_content = self._transport.get('last-loom')
         reader = loom_io.LoomStateReader(current_content)
         state = loom_state.LoomState(reader)
         return state
@@ -405,7 +405,7 @@
         if after_thread is None:
             insertion_point = len(threads)
         else:
-            insertion_point = self._thread_index(threads, after_thread) + 1
+            insertion_point = state.thread_index(after_thread) + 1
         if insertion_point == 0:
             revision_for_thread = self.last_revision()
         else:
@@ -422,14 +422,6 @@
         state.set_threads(threads)
         self._set_last_loom(state)
 
-    def _thread_index(self, threads, after_thread):
-        """Find the index of after_thread in threads."""
-        thread_names = [name for name, rev, parents in threads]
-        try:
-            return thread_names.index(after_thread)
-        except ValueError:
-            raise NoSuchThread(self, after_thread)
-
     def _parse_loom(self, content):
         """Parse the body of a loom file."""
         result = []
@@ -622,7 +614,7 @@
         """
         state = self.get_loom_state()
         threads = state.get_threads()
-        current_index = self._thread_index(threads, thread_name)
+        current_index = state.thread_index(thread_name)
         del threads[current_index]
         state.set_threads(threads)
         self._set_last_loom(state)
@@ -632,7 +624,7 @@
         """Revert the loom to be the same as the basis loom."""
         state = self.get_loom_state()
         # get the current position
-        position = self._thread_index(state.get_threads(), self.nick)
+        position = state.thread_index(self.nick)
         # reset the current threads
         basis_threads = self.get_threads(state.get_basis_revision_id())
         state.set_threads(
@@ -656,7 +648,7 @@
         state = self.get_loom_state()
         parents = state.get_parents()
         threads = state.get_threads()
-        position = self._thread_index(threads, thread)
+        position = state.thread_index(thread)
         basis_threads = self.get_threads(state.get_basis_revision_id())
         if thread in dict(basis_threads):
             basis_rev = dict(basis_threads)[thread]
@@ -674,7 +666,7 @@
         writer = loom_io.LoomStateWriter(state)
         writer.write(stream)
         stream.seek(0)
-        self.control_files.put('last-loom', stream)
+        self._transport.put_file('last-loom', stream)
 
     def unlock(self):
         """Unlock the loom after a lock.
@@ -734,7 +726,7 @@
         control_files.lock_write()
         try:
             for name, stream in files:
-                control_files.put(name, stream)
+                branch_transport.put_file(name, stream)
         finally:
             control_files.unlock()
         return self.open(a_bzrdir, _found=True, )
@@ -765,13 +757,13 @@
         The conversion takes effect when the branch is next opened.
         """
         assert branch._format.__class__ is self._parent_classs
-        branch.control_files.put_utf8('format', self.get_format_string())
+        branch._transport.put_bytes('format', self.get_format_string())
         state = loom_state.LoomState()
         writer = loom_io.LoomStateWriter(state)
         state_stream = StringIO()
         writer.write(state_stream)
         state_stream.seek(0)
-        branch.control_files.put('last-loom', state_stream)
+        branch._transport.put_file('last-loom', state_stream)
 
 
 

=== modified file 'commands.py'
--- a/commands.py	2008-04-04 04:52:07 +0000
+++ b/commands.py	2008-04-25 20:49:18 +0000
@@ -1,5 +1,5 @@
 # Loom, a plugin for bzr to assist in developing focused patches.
-# Copyright (C) 2006 Canonical Limited.
+# Copyright (C) 2006, 2008 Canonical Limited.
 # 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License version 2 as published
@@ -39,18 +39,24 @@
     in parallel.
 
     You must have a branch nickname explicitly set to use this command, as the
-    branch nickname becomes the 'base branch' of the loom.
+    branch nickname becomes the 'base thread' of the loom.  You can specify
+    the branch nick with the --base option.
     """
 
     takes_args = ['location?']
+    takes_options = [Option('base', type=str,
+                            help='The name to use for the base thread.')]
 
-    def run(self, location='.'):
+    def run(self, location='.', base=None):
         (target, path) = bzrlib.branch.Branch.open_containing(location)
         target.lock_write()
         try:
-            if not target.get_config().has_explicit_nickname():
+            if base is not None:
+                target.nick = base
+            elif not target.get_config().has_explicit_nickname():
                 raise errors.BzrCommandError(
-                    'You must have a branch nickname set to loomify a branch')
+                    'You must specify --base or have a branch nickname set to'
+                    ' loomify a branch')
             branch.loomify(target)
             loom = target.bzrdir.open_branch()
         finally:
@@ -81,13 +87,12 @@
             current_thread = tree.branch.nick
             state = tree.branch.get_loom_state()
             threads = state.get_threads()
-            if len(threads) < 2 or threads[0][0] == current_thread:
+            new_thread = state.get_new_thread_after_deleting(current_thread)
+            if new_thread is None:
                 raise branch.CannotCombineOnLastThread
-            current_index = tree.branch._thread_index(threads, current_thread)
-            new_thread = threads[current_index - 1][0]
             bzrlib.trace.note("Combining thread '%s' into '%s'",
                 current_thread, new_thread)
-            LoomTreeDecorator(tree).down_thread()
+            LoomTreeDecorator(tree).down_thread(new_thread)
             tree.branch.remove_thread(current_thread)
         finally:
             tree.unlock()

=== modified file 'loom_state.py'
--- a/loom_state.py	2007-11-23 01:36:56 +0000
+++ b/loom_state.py	2008-04-24 16:13:06 +0000
@@ -1,5 +1,5 @@
 # Loom, a plugin for bzr to assist in developing focused patches.
-# Copyright (C) 2006 Canonical Limited.
+# Copyright (C) 2006, 2008 Canonical Limited.
 # 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License version 2 as published
@@ -68,6 +68,26 @@
         """
         return dict((thread[0], thread[1:]) for thread in self._threads)
 
+    def thread_index(self, thread):
+        """Find the index of thread in threads."""
+        # Avoid circular import
+        from bzrlib.plugins.loom.branch import NoSuchThread
+        thread_names = [name for name, rev, parents in self._threads]
+        try:
+            return thread_names.index(thread)
+        except ValueError:
+            raise NoSuchThread(self, thread)
+
+    def get_new_thread_after_deleting(self, current_thread):
+        if len(self._threads) == 1:
+            return None
+        current_index = self.thread_index(current_thread)
+        if current_index == 0:
+            new_index = 1
+        else:
+            new_index = current_index - 1
+        return self._threads[new_index][0]
+
     def set_parents(self, parent_list):
         """Set the parents of this state to parent_list.
 

=== modified file 'revspec.py'
--- a/revspec.py	2008-01-20 04:52:32 +0000
+++ b/revspec.py	2008-04-24 19:24:24 +0000
@@ -1,5 +1,5 @@
 # Loom, a plugin for bzr to assist in developing focused patches.
-# Copyright (C) 2006 Canonical Limited.
+# Copyright (C) 2006, 2008 Canonical Limited.
 # 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License version 2 as published
@@ -40,6 +40,9 @@
     prefix = 'thread:'
 
     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
         branch.lock_read()
@@ -47,13 +50,13 @@
             state = branch.get_loom_state()
             threads = state.get_threads()
             if len(self.spec):
-                index = branch._thread_index(threads, self.spec)
+                index = state.thread_index(self.spec)
             else:
                 current_thread = branch.nick
-                index = branch._thread_index(threads, current_thread) - 1
+                index = state.thread_index(current_thread) - 1
                 if index < 0:
                     raise NoLowerThread()
-            return RevisionInfo(branch, None, threads[index][1])
+            return threads[index][1]
         finally:
             branch.unlock()
 

=== modified file 'tests/blackbox.py'
--- a/tests/blackbox.py	2008-04-04 02:33:58 +0000
+++ b/tests/blackbox.py	2008-04-25 20:49:18 +0000
@@ -1,5 +1,5 @@
 # Loom, a plugin for bzr to assist in developing focused patches.
-# Copyright (C) 2006 Canonical Limited.
+# Copyright (C) 2006, 2008 Canonical Limited.
 # 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License version 2 as published
@@ -21,6 +21,7 @@
 import os
 
 import bzrlib
+from bzrlib import workingtree
 from bzrlib.plugins.loom.branch import EMPTY_REVISION
 from bzrlib.plugins.loom.tree import LoomTreeDecorator
 from bzrlib.plugins.loom.tests import TestCaseWithLoom
@@ -67,9 +68,9 @@
         out, err = self.run_bzr(['loomify'], retcode=3)
         self.assertEqual('', out)
         self.assertEqual(
-            'bzr: ERROR: You must have a branch nickname set to loomify a branch\n', 
-            err)
-        
+            'bzr: ERROR: You must specify --base or have a branch nickname set'
+            ' to loomify a branch\n', err)
+
     def test_loomify_new_branch_with_nick(self):
         b = self.make_branch('.')
         b.nick = 'base'
@@ -94,6 +95,12 @@
             [('base', EMPTY_REVISION, [])],
             threads)
 
+    def test_loomify_base_option(self):
+        b = self.make_branch('foo')
+        self.run_bzr(['loomify', 'foo', '--base', 'bar'])
+        b = bzrlib.branch.Branch.open('foo')
+        self.assertEqual('bar', b.nick)
+
 
 class TestCreate(TestsWithLooms):
     
@@ -525,22 +532,27 @@
         self.assertEqual('', out)
         self.assertEqual('bzr: ERROR: Cannot combine threads on the bottom thread.\n', err)
 
-    def test_combine_last_two_threads(self):
-        """Doing a combine on two threads gives you just the bottom one."""
+    def get_two_thread_loom(self):
         tree = self.get_vendor_loom()
         tree.branch.new_thread('above-vendor')
-        LoomTreeDecorator(tree).up_thread()
+        loom_tree = LoomTreeDecorator(tree)
+        loom_tree.up_thread()
         self.build_tree(['file-a'])
         tree.add('file-a')
-        tree.commit('change the tree')
+        tree.commit('change the tree', rev_id='above-vendor-1')
+        loom_tree.down_thread()
+        return tree, loom_tree
+
+    def test_combine_last_two_threads(self):
+        """Doing a combine on two threads gives you just the bottom one."""
+        tree, loom_tree = self.get_two_thread_loom()
         # now we have a change between the threads, so merge this into the lower
         # thread to simulate real-world - different rev ids, and the lower
         # thread has merged the upper.
-        LoomTreeDecorator(tree).down_thread()
         # ugh, should make merge easier to use.
         self.run_bzr(['merge', '-r', 'thread:above-vendor', '.'])
         vendor_revid = tree.commit('merge in the above-vendor work.')
-        LoomTreeDecorator(tree).up_thread()
+        loom_tree.up_thread()
         out, err = self.run_bzr(['combine-thread'])
         self.assertEqual('', out)
         self.assertEqual(
@@ -551,6 +563,14 @@
         self.assertEqual(vendor_revid, tree.last_revision())
         self.assertEqual('vendor', tree.branch.nick)
 
+    def test_combine_lowest_thread(self):
+        """Doing a combine on two threads gives you just the bottom one."""
+        tree, loom_tree = self.get_two_thread_loom()
+        self.run_bzr('combine-thread')
+        tree = workingtree.WorkingTree.open('.')
+        self.assertEqual('above-vendor', tree.branch.nick)
+        self.assertEqual('above-vendor-1', tree.last_revision())
+
     def test_combine_thread_on_non_loomed_branch(self):
         """We should raise a user-friendly exception if the branch isn't loomed yet."""
         self.assert_exception_raised_on_non_loom_branch(['combine-thread'])

=== modified file 'tests/test_loom_state.py'
--- a/tests/test_loom_state.py	2007-11-23 01:36:56 +0000
+++ b/tests/test_loom_state.py	2008-04-24 16:13:06 +0000
@@ -1,5 +1,5 @@
 # Loom, a plugin for bzr to assist in developing focused patches.
-# Copyright (C) 2006 Canonical Limited.
+# Copyright (C) 2006 - 2008 Canonical Limited.
 # 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License version 2 as published
@@ -101,12 +101,31 @@
         self.assertEqual('bar', state.get_basis_revision_id())
         self.assertEqual(sample_threads, state.get_threads())
 
+    def get_sample_state(self):
+        state = loom_state.LoomState()
+        sample_threads = [('foo', 'bar', []), (u'g\xbe', 'bar', [])]
+        state.set_threads(sample_threads)
+        return state
+
     def test_get_threads_dict(self):
-        state = loom_state.LoomState()
-        sample_threads = [('foo', 'bar', []), (u'g\xbe', 'bar', [])]
-        state.set_threads(sample_threads)
+        state = self.get_sample_state()
         self.assertEqual(
             {'foo':('bar', []),
              u'g\xbe':('bar', []),
              },
             state.get_threads_dict())
+
+    def test_thread_index(self):
+        state = self.get_sample_state()
+        self.assertEqual(0, state.thread_index('foo'))
+        self.assertEqual(1, state.thread_index(u'g\xbe'))
+
+    def test_new_thread_after_deleting(self):
+        state = self.get_sample_state()
+        self.assertEqual(u'g\xbe', state.get_new_thread_after_deleting('foo'))
+        self.assertEqual('foo', state.get_new_thread_after_deleting(u'g\xbe'))
+
+    def test_new_thread_after_deleting_one_thread(self):
+        state = loom_state.LoomState()
+        state.set_threads([('foo', 'bar', [])])
+        self.assertIs(None, state.get_new_thread_after_deleting('foo'))

=== modified file 'tests/test_revspec.py'
--- a/tests/test_revspec.py	2008-01-20 04:52:32 +0000
+++ b/tests/test_revspec.py	2008-04-24 19:24:24 +0000
@@ -63,3 +63,9 @@
         loom_tree.down_thread()
         spec = RevisionSpec.from_string('thread:top')
         self.assertEqual(rev_id, spec.in_branch(tree.branch)[1])
+
+    def test_thread_colon_name_gets_named_thread_revision_id(self):
+        tree, loom_tree, _, rev_id = self.get_two_thread_loom()
+        loom_tree.down_thread()
+        spec = RevisionSpec.from_string('thread:top')
+        self.assertEqual(rev_id, spec.as_revision_id(tree.branch))

=== modified file 'tree.py'
--- a/tree.py	2008-03-20 06:02:24 +0000
+++ b/tree.py	2008-04-24 16:13:06 +0000
@@ -1,5 +1,5 @@
 # Loom, a plugin for bzr to assist in developing focused patches.
-# Copyright (C) 2006 Canonical Limited.
+# Copyright (C) 2006, 2008 Canonical Limited.
 # 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License version 2 as published
@@ -48,12 +48,15 @@
         self.tree = a_tree
         self.branch = self.tree.branch
 
+    def _check_switch(self):
+        if self.tree.last_revision() != self.tree.branch.last_revision():
+            raise bzrlib.errors.BzrCommandError('Cannot switch threads with an'
+            ' out-of-date tree. Please run bzr update.')
+
     @needs_write_lock
     def up_thread(self, merge_type=None):
         """Move one thread up in the loom."""
-        if self.tree.last_revision() != self.tree.branch.last_revision():
-            raise bzrlib.errors.BzrCommandError('cannot switch threads with an'
-            'out of date tree. Please run bzr update.')
+        self._check_switch()
         # set it up:
         current_revision = self.tree.last_revision()
         threadname = self.tree.branch.nick
@@ -137,13 +140,12 @@
         :param name: If None, use the next lower thread; otherwise the nae of
             the thread to move to.
         """
-        if self.tree.last_revision() != self.tree.branch.last_revision():
-            raise bzrlib.errors.BzrCommandError('cannot switch threads with an'
-                ' out of date tree. Please run bzr update.')
+        self._check_switch()
         current_revision = self.tree.last_revision()
         threadname = self.tree.branch.nick
-        threads = self.tree.branch.get_loom_state().get_threads()
-        old_thread_index = self.tree.branch._thread_index(threads, threadname)
+        state = self.tree.branch.get_loom_state()
+        threads = state.get_threads()
+        old_thread_index = state.thread_index(threadname)
         old_thread_rev = threads[old_thread_index][1]
         if name is None:
             if old_thread_index == 0:
@@ -152,7 +154,7 @@
             new_thread_name, new_thread_rev, _ = threads[old_thread_index - 1]
         else:
             new_thread_name = name
-            index = self.tree.branch._thread_index(threads, name)
+            index = state.thread_index(name)
             new_thread_rev = threads[index][1]
         assert new_thread_rev is not None
         self.tree.branch.nick = new_thread_name
@@ -187,9 +189,7 @@
 
         :param thread: Only revert a single thread.
         """
-        if self.tree.last_revision() != self.tree.branch.last_revision():
-            raise bzrlib.errors.BzrCommandError('cannot switch threads with an'
-                ' out of date tree. Please run bzr update.')
+        self._check_switch()
         current_thread = self.branch.nick
         last_rev = self.tree.last_revision()
         state = self.branch.get_loom_state()




More information about the bazaar-commits mailing list