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