Rev 380: Add svn-upgrade command. in http://people.samba.org/bzr/jelmer/bzr-svn/bzr.dev

Jelmer Vernooij jelmer at samba.org
Sat Jan 6 22:57:07 GMT 2007


------------------------------------------------------------
revno: 380
revision-id: jelmer at samba.org-20070106225630-x6bm3q2xu73xllyx
parent: jelmer at samba.org-20070106215112-2x0vx6ham30ej6bh
committer: Jelmer Vernooij <jelmer at samba.org>
branch nick: main
timestamp: Sat 2007-01-06 23:56:30 +0100
message:
  Add svn-upgrade command.
modified:
  TODO                           todo-20060729211917-2kpobww0zyvvo0j2-1
  __init__.py                    __init__.py-20051008155114-eae558e6cf149e1d
  tests/test_upgrade.py          test_upgrade.py-20070106170128-64zt3eqggg4tng1c-1
  upgrade.py                     upgrade.py-20070106192108-0rakplee2lzah4gs-1
=== modified file 'TODO'
--- a/TODO	2007-01-06 16:58:18 +0000
+++ b/TODO	2007-01-06 22:56:30 +0000
@@ -1,12 +1,14 @@
 - make scheme name part of revision id
-- fix commits in checkouts somehow
+- fix commits in heavyweight checkouts somehow
 - fix autorealm repository
 - handle parent directories of branches being moved correctly
 - fix "bzr status" in lightweight checkouts
 - faster "bzr status" in lightweight checkouts
 - avoid extra connect in logwalker?
 - get rid of use of `svn ls' in logwalker
-- rewrite TrunkBranchingScheme() and ListBranchingScheme() as 
-  subclasses of ListBranchingScheme()
+- make sure data didn't actually change in upgrade!
+- rewrite TrunkBranchingScheme() and ListBranchingScheme() as subclasses of 
+  ListBranchingScheme()
+- support multiple branching schemes per repository
 - more efficient implementation for applying txdeltas to weaves. perhaps convert svn deltas to bzr deltas?
 - free memory!

=== modified file '__init__.py'
--- a/__init__.py	2006-12-31 03:39:10 +0000
+++ b/__init__.py	2007-01-06 22:56:30 +0000
@@ -95,13 +95,16 @@
 
 InterRepository.register_optimiser(InterSvnRepository)
 
+from bzrlib.branch import Branch
 from bzrlib.commands import Command, register_command, display_command, Option
+from bzrlib.errors import BzrCommandError
+from bzrlib.repository import Repository
+import bzrlib.urlutils as urlutils
 
 
 def get_scheme(schemename):
     """Parse scheme identifier and return a branching scheme."""
     from scheme import BranchingScheme
-    from bzrlib.errors import BzrCommandError
     
     ret = BranchingScheme.find_scheme(schemename)
     if ret is None:
@@ -140,6 +143,38 @@
 
 register_command(cmd_svn_import)
 
+class cmd_svn_upgrade(Command):
+    """Upgrade the revisions mapped from Subversion in a Bazaar branch.
+    
+    This will change the revision ids of revisions whose parents 
+    were mapped from svn revisions.
+    """
+    takes_args = ['svn_repository?']
+    takes_options = [Option('allow-changes', help='Allow content changes')]
+
+    @display_command
+    def run(self, svn_repository=None, allow_changes=False):
+        from upgrade import upgrade_branch
+        
+        branch_to = Branch.open(".")
+
+        stored_loc = branch_to.get_parent()
+        if svn_repository is None:
+            if stored_loc is None:
+                raise BzrCommandError("No pull location known or"
+                                             " specified.")
+            else:
+                display_url = urlutils.unescape_for_display(stored_loc,
+                        self.outf.encoding)
+                self.outf.write("Using saved location: %s\n" % display_url)
+                svn_repository = stored_loc
+
+        upgrade_branch(branch_to, Repository.open(svn_repository), 
+                       allow_changes)
+
+register_command(cmd_svn_upgrade)
+
+
 def test_suite():
     from unittest import TestSuite, TestLoader
     import tests

=== modified file 'tests/test_upgrade.py'
--- a/tests/test_upgrade.py	2007-01-06 21:51:12 +0000
+++ b/tests/test_upgrade.py	2007-01-06 22:56:30 +0000
@@ -22,7 +22,7 @@
 import repository
 from repository import SvnRepository, MAPPING_VERSION, REVISION_ID_PREFIX
 from tests import TestCaseWithSubversionRepository
-from upgrade import (change_revision_parent, upgrade_repository, 
+from upgrade import (change_revision_parent, upgrade_repository, upgrade_branch,
                      UpgradeChangesContent, parse_legacy_revision_id,
                      create_upgraded_revid)
 
@@ -117,7 +117,7 @@
         file("f/a", "w").write("b")
         wt.add("a")
         wt.commit(message="data", rev_id="svn-v1:1@%s-" % oldrepos.uuid)
-        file("dc/a", 'w').write("moredata")
+        file("f/a", 'w').write("moredata")
         wt.commit(message='fix moredata', rev_id="customrev")
 
         upgrade_repository(newrepos, oldrepos)
@@ -126,3 +126,85 @@
         self.assertTrue(newrepos.has_revision("customrev-svn%d-upgrade" % MAPPING_VERSION))
         self.assertTrue(["svn-v%d:1@%s-" % (MAPPING_VERSION, oldrepos.uuid)],
                         newrepos.revision_parents("customrev-svn%d-upgrade" % MAPPING_VERSION))
+
+    def test_more_custom(self):
+        repos_url = self.make_client("a", "dc")
+        self.build_tree({'dc/a': 'b'})
+        self.client_add("dc/a")
+        self.client_commit("dc", "data")
+
+        oldrepos = Repository.open(repos_url)
+        dir = BzrDir.create("f")
+        newrepos = dir.create_repository()
+        dir.create_branch()
+        wt = dir.create_workingtree()
+        file("f/a", "w").write("b")
+        wt.add("a")
+        wt.commit(message="data", rev_id="svn-v1:1@%s-" % oldrepos.uuid)
+        file("f/a", 'w').write("moredata")
+        wt.commit(message='fix moredata', rev_id="customrev")
+        file("f/a", 'w').write("blackfield")
+        wt.commit(message='fix it again', rev_id="anotherrev")
+
+        renames = upgrade_repository(newrepos, oldrepos)
+        self.assertEqual({
+            "svn-v1:1@%s-" % oldrepos.uuid:"svn-v%d:1@%s-" % (MAPPING_VERSION, oldrepos.uuid),
+            "customrev": "customrev-svn%d-upgrade" % MAPPING_VERSION,
+            "anotherrev": "anotherrev-svn%d-upgrade" % MAPPING_VERSION},
+            renames)
+
+        self.assertTrue(newrepos.has_revision("svn-v%d:1@%s-" % (MAPPING_VERSION, oldrepos.uuid)))
+        self.assertTrue(newrepos.has_revision("customrev-svn%d-upgrade" % MAPPING_VERSION))
+        self.assertTrue(newrepos.has_revision("anotherrev-svn%d-upgrade" % MAPPING_VERSION))
+        self.assertTrue(["svn-v%d:1@%s-" % (MAPPING_VERSION, oldrepos.uuid)],
+                        newrepos.revision_parents("customrev-svn%d-upgrade" % MAPPING_VERSION))
+        self.assertTrue(["customrev-svn%d-upgrade" % MAPPING_VERSION],
+                        newrepos.revision_parents("anotherrev-svn%d-upgrade" % MAPPING_VERSION))
+
+    def test_more_custom_branch(self):
+        repos_url = self.make_client("a", "dc")
+        self.build_tree({'dc/a': 'b'})
+        self.client_add("dc/a")
+        self.client_commit("dc", "data")
+
+        oldrepos = Repository.open(repos_url)
+        dir = BzrDir.create("f")
+        newrepos = dir.create_repository()
+        b = dir.create_branch()
+        wt = dir.create_workingtree()
+        file("f/a", "w").write("b")
+        wt.add("a")
+        wt.commit(message="data", rev_id="svn-v1:1@%s-" % oldrepos.uuid)
+        file("f/a", 'w').write("moredata")
+        wt.commit(message='fix moredata', rev_id="customrev")
+        file("f/a", 'w').write("blackfield")
+        wt.commit(message='fix it again', rev_id="anotherrev")
+
+        upgrade_branch(b, oldrepos)
+        self.assertEqual(["svn-v2:1@%s-" % oldrepos.uuid,
+                          "customrev-svn%d-upgrade" % MAPPING_VERSION,
+                          "anotherrev-svn%d-upgrade" % MAPPING_VERSION
+                          ], b.revision_history())
+
+    def test_branch_none(self):
+        repos_url = self.make_client("a", "dc")
+        self.build_tree({'dc/a': 'b'})
+        self.client_add("dc/a")
+        self.client_commit("dc", "data")
+
+        oldrepos = Repository.open(repos_url)
+        dir = BzrDir.create("f")
+        newrepos = dir.create_repository()
+        b = dir.create_branch()
+        wt = dir.create_workingtree()
+        file("f/a", "w").write("b")
+        wt.add("a")
+        wt.commit(message="data", rev_id="blarev")
+        file("f/a", 'w').write("moredata")
+        wt.commit(message='fix moredata', rev_id="customrev")
+        file("f/a", 'w').write("blackfield")
+        wt.commit(message='fix it again', rev_id="anotherrev")
+
+        upgrade_branch(b, oldrepos)
+        self.assertEqual(["blarev", "customrev", "anotherrev"],
+                b.revision_history())

=== modified file 'upgrade.py'
--- a/upgrade.py	2007-01-06 21:51:12 +0000
+++ b/upgrade.py	2007-01-06 22:56:30 +0000
@@ -21,7 +21,8 @@
 from bzrlib.errors import BzrError, InvalidRevisionId
 from bzrlib.ui import ui_factory
 
-from repository import MAPPING_VERSION, parse_svn_revision_id, unescape_svn_path
+from repository import (MAPPING_VERSION, parse_svn_revision_id, 
+                        unescape_svn_path, generate_svn_revision_id)
 
 # Takes an existing Bazaar branch and replaces all old-version mapped revisions 
 # with new-style revisions mappings. 
@@ -87,10 +88,15 @@
     else:
         return revid + suffix
 
+def upgrade_branch(branch, svn_repository, allow_change=False):
+    renames = upgrade_repository(branch.repository, svn_repository, 
+              branch.last_revision(), allow_change)
+    if len(renames) > 0:
+        branch.generate_revision_history(renames[branch.last_revision()])
+
 
 def upgrade_repository(repository, svn_repository, revision_id=None, 
                        allow_change=False):
-
     needed_revs = []
     needs_upgrading = []
     new_parents = {}
@@ -98,44 +104,73 @@
 
     # Find revisions that need to be upgraded, create
     # dictionary with revision ids in key, new parents in value
-    graph = repository.get_revision_graph()
-    for revid in graph:
-        try:
-            uuid = parse_legacy_revision_id(revid)[0]
-            if uuid == svn_repository.uuid:
-                continue
-        except InvalidRevisionId:
-            pass
-        new_parents[revid] = []
-        for parent in graph[revid]:
+    graph = repository.get_revision_graph(revision_id)
+    def find_children(revid):
+        for x in graph:
+            if revid in graph[x]:
+                yield x
+    pb = ui_factory.nested_progress_bar()
+    i = 0
+    try:
+        for revid in graph:
+            pb.update('gather revision information', i, len(graph))
+            i+=1
             try:
-                (uuid, bp, rev, version) = parse_legacy_revision_id(parent)
-                new_parent = svn_repository.generate_revision_id(rev, bp)
-                if new_parent != parent:
-                    needed_revs.append(new_parent)
-                    needs_upgrading.append(revid)
-                new_parents[revid].append(new_parent)
+                (uuid, bp, rev, version) = parse_legacy_revision_id(revid)
+                newrevid = generate_svn_revision_id(uuid, rev, bp)
+                if svn_repository.has_revision(newrevid):
+                    rename_map[revid] = newrevid
+                    continue
             except InvalidRevisionId:
-                new_parents[revid].append(parent)
+                pass
+            new_parents[revid] = []
+            for parent in graph[revid]:
+                try:
+                    (uuid, bp, rev, version) = parse_legacy_revision_id(parent)
+                    new_parent = generate_svn_revision_id(uuid, rev, bp)
+                    if new_parent != parent:
+                        needed_revs.append(new_parent)
+                        needs_upgrading.append(revid)
+                    new_parents[revid].append(new_parent)
+                except InvalidRevisionId:
+                    new_parents[revid].append(parent)
+    finally:
+        pb.finished()
 
     # Make sure all the required current version revisions are present
     pb = ui_factory.nested_progress_bar()
     i = 0
-    for revid in needed_revs:
-        pb.update('fetching new revisions', i, len(needed_revs))
-        repository.fetch(svn_repository, revid)
-        i+=1
-    pb.finished()
+    try:
+        for revid in needed_revs:
+            pb.update('fetching new revisions', i, len(needed_revs))
+            repository.fetch(svn_repository, revid)
+            i+=1
+    finally:
+        pb.finished()
 
     pb = ui_factory.nested_progress_bar()
     i = 0
-    while len(needs_upgrading) > 0:
-        revid = needs_upgrading.pop()
-        pb.update('upgrading revisions', i, len(needs_upgrading))
-        i+=1
-        newrevid = create_upgraded_revid(revid)
-        if repository.has_revision(newrevid):
-            continue
-        change_revision_parent(repository, revid, newrevid, new_parents[revid])
-        # FIXME: also upgrade children of newrevid
-    pb.finished()
+    try:
+        while len(needs_upgrading) > 0:
+            revid = needs_upgrading.pop()
+            pb.update('upgrading revisions', i, len(needs_upgrading))
+            i+=1
+            newrevid = create_upgraded_revid(revid)
+            rename_map[revid] = newrevid
+            if repository.has_revision(newrevid):
+                continue
+            change_revision_parent(repository, revid, newrevid, new_parents[revid])
+            for childrev in find_children(revid):
+                if not new_parents.has_key(childrev):
+                    new_parents = repository.revision_parents(childrev)
+                def replace_parent(x):
+                    if x == revid:
+                        return newrevid
+                    return x
+                if (revid in new_parents[childrev] and 
+                    not childrev in needs_upgrading):
+                    new_parents[childrev] = map(replace_parent, new_parents[childrev])
+                    needs_upgrading.append(childrev)
+    finally:
+        pb.finished()
+    return rename_map




More information about the bazaar-commits mailing list