Rev 110: import new version of bzr-foreign. in http://people.samba.org/bzr/jelmer/bzr-git/trunk
Jelmer Vernooij
jelmer at samba.org
Wed Sep 10 12:14:37 BST 2008
At http://people.samba.org/bzr/jelmer/bzr-git/trunk
------------------------------------------------------------
revno: 110
revision-id: jelmer at samba.org-20080910111436-89veglifyh2v9ate
parent: jelmer at samba.org-20080906134222-77jwhfa9dizn3r6b
parent: jelmer at samba.org-20080909154418-4512tlepljq72tn3
committer: Jelmer Vernooij <jelmer at samba.org>
branch nick: trunk
timestamp: Wed 2008-09-10 13:14:36 +0200
message:
import new version of bzr-foreign.
added:
foreign/upgrade.py upgrade.py-20080909124113-1j5ajrrwjp4x7z52-1
modified:
foreign/__init__.py foreign.py-20080827193306-rxeku2c2obec90c4-1
------------------------------------------------------------
revno: 0.1.15
revision-id: jelmer at samba.org-20080909154418-4512tlepljq72tn3
parent: jelmer at samba.org-20080909125914-3rrqy2pbfvx4erq2
committer: Jelmer Vernooij <jelmer at samba.org>
branch nick: trunk
timestamp: Tue 2008-09-09 17:44:18 +0200
message:
Add test_suite function.
modified:
__init__.py foreign.py-20080827193306-rxeku2c2obec90c4-1
------------------------------------------------------------
revno: 0.1.14
revision-id: jelmer at samba.org-20080909125914-3rrqy2pbfvx4erq2
parent: jelmer at samba.org-20080909124835-vzc7ggc6arrhvri7
committer: Jelmer Vernooij <jelmer at samba.org>
branch nick: trunk
timestamp: Tue 2008-09-09 14:59:14 +0200
message:
Fix upgrade_branch.
modified:
upgrade.py upgrade.py-20080909124113-1j5ajrrwjp4x7z52-1
------------------------------------------------------------
revno: 0.1.13
revision-id: jelmer at samba.org-20080909124835-vzc7ggc6arrhvri7
parent: jelmer at samba.org-20080909124134-6x3hzc64tskifgli
committer: Jelmer Vernooij <jelmer at samba.org>
branch nick: trunk
timestamp: Tue 2008-09-09 14:48:35 +0200
message:
Fix syntax errors.
modified:
upgrade.py upgrade.py-20080909124113-1j5ajrrwjp4x7z52-1
------------------------------------------------------------
revno: 0.1.12
revision-id: jelmer at samba.org-20080909124134-6x3hzc64tskifgli
parent: jelmer at samba.org-20080830023110-397hpvc2rlqnf2ih
committer: Jelmer Vernooij <jelmer at samba.org>
branch nick: trunk
timestamp: Tue 2008-09-09 14:41:34 +0200
message:
Import upgrade code for upgrading mappings.
added:
upgrade.py upgrade.py-20080909124113-1j5ajrrwjp4x7z52-1
=== modified file 'foreign/__init__.py'
--- a/foreign/__init__.py 2008-08-30 02:31:10 +0000
+++ b/foreign/__init__.py 2008-09-09 15:44:18 +0000
@@ -146,5 +146,12 @@
source_branch.pull(target_branch, overwrite=True,
stop_revision=new_last_revid)
-
+def test_suite():
+ from unittest import TestSuite
+ from bzrlib.tests import TestUtil
+ loader = TestUtil.TestLoader()
+ suite = TestSuite()
+ testmod_names = ['test_versionedfiles',]
+ suite.addTest(loader.loadTestsFromModuleNames(testmod_names))
+ return suite
=== added file 'foreign/upgrade.py'
--- a/foreign/upgrade.py 1970-01-01 00:00:00 +0000
+++ b/foreign/upgrade.py 2008-09-09 12:59:14 +0000
@@ -0,0 +1,258 @@
+# Copyright (C) 2006,2008 by Jelmer Vernooij
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+"""Upgrading revisions made with older versions of the mapping."""
+
+from bzrlib import ui
+from bzrlib.errors import BzrError, InvalidRevisionId, DependencyNotPresent
+from bzrlib.revision import Revision
+from bzrlib.trace import info
+
+import itertools
+
+
+class RebaseNotPresent(DependencyNotPresent):
+ _fmt = "Unable to import bzr-rebase (required for upgrade support): %(error)s"
+
+ def __init__(self, error):
+ DependencyNotPresent.__init__(self, 'bzr-rebase', error)
+
+
+def check_rebase_version(min_version):
+ """Check what version of bzr-rebase is installed.
+
+ Raises an exception when the version installed is older than
+ min_version.
+
+ :raises RebaseNotPresent: Raised if bzr-rebase is not installed or too old.
+ """
+ try:
+ from bzrlib.plugins.rebase import version_info as rebase_version_info
+ if rebase_version_info[:2] < min_version:
+ raise RebaseNotPresent("Version %r present, at least %r required"
+ % (rebase_version_info, min_version))
+ except ImportError, e:
+ raise RebaseNotPresent(e)
+
+
+
+class UpgradeChangesContent(BzrError):
+ """Inconsistency was found upgrading the mapping of a revision."""
+ _fmt = """Upgrade will change contents in revision %(revid)s. Use --allow-changes to override."""
+
+ def __init__(self, revid):
+ self.revid = revid
+
+
+
+def create_upgraded_revid(revid, mapping_suffix, upgrade_suffix="-upgrade"):
+ """Create a new revision id for an upgraded version of a revision.
+
+ Prevents suffix to be appended needlessly.
+
+ :param revid: Original revision id.
+ :return: New revision id
+ """
+ if revid.endswith(upgrade_suffix):
+ return revid[0:revid.rfind("-svn")] + mapping_suffix + upgrade_suffix
+ else:
+ return revid + mapping_suffix + upgrade_suffix
+
+
+def determine_fileid_renames(old_tree, new_tree):
+ for old_file_id in old_tree:
+ new_file_id = new_tree.path2id(old_tree.id2path(old_file_id))
+ if new_file_id is not None:
+ yield old_file_id, new_file_id
+
+
+def upgrade_workingtree(wt, foreign_repository, new_mapping, mapping_registry,
+ allow_changes=False, verbose=False):
+ """Upgrade a working tree.
+
+ :param foreign_repository: Foreign repository object
+ """
+ wt.lock_write()
+ try:
+ old_revid = wt.last_revision()
+ renames = upgrade_branch(wt.branch, foreign_repository, new_mapping=new_mapping,
+ mapping_registry=mapping_registry,
+ allow_changes=allow_changes, verbose=verbose)
+ last_revid = wt.branch.last_revision()
+ wt.set_last_revision(last_revid)
+
+ # Adjust file ids in working tree
+ for (old_fileid, new_fileid) in determine_fileid_renames(wt.branch.repository.revision_tree(old_revid), wt.basis_tree()):
+ path = wt.id2path(old_fileid)
+ wt.remove(path)
+ wt.add([path], [new_fileid])
+ finally:
+ wt.unlock()
+
+ return renames
+
+
+def upgrade_branch(branch, foreign_repository, new_mapping,
+ mapping_registry, allow_changes=False, verbose=False):
+ """Upgrade a branch to the current mapping version.
+
+ :param branch: Branch to upgrade.
+ :param foreign_repository: Repository to fetch new revisions from
+ :param allow_changes: Allow changes in mappings.
+ :param verbose: Whether to print verbose list of rewrites
+ """
+ revid = branch.last_revision()
+ renames = upgrade_repository(branch.repository, foreign_repository,
+ revision_id=revid, new_mapping=new_mapping,
+ mapping_registry=mapping_registry,
+ allow_changes=allow_changes, verbose=verbose)
+ if len(renames) > 0:
+ branch.generate_revision_history(renames[revid])
+ return renames
+
+
+def check_revision_changed(oldrev, newrev):
+ """Check if two revisions are different. This is exactly the same
+ as Revision.equals() except that it does not check the revision_id."""
+ 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):
+ raise UpgradeChangesContent(oldrev.revision_id)
+
+
+def generate_upgrade_map(new_mapping, revs, mapping_registry):
+ """Generate an upgrade map for use by bzr-rebase.
+
+ :param new_mapping: Mapping to upgrade revisions to.
+ :param revs: Iterator over revisions to upgrade.
+ :return: Map from old revids as keys, new revids as values stored in a
+ dictionary.
+ """
+ rename_map = {}
+ # Create a list of revisions that can be renamed during the upgade
+ for revid in revs:
+ assert isinstance(revid, str)
+ try:
+ (foreign_revid, mapping) = mapping_registry.parse_revision_id(revid)
+ except InvalidRevisionId:
+ # Not a foreign revision, nothing to do
+ continue
+ newrevid = new_mapping.revision_id_foreign_to_bzr(foreign_revid)
+ if revid == newrevid:
+ continue
+ rename_map[revid] = newrevid
+
+ return rename_map
+
+MIN_REBASE_VERSION = (0, 4)
+
+def create_upgrade_plan(repository, foreign_repository, new_mapping,
+ mapping_registry, revision_id=None, allow_changes=False):
+ """Generate a rebase plan for upgrading revisions.
+
+ :param repository: Repository to do upgrade in
+ :param foreign_repository: Subversion repository to fetch new revisions from.
+ :param new_mapping: New mapping to use.
+ :param revision_id: Revision to upgrade (None for all revisions in
+ repository.)
+ :param allow_changes: Whether an upgrade is allowed to change the contents
+ of revisions.
+ :return: Tuple with a rebase plan and map of renamed revisions.
+ """
+ from bzrlib.plugins.rebase.rebase import generate_transpose_plan
+ check_rebase_version(MIN_REBASE_VERSION)
+
+ graph = repository.get_graph()
+ if revision_id is None:
+ potential = repository.all_revision_ids()
+ else:
+ potential = itertools.imap(lambda (rev, parents): rev,
+ graph.iter_ancestry([revision_id]))
+ upgrade_map = generate_upgrade_map(new_mapping, potential, mapping_registry)
+
+ # Make sure all the required current version revisions are present
+ for revid in upgrade_map.values():
+ if not repository.has_revision(revid):
+ repository.fetch(foreign_repository, revid)
+
+ if not allow_changes:
+ for oldrevid, newrevid in upgrade_map.items():
+ oldrev = repository.get_revision(oldrevid)
+ newrev = repository.get_revision(newrevid)
+ check_revision_changed(oldrev, newrev)
+
+ if revision_id is None:
+ heads = repository.all_revision_ids()
+ else:
+ heads = [revision_id]
+
+ plan = generate_transpose_plan(graph.iter_ancestry(heads), upgrade_map,
+ graph,
+ lambda revid: create_upgraded_revid(revid, new_mapping.upgrade_suffix))
+ def remove_parents((oldrevid, (newrevid, parents))):
+ return (oldrevid, newrevid)
+ upgrade_map.update(dict(map(remove_parents, plan.items())))
+
+ return (plan, upgrade_map)
+
+
+def upgrade_repository(repository, foreign_repository, new_mapping,
+ mapping_registry, revision_id=None, allow_changes=False,
+ verbose=False):
+ """Upgrade the revisions in repository until the specified stop revision.
+
+ :param repository: Repository in which to upgrade.
+ :param foreign_repository: Repository to fetch new revisions from.
+ :param new_mapping: New mapping.
+ :param revision_id: Revision id up until which to upgrade, or None for
+ all revisions.
+ :param allow_changes: Allow changes to mappings.
+ :param verbose: Whether to print list of rewrites
+ :return: Dictionary of mapped revisions
+ """
+ check_rebase_version(MIN_REBASE_VERSION)
+ from bzrlib.plugins.rebase.rebase import (
+ replay_snapshot, rebase, rebase_todo)
+
+ # Find revisions that need to be upgraded, create
+ # dictionary with revision ids in key, new parents in value
+ try:
+ repository.lock_write()
+ foreign_repository.lock_read()
+ (plan, revid_renames) = create_upgrade_plan(repository, foreign_repository,
+ new_mapping, mapping_registry,
+ revision_id=revision_id,
+ allow_changes=allow_changes)
+ if verbose:
+ for revid in rebase_todo(repository, plan):
+ info("%s -> %s" % (revid, plan[revid][0]))
+ def fix_revid(revid):
+ try:
+ (foreign_revid, mapping) = mapping_registry.parse_revision_id(revid)
+ except InvalidRevisionId:
+ return revid
+ return new_mapping.revision_id_foreign_to_bzr(foreign_revid)
+ def replay(repository, oldrevid, newrevid, new_parents):
+ return replay_snapshot(repository, oldrevid, newrevid, new_parents,
+ revid_renames, fix_revid)
+ rebase(repository, plan, replay)
+ return revid_renames
+ finally:
+ repository.unlock()
+ foreign_repository.unlock()
+
More information about the bazaar-commits
mailing list