Warn if data changed during an upgrade.
authorJelmer Vernooij <jelmer@samba.org>
Sun, 7 Jan 2007 00:48:00 +0000 (01:48 +0100)
committerJelmer Vernooij <jelmer@samba.org>
Sun, 7 Jan 2007 00:48:00 +0000 (01:48 +0100)
NEWS
TODO
repository.py
tests/test_upgrade.py
upgrade.py

diff --git a/NEWS b/NEWS
index f10467e62c41d9a57c89e152645c0e881d8bf80b..ac3d1f452f67dcc96da7fa6ca830975d6347e474 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -54,6 +54,9 @@ IN DEVELOPMENT
 
    * Conversion output can now be on a remote transport.
 
+   * Upgrade command can be used to upgrade branches created with 
+     older versions of the plugin.
+
   PERFORMANCE IMPROVEMENTS
 
    * More efficient implementation of follow_history().
diff --git a/TODO b/TODO
index 7590dab9d073ec2144638041d491374426426c26..a8013ca3d7c91131be8cbe2c4f8f96a3d90acbfd 100644 (file)
--- a/TODO
+++ b/TODO
@@ -3,12 +3,12 @@
 - fix autorealm repository
 - handle parent directories of branches being moved correctly
 - fix "bzr status" in lightweight checkouts
-- faster "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
-- make sure data didn't actually change in upgrade!
-- rewrite TrunkBranchingScheme() and ListBranchingScheme() as subclasses of 
-  ListBranchingScheme()
+- make ListBranchingScheme() support wildcards
+ - 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!
index 7ee8e9c162ef7b082d464acf03815e3639b853b3..6c2569267b030b1f6cc4e2dd1d99ad6e87341a97 100644 (file)
@@ -464,9 +464,6 @@ class SvnRepository(Repository):
         return bzrlib.xml5.serializer_v5.write_revision_to_string(
             self.get_revision(revision_id))
 
-    def get_revision_sha1(self, revision_id):
-        return osutils.sha_string(self.get_revision_xml(revision_id))
-
     def follow_history(self, revnum):
         while revnum > 0:
             yielded_paths = []
index 2f1fc8ed4233fdf87465211411e6a354c9cbe0a9..e47dc13fb4cd5522ab92bdcee0f84e09aba70f39 100644 (file)
@@ -18,6 +18,7 @@ from bzrlib.bzrdir import BzrDir
 from bzrlib.errors import NoRepositoryPresent, InvalidRevisionId
 from bzrlib.repository import Repository
 from bzrlib.tests import TestCase, TestCaseWithTransport
+from bzrlib.trace import mutter
 
 import repository
 from repository import SvnRepository, MAPPING_VERSION, REVISION_ID_PREFIX
@@ -98,7 +99,7 @@ class UpgradeTests(TestCaseWithSubversionRepository):
 
         self.assertTrue(newrepos.has_revision("svn-v1:1@%s-" % oldrepos.uuid))
 
-        upgrade_repository(newrepos, oldrepos)
+        upgrade_repository(newrepos, oldrepos, allow_change=True)
 
         self.assertTrue(newrepos.has_revision("svn-v%d:1@%s-" % (MAPPING_VERSION, oldrepos.uuid)))
 
@@ -120,7 +121,7 @@ class UpgradeTests(TestCaseWithSubversionRepository):
         file("f/a", 'w').write("moredata")
         wt.commit(message='fix moredata', rev_id="customrev")
 
-        upgrade_repository(newrepos, oldrepos)
+        upgrade_repository(newrepos, oldrepos, allow_change=True)
 
         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))
@@ -146,7 +147,7 @@ class UpgradeTests(TestCaseWithSubversionRepository):
         file("f/a", 'w').write("blackfield")
         wt.commit(message='fix it again', rev_id="anotherrev")
 
-        renames = upgrade_repository(newrepos, oldrepos)
+        renames = upgrade_repository(newrepos, oldrepos, allow_change=True)
         self.assertEqual({
             "svn-v1:1@%s-" % oldrepos.uuid:"svn-v%d:1@%s-" % (MAPPING_VERSION, oldrepos.uuid),
             "customrev": "customrev-svn%d-upgrade" % MAPPING_VERSION,
@@ -180,7 +181,7 @@ class UpgradeTests(TestCaseWithSubversionRepository):
         file("f/a", 'w').write("blackfield")
         wt.commit(message='fix it again', rev_id="anotherrev")
 
-        upgrade_branch(b, oldrepos)
+        upgrade_branch(b, oldrepos, allow_change=True)
         self.assertEqual(["svn-v2:1@%s-" % oldrepos.uuid,
                           "customrev-svn%d-upgrade" % MAPPING_VERSION,
                           "anotherrev-svn%d-upgrade" % MAPPING_VERSION
@@ -208,3 +209,20 @@ class UpgradeTests(TestCaseWithSubversionRepository):
         upgrade_branch(b, oldrepos)
         self.assertEqual(["blarev", "customrev", "anotherrev"],
                 b.revision_history())
+
+    def test_raise_incompat(self):
+        repos_url = self.make_client("a", "dc")
+        self.build_tree({'dc/d': 'e'})
+        self.client_add("dc/d")
+        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("c")
+        wt.add("a")
+        wt.commit(message="data", rev_id="svn-v1:1@%s-" % oldrepos.uuid)
+
+        self.assertRaises(UpgradeChangesContent, upgrade_branch, b, oldrepos)
index 0654d75e30de9d972abf5b9c2346003f7486e54c..45b4796239cbe824d7ff82819e8d78f7586d3e1d 100644 (file)
@@ -19,6 +19,7 @@
 
 from bzrlib.config import Config
 from bzrlib.errors import BzrError, InvalidRevisionId
+from bzrlib.trace import mutter
 from bzrlib.ui import ui_factory
 
 from repository import (MAPPING_VERSION, parse_svn_revision_id, 
@@ -91,10 +92,22 @@ def create_upgraded_revid(revid):
 def upgrade_branch(branch, svn_repository, allow_change=False):
     renames = upgrade_repository(branch.repository, svn_repository, 
               branch.last_revision(), allow_change)
+    mutter('renames %r' % renames)
     if len(renames) > 0:
         branch.generate_revision_history(renames[branch.last_revision()])
 
 
+def revision_changed(oldrev, newrev):
+    if (newrev.inventory_sha1 != oldrev.inventory_sha1 or
+        newrev.timestamp != oldrev.timestamp or
+        newrev.message != oldrev.message or
+        newrev.timezone != oldrev.timezone or
+        newrev.committer != oldrev.committer or
+        newrev.properties != oldrev.properties):
+        return True
+    return False
+
+
 def upgrade_repository(repository, svn_repository, revision_id=None, 
                        allow_change=False):
     needed_revs = []
@@ -123,6 +136,13 @@ def upgrade_repository(repository, svn_repository, revision_id=None,
                     newrevid = generate_svn_revision_id(uuid, rev, bp)
                     if svn_repository.has_revision(newrevid):
                         rename_map[revid] = newrevid
+                        if not repository.has_revision(newrevid):
+                            if not allow_change:
+                                oldrev = repository.get_revision(revid)
+                                newrev = svn_repository.get_revision(newrevid)
+                                if revision_changed(oldrev, newrev):
+                                    raise UpgradeChangesContent(revid)
+                            needed_revs.append(newrevid)
                         continue
                 except InvalidRevisionId:
                     pass
@@ -132,8 +152,15 @@ def upgrade_repository(repository, svn_repository, revision_id=None,
                         (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)
+                            if not repository.has_revision(revid):
+                                needed_revs.append(new_parent)
                             needs_upgrading.append(revid)
+
+                            if not allow_change:
+                                oldrev = repository.get_revision(parent)
+                                newrev = svn_repository.get_revision(new_parent)
+                                if revision_changed(oldrev, newrev):
+                                    raise UpgradeChangesContent(parent)
                         new_parents[revid].append(new_parent)
                     except InvalidRevisionId:
                         new_parents[revid].append(parent)