Rev 9: Add rebase-todo command, fix rebase-continue. in file:///data/jelmer/bzr-rebase/trunk/

Jelmer Vernooij jelmer at samba.org
Thu Jul 12 09:22:38 BST 2007


At file:///data/jelmer/bzr-rebase/trunk/

------------------------------------------------------------
revno: 9
revision-id: jelmer at samba.org-20070704211144-x24jnvqimeakxpq0
parent: jelmer at samba.org-20070704203154-3px851kiifoetfry
committer: Jelmer Vernooij <jelmer at samba.org>
branch nick: bzr-rebase
timestamp: Wed 2007-07-04 23:11:44 +0200
message:
  Add rebase-todo command, fix rebase-continue.
modified:
  __init__.py                    __init__.py-20070626215909-fi0s39bkwxn4gcto-1
  rebase.py                      rebase.py-20070626221123-ellanmf93nw8z9r1-1
  test_rebase.py                 test_rebase.py-20070626221123-ellanmf93nw8z9r1-2
=== modified file '__init__.py'
--- a/__init__.py	2007-07-04 20:31:54 +0000
+++ b/__init__.py	2007-07-04 21:11:44 +0000
@@ -15,7 +15,8 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
 from bzrlib.commands import Command, Option, display_command, register_command
-from bzrlib.errors import BzrCommandError, UnrelatedBranches, ConflictsInTree
+from bzrlib.errors import BzrCommandError, UnrelatedBranches, ConflictsInTree, NoSuchFile
+from bzrlib.trace import info
 
 class cmd_rebase(Command):
     """Re-base a branch.
@@ -96,7 +97,10 @@
         wt.lock_write()
         try:
             # Read plan file and set last revision
-            last_rev_info = read_rebase_plan(wt)[0]
+            try:
+                last_rev_info = read_rebase_plan(wt)[0]
+            except NoSuchFile:
+                raise BzrCommandError("No rebase to abort")
             wt.branch.set_last_revision_info(last_rev_info[0], last_rev_info[1])
             wt.set_last_revision(last_rev_info[1])
             wt.revert([], backups=False)
@@ -112,7 +116,7 @@
     
     @display_command
     def run(self):
-        from rebase import read_rebase_plan, rebase_plan_exists, workingtree_replay, rebase, remove_rebase_plan
+        from rebase import read_rebase_plan, rebase_plan_exists, workingtree_replay, rebase, remove_rebase_plan, commit_rebase, read_active_rebase_revid
         from bzrlib.workingtree import WorkingTree
         wt = WorkingTree.open('.')
         wt.lock_write()
@@ -121,8 +125,14 @@
             if len(wt.conflicts()) != 0:
                 raise BzrCommandError("There are still conflicts present")
             # Read plan file
-            replace_map = read_rebase_plan(wt)[1]
-
+            try:
+                replace_map = read_rebase_plan(wt)[1]
+            except NoSuchFile:
+                raise BzrCommandError("No rebase to continue")
+            oldrevid = read_active_rebase_revid(wt)
+            if oldrevid is not None:
+                oldrev = wt.branch.repository.get_revision(oldrevid)
+                commit_rebase(wt, oldrev, replace_map[oldrevid][0])
             try:
                 # Start executing plan from current Branch.last_revision()
                 rebase(wt.branch.repository, replace_map, workingtree_replay(wt))
@@ -134,9 +144,33 @@
             wt.unlock()
 
 
+class cmd_rebase_todo(Command):
+    """Print list of revisions that still need to be replayed as part of the current rebase operation.
+
+    """
+    
+    def run(self):
+        from rebase import read_rebase_plan, rebase_todo, read_active_rebase_revid
+        from bzrlib.workingtree import WorkingTree
+        wt = WorkingTree.open('.')
+        wt.lock_read()
+        try:
+            try:
+                replace_map = read_rebase_plan(wt)[1]
+            except NoSuchFile:
+                raise BzrCommandError("No rebase to view")
+            currentrevid = read_active_rebase_revid(wt)
+            if currentrevid is not None:
+                info("Currently replaying: %s" % currentrevid)
+            for revid in rebase_todo(wt.branch.repository, replace_map):
+                info("%s -> %s" % (revid, replace_map[revid][0]))
+        finally:
+            wt.unlock()
+
 register_command(cmd_rebase)
 register_command(cmd_rebase_abort)
 register_command(cmd_rebase_continue)
+register_command(cmd_rebase_todo)
 
 def test_suite():
     from unittest import TestSuite

=== modified file 'rebase.py'
--- a/rebase.py	2007-07-04 20:31:54 +0000
+++ b/rebase.py	2007-07-04 21:11:44 +0000
@@ -17,10 +17,12 @@
 from bzrlib.config import Config
 from bzrlib.errors import UnknownFormatError, NoSuchFile, BzrError
 from bzrlib.generate_ids import gen_revision_id
+from bzrlib.revision import NULL_REVISION
 from bzrlib.trace import mutter
 import bzrlib.ui as ui
 
 REBASE_PLAN_FILENAME = 'rebase-plan'
+REBASE_CURRENT_REVID_FILENAME = 'rebase-current'
 REBASE_PLAN_VERSION = 1
 
 def rebase_plan_exists(wt):
@@ -183,6 +185,17 @@
     return replace_map
 
 
+def rebase_todo(repository, replace_map):
+    """Figure out what revisions still need to be rebased.
+
+    :param repository: Repository that contains the revisions
+    :param replace_map: Replace map
+    """
+    for revid in replace_map:
+        if not repository.has_revision(replace_map[revid][0]):
+            yield revid
+
+
 def rebase(repository, replace_map, replay_fn):
     """Rebase a working tree according to the specified map.
 
@@ -190,10 +203,7 @@
     :param replace_map: Dictionary with revisions to (optionally) rewrite
     :param merge_fn: Function for replaying a revision
     """
-    todo = []
-    for revid in replace_map:
-        if not repository.has_revision(replace_map[revid][0]):
-            todo.append(revid)
+    todo = list(rebase_todo(repository, replace_map))
     dependencies = {}
 
     # Figure out the dependencies
@@ -234,7 +244,7 @@
      
 
 class MapTree:
-    def __init__(self, oldtree, old_parents, new_parents):
+    def __init__(self, repository, oldtree, old_parents, new_parents):
         self.map = {}
         for (oldp, newp) in zip(old_parents, new_parents):
             oldinv = repository.get_revision_inventory(oldp)
@@ -252,7 +262,7 @@
 
     def new_id(self, file_id):
         try:
-            return new_id[file_id]
+            return self.map[file_id]
         except KeyError:
             return file_id
 
@@ -292,7 +302,8 @@
 
     # Check what new_ie.file_id should be
     # use old and new parent inventories to generate new_id map
-    oldtree = MapTree(repository.revision_tree(oldrevid), 
+    oldtree = MapTree(repository, 
+                      repository.revision_tree(oldrevid), 
                       oldrev.parent_ids, new_parents)
     oldinv = repository.get_revision_inventory(oldrevid)
     total = len(oldinv)
@@ -318,6 +329,20 @@
     return builder.commit(oldrev.message)
 
 
+def commit_rebase(wt, oldrev, newrevid):
+    """Commit a rebase.
+    
+    :param wt: Mutable tree with the changes.
+    :param oldrev: Revision info of new revision to commit.
+    :param newrevid: New revision id."""
+    assert oldrev.revision_id != newrevid
+    revprops = dict(oldrev.properties)
+    revprops['rebase-of'] = oldrev.revision_id
+    wt.commit(message=oldrev.message, timestamp=oldrev.timestamp, timezone=oldrev.timezone,
+              revprops=revprops, rev_id=newrevid)
+    write_active_rebase_revid(wt, None)
+
+
 def replay_delta_workingtree(wt, oldrevid, newrevid, newparents, map_ids=False,
         merge_type=None):
     """Replay a commit in a working tree, with a different base.
@@ -346,19 +371,15 @@
     oldtree = repository.revision_tree(oldrevid)
     basetree = repository.revision_tree(oldrev.parent_ids[0])
     if map_ids:
-        oldtree = MapTree(oldtree, oldrev.parent_ids, new_parents)
-        basetree = MapTree(basetree, oldrev.parent_ids, new_parents)
+        oldtree = MapTree(repository, oldtree, oldrev.parent_ids, new_parents)
+        basetree = MapTree(repository, basetree, oldrev.parent_ids, new_parents)
 
+    write_active_rebase_revid(wt, oldrevid)
     merge = merge_type(working_tree=wt, this_tree=wt, 
             base_tree=basetree,
             other_tree=oldtree)
 
-    # commit
-    revprops = dict(oldrev.properties)
-    revprops['rebase-of'] = oldrevid
-    wt.commit(message=oldrev.message, timestamp=oldrev.timestamp, timezone=oldrev.timezone,
-              revprops=revprops, rev_id=newrevid)
-
+    commit_rebase(wt, oldrev, newrevid)
 
 def workingtree_replay(wt, map_ids=False):
     """Returns a function that can replay revisions in wt.
@@ -371,5 +392,17 @@
         return replay_delta_workingtree(wt, oldrevid, newrevid, newparents)
     return replay
 
-class MergeConflicted(BzrError):
-    _fmt = "Conflict during merge"
+
+def write_active_rebase_revid(wt, revid):
+    if revid is None:
+        revid = NULL_REVISION
+    wt._control_files.put_utf8(REBASE_CURRENT_REVID_FILENAME, revid)
+
+def read_active_rebase_revid(wt):
+    try:
+        text = wt._control_files.get(REBASE_CURRENT_REVID_FILENAME).read().rstrip("\n")
+        if text == NULL_REVISION:
+            return None
+        return text
+    except NoSuchFile:
+        return None

=== modified file 'test_rebase.py'
--- a/test_rebase.py	2007-07-04 19:55:29 +0000
+++ b/test_rebase.py	2007-07-04 21:11:44 +0000
@@ -22,7 +22,10 @@
                     replay_snapshot, generate_simple_plan,
                     generate_transpose_plan, rebase_plan_exists,
                     REBASE_PLAN_FILENAME, write_rebase_plan,
-                    read_rebase_plan, remove_rebase_plan) 
+                    REBASE_CURRENT_REVID_FILENAME,
+                    read_rebase_plan, remove_rebase_plan, 
+                    read_active_rebase_revid, 
+                    write_active_rebase_revid)
 
 
 class RebasePlanReadWriterTests(TestCase):
@@ -205,3 +208,28 @@
         self.assertEquals(((1, "bla"), {"oldrev": ("newrev", ["newparent1", "newparent2"])}),
                 read_rebase_plan(wt))
 
+class CurrentRevidFileTests(TestCaseWithTransport):
+    def test_read_nonexistant(self):
+        wt = self.make_branch_and_tree('.')
+        self.assertIs(None, read_active_rebase_revid(wt))
+
+    def test_read_null(self):
+        wt = self.make_branch_and_tree('.')
+        wt._control_files.put_utf8(REBASE_CURRENT_REVID_FILENAME, NULL_REVISION)
+        self.assertIs(None, read_active_rebase_revid(wt))
+
+    def test_read(self):
+        wt = self.make_branch_and_tree('.')
+        wt._control_files.put_utf8(REBASE_CURRENT_REVID_FILENAME, "bla")
+        self.assertEquals("bla", read_active_rebase_revid(wt))
+
+    def test_write(self):
+        wt = self.make_branch_and_tree('.')
+        write_active_rebase_revid(wt, "bloe")
+        self.assertEquals("bloe", read_active_rebase_revid(wt))
+
+    def test_write_null(self):
+        wt = self.make_branch_and_tree('.')
+        write_active_rebase_revid(wt, None)
+        self.assertIs(None, read_active_rebase_revid(wt))
+




More information about the bazaar-commits mailing list