Rev 2321: Use unicode internally in file id determination code rather than converting back and forth, simplify. in http://people.samba.org/bzr/jelmer/bzr-svn/0.5
Jelmer Vernooij
jelmer at samba.org
Sat Jan 17 02:43:00 GMT 2009
At http://people.samba.org/bzr/jelmer/bzr-svn/0.5
------------------------------------------------------------
revno: 2321
revision-id: jelmer at samba.org-20090117024257-hspprbbejc4ux2al
parent: jelmer at samba.org-20090116235749-qf3wl555yvvi44sv
committer: Jelmer Vernooij <jelmer at samba.org>
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 at uuid::foo",
+ map = self.apply_mappings({(1, ""): {u"foo": ('A', None, None)}})
+ self.assertEqual({ u'foo': ("1 at 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 at uuid::', (1, "")),
- 'foo': ("1 at uuid::foo", (1, ""))
+ u'': ('1 at uuid::', (1, "")),
+ u'foo': ("1 at 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 at uuid::foo", map["foo"][0])
- self.assertEqual((1, ""), map["foo"][1])
+ renames={(2, ""): {u"foo": "myid"}})
+ self.assertEqual("1 at uuid::foo", map[u"foo"][0])
+ self.assertEqual((1, ""), map[u"foo"][1])
class GetMapTests(SubversionTestCase):
More information about the bazaar-commits
mailing list