Rev 1860: Store unusual text parents. in file:///data/jelmer/bzr-svn/trunk/

Jelmer Vernooij jelmer at samba.org
Mon Sep 8 05:03:34 BST 2008


At file:///data/jelmer/bzr-svn/trunk/

------------------------------------------------------------
revno: 1860
revision-id: jelmer at samba.org-20080908040330-puze69qhyxmcknam
parent: jelmer at samba.org-20080908012606-4i79s8eslvxlqz27
committer: Jelmer Vernooij <jelmer at samba.org>
branch nick: trunk
timestamp: Mon 2008-09-08 06:03:30 +0200
message:
  Store unusual text parents.
modified:
  NEWS                           news-20061231030336-h9fhq245ie0de8bs-1
  TODO                           todo-20060729211917-2kpobww0zyvvo0j2-1
  commit.py                      commit.py-20060607190346-qvq128wgfubhhgm2-1
  fetch.py                       fetch.py-20060625004942-x2lfaib8ra707a8p-1
  fileids.py                     fileids.py-20060714013623-u5iiyqqnko11grcf-1
  mapping.py                     mapping.py-20080128201303-6cp01phc0dmc0kiv-1
  mapping2.py                    mapping.py-20080904055555-lw057kjuadn0r2ma-2
  mapping3/__init__.py           __init__.py-20080502174630-9324zh25kka98vlw-1
  mapping4.py                    mapping4.py-20080827182338-y4xzpsf43vyiwcir-1
  tests/mapping_implementations/test_base.py test_base.py-20080904055908-3t0g1y0qnmr6aeiq-1
  tests/test_mapping.py          test_mapping.py-20080201131338-0zd86eznn4bojtee-1
  tests/test_push.py             test_push.py-20070201165715-g2ievcdfqi33wqsy-1
  upgrade.py                     upgrade.py-20070106192108-0rakplee2lzah4gs-1
=== modified file 'NEWS'
--- a/NEWS	2008-09-07 22:15:06 +0000
+++ b/NEWS	2008-09-08 04:03:30 +0000
@@ -40,6 +40,8 @@
 
    * Avoid pushing changes again when pushing new branch. (#203368)
 
+   * Store text parents properly. (#260416)
+
   INTERNALS
 
    * Remove custom commit code for working tree. 

=== modified file 'TODO'
--- a/TODO	2008-09-07 22:15:06 +0000
+++ b/TODO	2008-09-08 04:03:30 +0000
@@ -1,6 +1,5 @@
 mappingv4:
  - implement layout functions, including command
- - allow skipping a revision completely - to allow creating branches using "svn cp"
  - create schemes from layouts rather than the other way around
   + remove Mapping.get_guessed_layout()
 - fix update_after_commit test

=== modified file 'commit.py'
--- a/commit.py	2008-09-07 22:15:06 +0000
+++ b/commit.py	2008-09-08 04:03:30 +0000
@@ -154,6 +154,7 @@
         self.branch_path = branch_path
         self.push_metadata = push_metadata
         self._append_revisions_only = append_revisions_only
+        self._text_parents = {}
 
         # Gather information about revision on top of which the commit is 
         # happening
@@ -448,7 +449,7 @@
                     old_inv.id2path(child_ie.file_id) != new_child_path or
                     old_inv[child_ie.file_id].revision != child_ie.revision or
                     old_inv[child_ie.file_id].parent_id != child_ie.parent_id):
-                    ret.append((child_ie.file_id, new_child_path, child_ie.revision))
+                    ret.append((child_ie.file_id, new_child_path, child_ie.revision, self._text_parents[child_ie.file_id]))
 
                 if (child_ie.kind == 'directory' and 
                     child_ie.file_id in self.visit_dirs):
@@ -457,19 +458,23 @@
 
         fileids = {}
         text_parents = {}
+        text_revisions = {}
         changes = []
 
         if (self.old_inv.root is None or 
             self.new_inventory.root.file_id != self.old_inv.root.file_id):
-            changes.append((self.new_inventory.root.file_id, "", self.new_inventory.root.revision))
+            changes.append((self.new_inventory.root.file_id, "", self.new_inventory.root.revision, self._text_parents[self.new_inventory.root.file_id]))
 
         changes += _dir_process_file_id(self.old_inv, self.new_inventory, "", self.new_inventory.root.file_id)
 
-        for id, path, revid in changes:
+        for id, path, revid, parents in changes:
             fileids[path] = id
             if revid is not None and revid != self.base_revid and revid != self._new_revision_id:
-                text_parents[path] = revid
-        return (fileids, text_parents)
+                text_revisions[path] = revid
+            if ((id not in self.old_inv and parents != []) or 
+                (id in self.old_inv and parents != [self.base_revid])):
+                text_parents[path] = parents
+        return (fileids, text_revisions, text_parents)
 
     def commit(self, message):
         """Finish the commit.
@@ -490,8 +495,9 @@
         self._changed_fileprops = {}
 
         if self.push_metadata:
-            (fileids, text_parents) = self._determine_texts_identity()
+            (fileids, text_revisions, text_parents) = self._determine_texts_identity()
 
+            self.base_mapping.export_text_revisions(text_revisions, self._svn_revprops, self._svnprops)
             self.base_mapping.export_text_parents(text_parents, self._svn_revprops, self._svnprops)
             self.base_mapping.export_fileid_map(fileids, self._svn_revprops, self._svnprops)
             if self._config.get_log_strip_trailing_newline():
@@ -619,6 +625,10 @@
                 accessed when the entry has a revision of None - that is when 
                 it is a candidate to commit.
         """
+        self._text_parents[ie.file_id] = []
+        for parent_inv in parent_invs:
+            if ie.file_id in parent_inv:
+                self._text_parents[ie.file_id].append(parent_inv[ie.file_id].revision)
         self.new_inventory.add(ie)
         assert (ie.file_id not in self.old_inv or 
                 self.old_inv[ie.file_id].revision is not None)

=== modified file 'fetch.py'
--- a/fetch.py	2008-09-07 22:15:06 +0000
+++ b/fetch.py	2008-09-08 04:03:30 +0000
@@ -227,9 +227,11 @@
             assert self.editor.revid is not None
             ie.revision = self.editor.revid
 
+            text_revision = self.editor._get_text_revid(self.path) or ie.revision
+            text_parents = self.editor._get_text_parents(self.path) or self.parent_revids
             self.editor.texts.add_lines(
-                (self.new_id, self.editor._get_text_revid(self.path) or ie.revision),
-                [(self.new_id, revid) for revid in self.parent_revids], [])
+                (self.new_id, text_revision),
+                [(self.new_id, revid) for revid in text_parents], [])
 
         if self.new_id == self.editor.inventory.root.file_id:
             assert self.editor.inventory.root.revision is not None
@@ -340,8 +342,10 @@
         actual_checksum = md5_strings(lines)
         assert checksum is None or checksum == actual_checksum
 
-        self.editor.texts.add_lines((self.file_id, self.editor._get_text_revid(self.path) or self.editor.revid), 
-                [(self.file_id, revid) for revid in self.file_parents], lines)
+        text_revision = self.editor._get_text_revid(self.path) or self.editor.revid
+        text_parents = self.editor._get_text_parents(self.path) or self.file_parents
+        self.editor.texts.add_lines((self.file_id, text_revision), 
+            [(self.file_id, revid) for revid in text_parents], lines)
 
         if self.is_special is not None:
             self.is_symlink = (self.is_special and len(lines) > 0 and lines[0].startswith("link "))
@@ -382,6 +386,7 @@
         self.texts = target.texts
         self.revid = revid
         self._text_revids = None
+        self._text_parents = None
         self._premature_deletes = set()
         self.old_inventory = prev_inventory
         self.inventory = prev_inventory.copy()
@@ -470,10 +475,13 @@
 
     def _get_text_revid(self, path):
         if self._text_revids is None:
-            self._text_revids = self.mapping.import_text_parents(self.revmeta.get_revprops(), 
-                                                                 self.revmeta.get_changed_fileprops())
+            self._text_revids = self.mapping.import_text_revisions(self.revmeta.get_revprops(), self.revmeta.get_changed_fileprops())
         return self._text_revids.get(path)
 
+    def _get_text_parents(self, path):
+        if self._text_parents is None:
+            self._text_parents = self.mapping.import_text_parents(self.revmeta.get_revprops(), self.revmeta.get_changed_fileprops())
+        return self._text_parents.get(path)
 
 
 class FileTreeDeltaBuildEditor(FileBuildEditor):

=== modified file 'fileids.py'
--- a/fileids.py	2008-09-07 22:15:06 +0000
+++ b/fileids.py	2008-09-08 04:03:30 +0000
@@ -114,7 +114,7 @@
         self.repos = repos
 
     def _use_text_revids(self, mapping, revmeta, map):
-        text_revids = mapping.import_text_parents(revmeta.get_revprops(), revmeta.get_changed_fileprops()).items()
+        text_revids = mapping.import_text_revisions(revmeta.get_revprops(), revmeta.get_changed_fileprops()).items()
         for path, revid in text_revids:
             assert path in map
             map[path] = (map[path][0], revid)

=== modified file 'mapping.py'
--- a/mapping.py	2008-09-07 23:43:34 +0000
+++ b/mapping.py	2008-09-08 04:03:30 +0000
@@ -30,6 +30,7 @@
 SVN_PROP_BZR_FILEIDS = 'bzr:file-ids'
 SVN_PROP_BZR_REVISION_INFO = 'bzr:revision-info'
 SVN_PROP_BZR_REVISION_ID = 'bzr:revision-id:'
+SVN_PROP_BZR_TEXT_REVISIONS = 'bzr:text-revisions'
 SVN_PROP_BZR_TEXT_PARENTS = 'bzr:text-parents'
 SVN_PROP_BZR_LOG = 'bzr:log'
 SVN_PROP_BZR_REQUIRED_FEATURES = 'bzr:required-features'
@@ -47,6 +48,7 @@
 SVN_REVPROP_BZR_TIMESTAMP = 'bzr:timestamp'
 SVN_REVPROP_BZR_LOG = 'bzr:log'
 SVN_REVPROP_BZR_TEXT_PARENTS = 'bzr:text-parents'
+SVN_REVPROP_BZR_TEXT_REVISIONS = 'bzr:text-revisions'
 SVN_REVPROP_BZR_REQUIRED_FEATURES = 'bzr:required-features'
 SVN_REVPROP_BZR_BASE_REVISION = 'bzr:base-revision'
 SVN_REVPROP_BZR_SKIP = 'bzr:skip'
@@ -419,6 +421,12 @@
         """
         raise NotImplementedError(self.export_text_parents)
 
+    def export_text_revisions(self, text_revisions, revprops, fileprops):
+        raise NotImplementedError(self.export_text_revisions)
+
+    def import_text_revisions(self, revprops, fileprops):
+        raise NotImplementedError(self.import_text_revisions)
+
     def export_revision(self, branch_root, timestamp, timezone, committer, revprops, revision_id, revno, parent_ids, svn_revprops, svn_fileprops):
         """Determines the revision properties and branch root file 
         properties.
@@ -467,13 +475,26 @@
 def parse_text_parents_property(text):
     ret = {}
     for line in text.splitlines():
-        (entry, parent_revid) = line.split("\t", 1)
-        ret[urllib.unquote(entry)] = osutils.safe_revision_id(parent_revid)
+        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:]])
+    return ret
+
+
+def parse_text_revisions_property(text):
+    ret = {}
+    for line in text.splitlines():
+        (entry, revid) = line.split("\t", 1)
+        ret[urllib.unquote(entry)] = osutils.safe_revision_id(revid)
     return ret
 
 
 def generate_text_parents_property(text_parents):
-    return "".join(["%s\t%s\n" % (urllib.quote(path.encode("utf-8")), text_parents[path]) for path in sorted(text_parents.keys())])
+    return "".join(["%s\t%s\n" % (urllib.quote(path.encode("utf-8")), "\t".join(text_parents[path])) for path in sorted(text_parents.keys())])
+
+
+def generate_text_revisions_property(text_revisions):
+    return "".join(["%s\t%s\n" % (urllib.quote(path.encode("utf-8")), text_revisions[path]) for path in sorted(text_revisions.keys())])
 
 
 class BzrSvnMappingFileProps(object):
@@ -488,6 +509,12 @@
         if metadata is not None:
             parse_revision_metadata(metadata, rev)
 
+    def import_text_revisions(self, svn_revprops, fileprops):
+        metadata = fileprops.get(SVN_PROP_BZR_TEXT_REVISIONS)
+        if metadata is None:
+            return {}
+        return parse_text_revisions_property(metadata)
+
     def import_text_parents(self, svn_revprops, fileprops):
         metadata = fileprops.get(SVN_PROP_BZR_TEXT_PARENTS)
         if metadata is None:
@@ -500,6 +527,12 @@
         elif SVN_PROP_BZR_TEXT_PARENTS in fileprops:
             fileprops[SVN_PROP_BZR_TEXT_PARENTS] = ""
 
+    def export_text_revisions(self, text_revisions, svn_revprops, fileprops):
+        if text_revisions != {}:
+            fileprops[SVN_PROP_BZR_TEXT_REVISIONS] = generate_text_revisions_property(text_revisions)
+        elif SVN_PROP_BZR_TEXT_REVISIONS in fileprops:
+            fileprops[SVN_PROP_BZR_TEXT_REVISIONS] = ""
+
     def get_rhs_parents(self, branch_path, revprops, fileprops):
         bzr_merges = fileprops.get(SVN_PROP_BZR_ANCESTRY+self.name, None)
         if bzr_merges is not None:
@@ -591,6 +624,15 @@
         if text_parents != {}:
             svn_revprops[SVN_REVPROP_BZR_TEXT_PARENTS] = generate_text_parents_property(text_parents)
 
+    def import_text_revisions(self, svn_revprops, fileprops):
+        if not svn_revprops.has_key(SVN_REVPROP_BZR_TEXT_REVISIONS):
+            return {}
+        return parse_text_revisions_property(svn_revprops[SVN_REVPROP_BZR_TEXT_REVISIONS])
+
+    def export_text_revisions(self, text_revisions, svn_revprops, fileprops):
+        if text_revisions != {}:
+            svn_revprops[SVN_REVPROP_BZR_TEXT_REVISIONS] = generate_text_revisions_property(text_revisions)
+
     def get_lhs_parent(self, branch_parent, svn_revprops, fileprops):
         return svn_revprops.get(SVN_REVPROP_BZR_BASE_REVISION)
 

=== modified file 'mapping2.py'
--- a/mapping2.py	2008-09-05 17:12:11 +0000
+++ b/mapping2.py	2008-09-08 04:03:30 +0000
@@ -76,6 +76,9 @@
     def import_text_parents(self, revprops, fileprops):
         return {}
 
+    def import_text_revisions(self, svn_revprops, fileprops):
+        return {}
+
     def get_rhs_parents(self, branch_path, revprops, fileprops):
         value = fileprops.get(SVN_PROP_BZR_MERGE, "")
         if value == "":

=== modified file 'mapping3/__init__.py'
--- a/mapping3/__init__.py	2008-09-06 22:49:08 +0000
+++ b/mapping3/__init__.py	2008-09-08 04:03:30 +0000
@@ -289,6 +289,11 @@
         if svn_revprops is not None:
             self.revprop_map.export_text_parents(text_parents, svn_revprops, fileprops)
 
+    def export_text_revisions(self, text_revisions, svn_revprops, fileprops):
+        mapping.BzrSvnMappingFileProps.export_text_revisions(self, text_revisions, svn_revprops, fileprops)
+        if svn_revprops is not None:
+            self.revprop_map.export_text_revisions(text_revisions, svn_revprops, fileprops)
+
     def export_revision(self, branch_root, timestamp, timezone, committer, revprops, revision_id, revno, parent_ids, svn_revprops, svn_fileprops):
         mapping.BzrSvnMappingFileProps.export_revision(self, branch_root, timestamp, timezone, committer, revprops, revision_id, revno, parent_ids, svn_revprops, svn_fileprops)
         if svn_revprops is not None:

=== modified file 'mapping4.py'
--- a/mapping4.py	2008-09-07 22:15:06 +0000
+++ b/mapping4.py	2008-09-08 04:03:30 +0000
@@ -107,6 +107,12 @@
         else:
             return self.fileprops.import_text_parents(svn_revprops, fileprops)
 
+    def import_text_revisions(self, svn_revprops, fileprops):
+        if svn_revprops.has_key(mapping.SVN_REVPROP_BZR_TEXT_REVISIONS):
+            return self.revprops.import_text_revisions(svn_revprops, fileprops)
+        else:
+            return self.fileprops.import_text_revisions(svn_revprops, fileprops)
+
     def import_fileid_map(self, svn_revprops, fileprops):
         if svn_revprops.has_key(mapping.SVN_REVPROP_BZR_MAPPING_VERSION):
             return self.revprops.import_fileid_map(svn_revprops, fileprops)
@@ -135,6 +141,12 @@
         else:
             self.fileprops.export_text_parents(text_parents, revprops, fileprops)
 
+    def export_text_revisions(self, text_revisions, revprops, fileprops):
+        if revprops is not None:
+            self.revprops.export_text_revisions(text_revisions, revprops, fileprops)
+        else:
+            self.fileprops.export_text_revisions(text_revisions, revprops, fileprops)
+
     def import_revision(self, svn_revprops, fileprops, uuid, branch, revnum, rev):
         if svn_revprops.has_key(mapping.SVN_REVPROP_BZR_REQUIRED_FEATURES):
             features = mapping.parse_required_features_property(svn_revprops[mapping.SVN_REVPROP_BZR_REQUIRED_FEATURES])

=== modified file 'tests/mapping_implementations/test_base.py'
--- a/tests/mapping_implementations/test_base.py	2008-09-04 07:58:37 +0000
+++ b/tests/mapping_implementations/test_base.py	2008-09-08 04:03:30 +0000
@@ -50,11 +50,21 @@
             raise TestNotApplicable
         revprops = {}
         fileprops = {}
-        text_parents = {"bla": "bloe", "ll": "12"}
+        text_parents = {"bla": ["bloe"], "ll": ["12", "bli"]}
         self.mapping.export_text_parents(text_parents, revprops, fileprops)
         self.assertEquals(text_parents,
             self.mapping.import_text_parents(revprops, fileprops))
 
+    def test_text_revisions(self):
+        if not self.mapping.roundtripping:
+            raise TestNotApplicable
+        revprops = {}
+        fileprops = {}
+        text_revisions = {"bla": "bloe", "ll": "12"}
+        self.mapping.export_text_revisions(text_revisions, revprops, fileprops)
+        self.assertEquals(text_revisions,
+            self.mapping.import_text_revisions(revprops, fileprops))
+
     def test_message(self):
         if not self.mapping.roundtripping:
             raise TestNotApplicable

=== modified file 'tests/test_mapping.py'
--- a/tests/test_mapping.py	2008-09-04 08:11:08 +0000
+++ b/tests/test_mapping.py	2008-09-08 04:03:30 +0000
@@ -115,7 +115,7 @@
 
 class ParseTextParentsTestCase(TestCase):
     def test_text_parents(self):
-        self.assertEquals({"bla": "bloe"}, parse_text_parents_property("bla\tbloe\n"))
+        self.assertEquals({"bla": ["bloe"]}, parse_text_parents_property("bla\tbloe\n"))
 
     def test_text_parents_empty(self):
         self.assertEquals({}, parse_text_parents_property(""))
@@ -126,7 +126,7 @@
         self.assertEquals("", generate_text_parents_property({}))
 
     def test_generate_simple(self):
-        self.assertEquals("bla\tbloe\n", generate_text_parents_property({"bla": "bloe"}))
+        self.assertEquals("bla\tbloe\n", generate_text_parents_property({"bla": ["bloe"]}))
 
 
 class ParseMergePropertyTestCase(TestCase):

=== modified file 'tests/test_push.py'
--- a/tests/test_push.py	2008-09-04 09:40:03 +0000
+++ b/tests/test_push.py	2008-09-08 04:03:30 +0000
@@ -617,7 +617,7 @@
         wt1.branch.push(Branch.open(repos_url+"/trunk"))
         r = Repository.open(repos_url)
         props = r._revmeta_provider.get_revision("trunk", 3).get_changed_fileprops()
-        self.assertEquals(props['bzr:text-parents'], 'bar2.txt\tside1\n')
+        self.assertEquals(props['bzr:text-revisions'], 'bar2.txt\tside1\n')
 
         os.mkdir("cpy")
         cpy = BzrDir.create("cpy", format.get_rich_root_format())

=== modified file 'upgrade.py'
--- a/upgrade.py	2008-09-07 22:15:06 +0000
+++ b/upgrade.py	2008-09-08 04:03:30 +0000
@@ -276,8 +276,8 @@
             new_mapping.export_revision(bp, rev.timestamp, rev.timezone, rev.committer, rev.properties, rev.revision_id, revno, rev.parent_ids, new_revprops, None)
             new_mapping.export_fileid_map(old_mapping.import_fileid_map(revprops, fileprops), 
                 new_revprops, None)
-            new_mapping.export_text_parents(old_mapping.import_text_parents(revprops, fileprops),
-                new_revprops, None)
+            new_mapping.export_text_parents(old_mapping.import_text_parents(revprops, fileprops), new_revprops, None)
+            new_mapping.export_text_revisions(old_mapping.import_text_revisions(revprops, fileprops), new_revprops, None)
             if rev.message != mapping.parse_svn_log(revprops.get(properties.PROP_REVISION_LOG)):
                 new_mapping.export_message(rev.message, new_revprops, None)
             changed_revprops = dict(filter(lambda (k,v): k not in revprops or revprops[k] != v, new_revprops.items()))




More information about the bazaar-commits mailing list