At http://people.samba.org/bzr/jelmer/bzr-svn/0.5
------------------------------------------------------------ revno: 2321 revision-id: [email protected] parent: [email protected] committer: Jelmer Vernooij <[email protected]> branch nick: 0.5 timestamp: Sat 2009-01-17 03:42:57 +0100 message: Use unicode internally in file id determination code rather than converting back and forth, simplify. modified: fetch.py fetch.py-20060625004942-x2lfaib8ra707a8p-1 fileids.py fileids.py-20060714013623-u5iiyqqnko11grcf-1 mapping.py mapping.py-20080128201303-6cp01phc0dmc0kiv-1 tests/test_fileids.py test_fileids.py-20060622131341-19gyrlgqy8yl2od5-1 === modified file 'fetch.py' --- a/fetch.py 2009-01-16 22:37:58 +0000 +++ b/fetch.py 2009-01-17 02:42:57 +0000 @@ -35,6 +35,7 @@ from subvertpy.delta import apply_txdelta_handler from bzrlib.plugins.svn.errors import InvalidFileName, FileIdMapIncomplete +from bzrlib.plugins.svn.fileids import get_local_changes from bzrlib.plugins.svn.foreign import escape_commit_message from bzrlib.plugins.svn.mapping import SVN_PROP_BZR_PREFIX from bzrlib.plugins.svn.repository import SvnRepository, SvnRepositoryFormat @@ -581,8 +582,12 @@ if self._id_map is not None: return self._id_map - self._id_map = self.source.fileid_map.get_idmap_delta(self.revmeta, - self.mapping)[0] + local_changes = get_local_changes(self.revmeta.get_paths(self.mapping), + self.revmeta.branch_path, self.mapping, + self.source.get_layout(), + self.source.generate_revision_id) + self._id_map = self.source.fileid_map.get_idmap_delta(local_changes, self.revmeta, + self.mapping) return self._id_map @@ -629,11 +634,13 @@ return self.mapping.generate_file_id(self.revmeta.get_foreign_revid(), new_path) def _get_text_revid(self, path): + assert isinstance(path, unicode) if self._text_revids is None: self._text_revids = self.revmeta.get_text_revisions(self.mapping) return self._text_revids.get(path) def _get_text_parents(self, path): + assert isinstance(path, unicode) if self._text_parents is None: self._text_parents = self.revmeta.get_text_parents(self.mapping) return self._text_parents.get(path) === modified file 'fileids.py' --- a/fileids.py 2009-01-16 23:57:49 +0000 +++ b/fileids.py 2009-01-17 02:42:57 +0000 @@ -22,6 +22,7 @@ from bzrlib.trace import mutter from bzrlib.versionedfile import ConstantMapper +from collections import defaultdict import urllib from bzrlib.plugins.svn import ( @@ -32,34 +33,48 @@ iter_with_mapping, ) - -def apply_idmap_delta(map, revid, delta, changes): +# idmap: dictionary mapping unicode paths to tuples with file id and revision id +# idmap delta: dictionary mapping unicode paths to new file id assignments +# text revision map: dictionary mapping unicode paths to text revisions (usually revision ids) + +def determine_text_revisions(changes, default_revid, specific_revids): + """Create a text revision map. + + :param changes: Local changes dictionary + :param default_revid: Default revision id, if none is explicitly specified + :param specific_revids: Dictionary with explicit text revisions to use + :return: text revision map + """ + ret = {} + ret.update(specific_revids) + for p, data in changes.iteritems(): + assert isinstance(p, unicode) + if data[0] in ('A', 'R', 'M') and p not in ret: + ret[p] = default_revid + return ret + + +def apply_idmap_delta(map, text_revisions, delta, changes, default_revid): """Update a file id map. :param map: Existing file id map that needs to be updated - :param revid: Revision id of the id map + :param text_revisions: Text revisions for the map :param delta: Id map delta. :param changes: Changes for the revision in question. """ - for p in changes: - inv_p = p.decode("utf-8") - if changes[p][0] == 'M' and not delta.has_key(p): - delta[inv_p] = map[inv_p][0] - - for x in sorted(delta.keys(), reverse=True): + for p, data in changes.iteritems(): + if data[0] in ('D', 'R') and not p in delta: + del map[p] + for xp in map.keys(): + if xp.startswith(u"%s/" % p) and not xp in delta: + del map[xp] + + for x in sorted(text_revisions.keys() + delta.keys()): assert isinstance(x, unicode) - if delta[x] is None: - del map[x] - for p in map.keys(): - if p.startswith(u"%s/" % x): - del map[p] - - for x in sorted(delta.keys()): - if (delta[x] is not None and - # special case - we change metadata in svn at the branch root path + if (# special case - we change metadata in svn at the branch root path # but that's not reflected as a bzr metadata change in bzr (x != "" or not "" in map or map[x][1] == NULL_REVISION)): - map[x] = (str(delta[x]), revid) + map[x] = (delta.get(x) or map[x][0], text_revisions.get(x) or default_revid) def get_local_changes(paths, branch, mapping, layout, generate_revid, @@ -102,10 +117,10 @@ if get_children is not None: for c in get_children(data[1], data[2]): mutter('oops: %r child %r', data[1], c) - new_paths[changes.rebase_path(c, data[1], new_p)] = (data[0], None, -1) + new_paths[changes.rebase_path(c, data[1], new_p).decode("utf-8")] = (data[0], None, -1) data = (data[0], None, -1) - new_paths[new_p] = data + new_paths[new_p.decode("utf-8")] = data return new_paths @@ -115,29 +130,21 @@ """Simple function that generates a dictionary with file id changes. Does not track renames. """ - map = {} + delta = {} for p in sorted(changes.keys(), reverse=False): data = changes[p] - - inv_p = p.decode("utf-8") - if data[0] in ('D', 'R'): - if not inv_p in map: - map[inv_p] = None + assert isinstance(p, unicode) if data[0] in ('A', 'R'): - assert isinstance(inv_p, unicode) - map[inv_p] = new_file_id(inv_p) - + delta[p] = new_file_id(p) if data[1] is not None: - mutter('%r copied from %r:%s', inv_p, data[1], data[2]) + mutter('%r copied from %r:%s', p, data[1], data[2]) if find_children is not None: for c in find_children(data[1], data[2]): - inv_c = c.decode("utf-8") - path = inv_c.replace(data[1].decode("utf-8"), inv_p+"/", 1).replace(u"//", u"/") + path = c.replace(data[1], p+"/", 1).replace(u"//", u"/") assert isinstance(path, unicode) - map[path] = new_file_id(path) - mutter('added mapping %r -> %r', path, map[path]) - - return map + delta[path] = new_file_id(path) + mutter('added mapping %r -> %r', path, delta[path]) + return delta class FileIdMap(object): @@ -151,21 +158,18 @@ self.apply_changes_fn = apply_changes_fn self.repos = repos - def get_idmap_delta(self, revmeta, mapping, find_children=None): + def get_idmap_delta(self, changes, revmeta, mapping, find_children=None): """Change file id map to incorporate specified changes. :param revmeta: RevisionMetadata object for revision with changes :param renames: List of renames (known file ids for particular paths) :param mapping: Mapping """ - changes = get_local_changes(revmeta.get_paths(mapping), revmeta.branch_path, mapping, - self.repos.get_layout(), - self.repos.generate_revision_id, find_children) if find_children is not None: def get_children(path, revid): (uuid, bp, revnum), mapping = self.repos.lookup_revision_id(revid) - for p in find_children(bp+"/"+path, revnum): - yield p[len(bp):].strip("/") + for p in find_children(bp+"/"+path.encode("utf-8"), revnum): + yield p[len(bp):].strip("/").decode("utf-8") else: get_children = None @@ -175,15 +179,19 @@ idmap = self.apply_changes_fn(new_file_id, changes, get_children) idmap.update(revmeta.get_fileid_map(mapping)) - return (idmap, changes) + return idmap def update_idmap(self, map, revmeta, mapping, find_children=None): - (idmap, changes) = self.get_idmap_delta(revmeta, + local_changes = get_local_changes(revmeta.get_paths(mapping), + revmeta.branch_path, mapping, + self.repos.get_layout(), + self.repos.generate_revision_id, find_children) + idmap = self.get_idmap_delta(local_changes, revmeta, mapping, find_children) - apply_idmap_delta(map, revmeta.get_revision_id(mapping), idmap, changes) - for path, revid in revmeta.get_text_revisions(mapping).iteritems(): - assert path in map - map[path] = (map[path][0], revid) + revid = revmeta.get_revision_id(mapping) + text_revisions = determine_text_revisions(local_changes, revid, + revmeta.get_text_revisions(mapping)) + apply_idmap_delta(map, text_revisions, idmap, local_changes, revid) def get_map(self, foreign_revid, mapping): """Make sure the map is up to date until revnum.""" === modified file 'mapping.py' --- a/mapping.py 2009-01-16 22:22:09 +0000 +++ b/mapping.py 2009-01-17 02:42:57 +0000 @@ -593,7 +593,7 @@ for line in text.splitlines(): parts = line.split("\t") entry = parts[0] - ret[urllib.unquote(entry)] = filter(lambda x: x != "", [osutils.safe_revision_id(parent_revid) for parent_revid in parts[1:]]) + ret[urllib.unquote(entry).decode("utf-8")] = filter(lambda x: x != "", [osutils.safe_revision_id(parent_revid) for parent_revid in parts[1:]]) return ret @@ -601,7 +601,7 @@ ret = {} for line in text.splitlines(): (entry, revid) = line.split("\t", 1) - ret[urllib.unquote(entry)] = osutils.safe_revision_id(revid) + ret[urllib.unquote(entry).decode("utf-8")] = osutils.safe_revision_id(revid) return ret === modified file 'tests/test_fileids.py' --- a/tests/test_fileids.py 2009-01-16 22:22:09 +0000 +++ b/tests/test_fileids.py 2009-01-17 02:42:57 +0000 @@ -200,70 +200,70 @@ return map def test_simple(self): - map = self.apply_mappings({(1, ""): {"foo": ('A', None, None)}}) - self.assertEqual({ 'foo': ("1...@uuid::foo", + map = self.apply_mappings({(1, ""): {u"foo": ('A', None, None)}}) + self.assertEqual({ u'foo': ("1...@uuid::foo", (1, "")) }, map) def test_simple_add(self): - map = self.apply_mappings({(1, ""): {"": ('A', None, None), "foo": ('A', None, None)}}) + map = self.apply_mappings({(1, ""): {u"": ('A', None, None), u"foo": ('A', None, None)}}) self.assertEqual({ - '': ('1...@uuid::', (1, "")), - 'foo': ("1...@uuid::foo", (1, "")) + u'': ('1...@uuid::', (1, "")), + u'foo': ("1...@uuid::foo", (1, "")) }, map) def test_copy(self): def find_children(path, revid): - if path == "foo": - yield "foo/blie" - yield "foo/bla" + if path == u"foo": + yield u"foo/blie" + yield u"foo/bla" map = self.apply_mappings({ (1, ""): { - "foo": ('A', None, None), - "foo/blie": ('A', None, None), - "foo/bla": ('A', None, None)}, + u"foo": ('A', None, None), + u"foo/blie": ('A', None, None), + u"foo/bla": ('A', None, None)}, (2, ""): { - "foob": ('A', 'foo', 1), - "foob/bla": ('M', None, None)} + u"foob": ('A', 'foo', 1), + u"foob/bla": ('M', None, None)} }, find_children) - self.assertTrue(map.has_key("foob/bla")) - self.assertTrue(map.has_key("foob/blie")) + self.assertTrue(map.has_key(u"foob/bla")) + self.assertTrue(map.has_key(u"foob/blie")) def test_touchparent(self): map = self.apply_mappings( {(1, ""): { - "foo": ('A', None, None), - "foo/bla": ('A', None, None)}, + u"foo": ('A', None, None), + u"foo/bla": ('A', None, None)}, (2, ""): { - "foo/bla": ('M', None, None)} + u"foo/bla": ('M', None, None)} }) self.assertEqual((1, ""), - map["foo"][1]) + map[u"foo"][1]) self.assertEqual((1, ""), - map["foo/bla"][1]) + map[u"foo/bla"][1]) def test_usemap(self): map = self.apply_mappings( {(1, ""): { - "foo": ('A', None, None), - "foo/bla": ('A', None, None)}, + u"foo": ('A', None, None), + u"foo/bla": ('A', None, None)}, (2, ""): { - "foo/bla": ('M', None, None)} + u"foo/bla": ('M', None, None)} }, - renames={(1, ""): {"foo": "myid"}}) - self.assertEqual("myid", map["foo"][0]) + renames={(1, ""): {u"foo": "myid"}}) + self.assertEqual("myid", map[u"foo"][0]) def test_usemap_later(self): map = self.apply_mappings( {(1, ""): { - "foo": ('A', None, None), - "foo/bla": ('A', None, None)}, + u"foo": ('A', None, None), + u"foo/bla": ('A', None, None)}, (2, ""): { - "foo/bla": ('M', None, None)} + u"foo/bla": ('M', None, None)} }, - renames={(2, ""): {"foo": "myid"}}) - self.assertEqual("1...@uuid::foo", map["foo"][0]) - self.assertEqual((1, ""), map["foo"][1]) + renames={(2, ""): {u"foo": "myid"}}) + self.assertEqual("1...@uuid::foo", map[u"foo"][0]) + self.assertEqual((1, ""), map[u"foo"][1]) class GetMapTests(SubversionTestCase): -- bazaar-commits mailing list [email protected] https://lists.ubuntu.com/mailman/listinfo/bazaar-commits
