Rev 118: ``bzr combine-thread`` will no longer combine threads without ``--force`` in http://bazaar.launchpad.net/~bzr-loom-devs/bzr-loom/trunk/

Robert Collins robertc at robertcollins.net
Tue Jun 29 08:25:55 BST 2010


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

------------------------------------------------------------
revno: 118
revision-id: robertc at robertcollins.net-20100629072549-8sw1estpvchhsuya
parent: robertc at robertcollins.net-20100629060616-ysrhik7k0ejk6kk0
fixes bug(s): https://launchpad.net/bugs/506235
committer: Robert Collins <robertc at robertcollins.net>
branch nick: trunk
timestamp: Tue 2010-06-29 17:25:49 +1000
message:
  ``bzr combine-thread`` will no longer combine threads without ``--force``
  when the thread being removed has work not merged into either the thread
  above or below. (Robert Collins, #506235)
=== modified file 'NEWS'
--- a/NEWS	2010-06-29 06:06:16 +0000
+++ b/NEWS	2010-06-29 07:25:49 +0000
@@ -36,6 +36,10 @@
 BUGFIXES
 --------
 
+* ``bzr combine-thread`` will no longer combine threads without ``--force``
+  when the thread being removed has work not merged into either the thread
+  above or below. (Robert Collins, #506235)
+
 * ``switch`` now accepts the ``--directory`` option. (Vincent Ladeuil, #595563)
 
 API BREAKS

=== modified file 'commands.py'
--- a/commands.py	2010-06-29 06:06:16 +0000
+++ b/commands.py	2010-06-29 07:25:49 +0000
@@ -92,21 +92,45 @@
     def run(self, force=False):
         (tree, path) = workingtree.WorkingTree.open_containing('.')
         branch.require_loom_branch(tree.branch)
-        tree.lock_write()
-        try:
-            current_thread = tree.branch.nick
-            state = tree.branch.get_loom_state()
+        self.add_cleanup(tree.lock_write().unlock)
+        current_thread = tree.branch.nick
+        state = tree.branch.get_loom_state()
+        if not force:
+            # Check for unmerged work.
             # XXX: Layering issue whom should be caring for the check, not the
             # command thats for sure.
-            new_thread = state.get_new_thread_after_deleting(current_thread)
-            if new_thread is None:
-                raise branch.CannotCombineOnLastThread
-            bzrlib.trace.note("Combining thread '%s' into '%s'",
-                current_thread, new_thread)
-            LoomTreeDecorator(tree).down_thread(new_thread)
-            tree.branch.remove_thread(current_thread)
-        finally:
-            tree.unlock()
+            threads = state.get_threads()
+            current_index = state.thread_index(current_thread)
+            rev_below = None
+            rev_current = threads[current_index][1]
+            rev_above = None
+            if current_index:
+                # There is a thread below
+                rev_below = threads[current_index - 1][1]
+            if current_index < len(threads) - 1:
+                rev_above = threads[current_index + 1][1]
+            graph = tree.branch.repository.get_graph()
+            candidates = [rev for rev in
+                (rev_below, rev_current, rev_above) if rev]
+            heads = graph.heads(candidates)
+            # If current is not a head, its trivially merged, or
+            # if current is == rev_below, its also merged, or
+            # if there is only one thread its merged (well its not unmerged).
+            if (rev_current == rev_below or rev_current not in heads or
+                (rev_below is None and rev_above is None)):
+                merged = True
+            else:
+                merged = False
+            if not merged:
+                raise errors.BzrCommandError("Thread '%s' has unmerged work"
+                    ". Use --force to combine anyway." % current_thread)
+        new_thread = state.get_new_thread_after_deleting(current_thread)
+        if new_thread is None:
+            raise branch.CannotCombineOnLastThread
+        bzrlib.trace.note("Combining thread '%s' into '%s'",
+            current_thread, new_thread)
+        LoomTreeDecorator(tree).down_thread(new_thread)
+        tree.branch.remove_thread(current_thread)
 
 
 class cmd_create_thread(bzrlib.commands.Command):

=== modified file 'tests/blackbox.py'
--- a/tests/blackbox.py	2010-06-29 06:06:16 +0000
+++ b/tests/blackbox.py	2010-06-29 07:25:49 +0000
@@ -747,6 +747,19 @@
         self.assertEqual(vendor_revid, tree.last_revision())
         self.assertEqual('vendor', tree.branch.nick)
 
+    def test_combine_unmerged_thread_errors(self):
+        """Combining a thread with unique work errors without --force."""
+        tree, loom_tree = self.get_loom_with_unique_thread()
+        loom_tree.up_thread()
+        unique_revid = tree.last_revision()
+        out, err = self.run_bzr(['combine-thread'], retcode=3)
+        self.assertEqual('', out)
+        self.assertEqual("bzr: ERROR: "
+"Thread 'unique-thread' has unmerged work. Use --force to combine anyway.\n",
+            err)
+        self.assertEqual(unique_revid, tree.last_revision())
+        self.assertEqual('unique-thread', tree.branch.nick)
+
     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()




More information about the bazaar-commits mailing list