bzr branch
http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
| 1773.4.1
by Martin Pool Add pyflakes makefile target; fix many warnings | 1 | # Copyright (C) 2005, 2006 Canonical Ltd
 | 
| 2 | #
 | |
| 1189
by Martin Pool - BROKEN: partial support for commit into weave | 3 | # This program is free software; you can redistribute it and/or modify
 | 
| 4 | # it under the terms of the GNU General Public License as published by
 | |
| 5 | # the Free Software Foundation; either version 2 of the License, or
 | |
| 6 | # (at your option) any later version.
 | |
| 1887.1.1
by Adeodato Simó Do not separate paragraphs in the copyright statement with blank lines, | 7 | #
 | 
| 1189
by Martin Pool - BROKEN: partial support for commit into weave | 8 | # This program is distributed in the hope that it will be useful,
 | 
| 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
| 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
| 11 | # GNU General Public License for more details.
 | |
| 1887.1.1
by Adeodato Simó Do not separate paragraphs in the copyright statement with blank lines, | 12 | #
 | 
| 1189
by Martin Pool - BROKEN: partial support for commit into weave | 13 | # You should have received a copy of the GNU General Public License
 | 
| 14 | # along with this program; if not, write to the Free Software
 | |
| 15 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | |
| 16 | ||
| 1934.1.3
by John Arbash Meinel [merge] robert's custom XML serializer, and cleanup for benchmarks and iter_entries() differences | 17 | import cStringIO | 
| 1934.1.4
by John Arbash Meinel rewrite escaper to use xml numerical entities, rather than using encode('utf8') | 18 | import re | 
| 1189
by Martin Pool - BROKEN: partial support for commit into weave | 19 | |
| 1911.2.6
by John Arbash Meinel Cache revision ids and file ids as part of xml processing. A custom xml parser could just call decode/encode directly. | 20 | from bzrlib import ( | 
| 21 | cache_utf8, | |
| 1934.1.3
by John Arbash Meinel [merge] robert's custom XML serializer, and cleanup for benchmarks and iter_entries() differences | 22 | inventory, | 
| 1911.2.6
by John Arbash Meinel Cache revision ids and file ids as part of xml processing. A custom xml parser could just call decode/encode directly. | 23 |     )
 | 
| 1773.4.1
by Martin Pool Add pyflakes makefile target; fix many warnings | 24 | from bzrlib.xml_serializer import SubElement, Element, Serializer | 
| 1189
by Martin Pool - BROKEN: partial support for commit into weave | 25 | from bzrlib.inventory import ROOT_ID, Inventory, InventoryEntry | 
| 1773.4.1
by Martin Pool Add pyflakes makefile target; fix many warnings | 26 | from bzrlib.revision import Revision | 
| 1189
by Martin Pool - BROKEN: partial support for commit into weave | 27 | from bzrlib.errors import BzrError | 
| 28 | ||
| 29 | ||
| 1934.1.4
by John Arbash Meinel rewrite escaper to use xml numerical entities, rather than using encode('utf8') | 30 | _utf8_re = None | 
| 31 | _utf8_escape_map = { | |
| 32 | "&":'&', | |
| 33 | "'":"'", # FIXME: overkill | |
| 34 | "\"":""", | |
| 35 | "<":"<", | |
| 36 | ">":">", | |
| 37 |     }
 | |
| 38 | ||
| 39 | ||
| 40 | def _ensure_utf8_re(): | |
| 41 | """Make sure the _utf8_re regex has been compiled""" | |
| 42 | global _utf8_re | |
| 43 | if _utf8_re is not None: | |
| 44 |         return
 | |
| 1934.1.12
by John Arbash Meinel Switch back to using Entity serializer, since performance is equivalent, yet still compatible | 45 | _utf8_re = re.compile(u'[&<>\'\"\u0080-\uffff]') | 
| 1934.1.4
by John Arbash Meinel rewrite escaper to use xml numerical entities, rather than using encode('utf8') | 46 | |
| 47 | ||
| 48 | def _utf8_escape_replace(match, _map=_utf8_escape_map): | |
| 49 | """Replace a string of non-ascii, non XML safe characters with their escape | |
| 50 | ||
| 51 |     This will escape both Standard XML escapes, like <>"', etc.
 | |
| 52 |     As well as escaping non ascii characters, because ElementTree did.
 | |
| 53 |     This helps us remain compatible to older versions of bzr. We may change
 | |
| 54 |     our policy in the future, though.
 | |
| 55 |     """
 | |
| 1934.1.7
by John Arbash Meinel Comment why we do caching the way we do | 56 |     # jam 20060816 Benchmarks show that try/KeyError is faster if you
 | 
| 57 |     # expect the entity to rarely miss. There is about a 10% difference
 | |
| 58 |     # in overall time. But if you miss frequently, then if None is much
 | |
| 59 |     # faster. For our use case, we *rarely* have a revision id, file id
 | |
| 60 |     # or path name that is unicode. So use try/KeyError.
 | |
| 1934.1.12
by John Arbash Meinel Switch back to using Entity serializer, since performance is equivalent, yet still compatible | 61 | try: | 
| 62 | return _map[match.group()] | |
| 63 | except KeyError: | |
| 64 | return "&#%d;" % ord(match.group()) | |
| 1934.1.4
by John Arbash Meinel rewrite escaper to use xml numerical entities, rather than using encode('utf8') | 65 | |
| 66 | ||
| 1934.1.5
by John Arbash Meinel Cache the entity escaping cuts us down to 450ms | 67 | _unicode_to_escaped_map = {} | 
| 68 | ||
| 1934.1.12
by John Arbash Meinel Switch back to using Entity serializer, since performance is equivalent, yet still compatible | 69 | def _encode_and_escape(unicode_str, _map=_unicode_to_escaped_map): | 
| 1934.1.4
by John Arbash Meinel rewrite escaper to use xml numerical entities, rather than using encode('utf8') | 70 | """Encode the string into utf8, and escape invalid XML characters""" | 
| 1934.1.7
by John Arbash Meinel Comment why we do caching the way we do | 71 |     # We frequently get entities we have not seen before, so it is better
 | 
| 72 |     # to check if None, rather than try/KeyError
 | |
| 1934.1.5
by John Arbash Meinel Cache the entity escaping cuts us down to 450ms | 73 | text = _map.get(unicode_str) | 
| 74 | if text is None: | |
| 1934.1.4
by John Arbash Meinel rewrite escaper to use xml numerical entities, rather than using encode('utf8') | 75 |         # The alternative policy is to do a regular UTF8 encoding
 | 
| 1934.1.12
by John Arbash Meinel Switch back to using Entity serializer, since performance is equivalent, yet still compatible | 76 |         # and then escape only XML meta characters.
 | 
| 77 |         # Performance is equivalent once you use cache_utf8. *However*
 | |
| 78 |         # this makes the serialized texts incompatible with old versions
 | |
| 79 |         # of bzr. So no net gain. (Perhaps the read code would handle utf8
 | |
| 80 |         # better than entity escapes, but cElementTree seems to do just fine
 | |
| 81 |         # either way)
 | |
| 82 | text = str(_utf8_re.sub(_utf8_escape_replace, unicode_str)) + '"' | |
| 1934.1.4
by John Arbash Meinel rewrite escaper to use xml numerical entities, rather than using encode('utf8') | 83 | _map[unicode_str] = text | 
| 1934.1.5
by John Arbash Meinel Cache the entity escaping cuts us down to 450ms | 84 | return text | 
| 85 | ||
| 86 | ||
| 87 | def _clear_cache(): | |
| 88 | """Clean out the unicode => escaped map""" | |
| 89 | _unicode_to_escaped_map.clear() | |
| 1934.1.4
by John Arbash Meinel rewrite escaper to use xml numerical entities, rather than using encode('utf8') | 90 | |
| 91 | ||
| 1189
by Martin Pool - BROKEN: partial support for commit into weave | 92 | class Serializer_v5(Serializer): | 
| 93 | """Version 5 serializer | |
| 94 | ||
| 95 |     Packs objects into XML and vice versa.
 | |
| 96 |     """
 | |
| 97 | ||
| 1934.1.4
by John Arbash Meinel rewrite escaper to use xml numerical entities, rather than using encode('utf8') | 98 | __slots__ = [] | 
| 1934.1.3
by John Arbash Meinel [merge] robert's custom XML serializer, and cleanup for benchmarks and iter_entries() differences | 99 | |
| 100 | def write_inventory_to_string(self, inv): | |
| 1934.1.4
by John Arbash Meinel rewrite escaper to use xml numerical entities, rather than using encode('utf8') | 101 | """Just call write_inventory with a StringIO and return the value""" | 
| 1934.1.3
by John Arbash Meinel [merge] robert's custom XML serializer, and cleanup for benchmarks and iter_entries() differences | 102 | sio = cStringIO.StringIO() | 
| 103 | self.write_inventory(inv, sio) | |
| 104 | return sio.getvalue() | |
| 105 | ||
| 106 | def write_inventory(self, inv, f): | |
| 107 | """Write inventory to a file. | |
| 108 |         
 | |
| 109 |         :param inv: the inventory to write.
 | |
| 110 |         :param f: the file to write.
 | |
| 111 |         """
 | |
| 1934.1.4
by John Arbash Meinel rewrite escaper to use xml numerical entities, rather than using encode('utf8') | 112 | _ensure_utf8_re() | 
| 1934.1.3
by John Arbash Meinel [merge] robert's custom XML serializer, and cleanup for benchmarks and iter_entries() differences | 113 | output = [] | 
| 1934.1.8
by John Arbash Meinel Passing around the append function rather than the list shaves off another 10%, down to 400ms | 114 | append = output.append | 
| 115 | self._append_inventory_root(append, inv) | |
| 1934.1.3
by John Arbash Meinel [merge] robert's custom XML serializer, and cleanup for benchmarks and iter_entries() differences | 116 | entries = inv.iter_entries() | 
| 1934.1.4
by John Arbash Meinel rewrite escaper to use xml numerical entities, rather than using encode('utf8') | 117 |         # Skip the root
 | 
| 1934.1.3
by John Arbash Meinel [merge] robert's custom XML serializer, and cleanup for benchmarks and iter_entries() differences | 118 | root_path, root_ie = entries.next() | 
| 119 | for path, ie in entries: | |
| 1934.1.8
by John Arbash Meinel Passing around the append function rather than the list shaves off another 10%, down to 400ms | 120 | self._append_entry(append, ie) | 
| 121 | append('</inventory>\n') | |
| 1934.1.4
by John Arbash Meinel rewrite escaper to use xml numerical entities, rather than using encode('utf8') | 122 | f.writelines(output) | 
| 1934.1.5
by John Arbash Meinel Cache the entity escaping cuts us down to 450ms | 123 |         # Just to keep the cache from growing without bounds
 | 
| 124 |         # but we may actually not want to do clear the cache
 | |
| 1934.1.6
by John Arbash Meinel With a full cache the time is down to 381 ms | 125 |         #_clear_cache()
 | 
| 1934.1.3
by John Arbash Meinel [merge] robert's custom XML serializer, and cleanup for benchmarks and iter_entries() differences | 126 | |
| 1934.1.8
by John Arbash Meinel Passing around the append function rather than the list shaves off another 10%, down to 400ms | 127 | def _append_inventory_root(self, append, inv): | 
| 1934.1.3
by John Arbash Meinel [merge] robert's custom XML serializer, and cleanup for benchmarks and iter_entries() differences | 128 | """Append the inventory root to output.""" | 
| 1934.1.8
by John Arbash Meinel Passing around the append function rather than the list shaves off another 10%, down to 400ms | 129 | append('<inventory') | 
| 1934.1.3
by John Arbash Meinel [merge] robert's custom XML serializer, and cleanup for benchmarks and iter_entries() differences | 130 | if inv.root.file_id not in (None, ROOT_ID): | 
| 1934.1.8
by John Arbash Meinel Passing around the append function rather than the list shaves off another 10%, down to 400ms | 131 | append(' file_id="') | 
| 1934.1.9
by John Arbash Meinel Caching the trailing " and directly appending, down another 50ms, 275ms cached, 354ms uncached | 132 | append(_encode_and_escape(inv.root.file_id)) | 
| 1934.1.8
by John Arbash Meinel Passing around the append function rather than the list shaves off another 10%, down to 400ms | 133 | append(' format="5"') | 
| 1934.1.3
by John Arbash Meinel [merge] robert's custom XML serializer, and cleanup for benchmarks and iter_entries() differences | 134 | if inv.revision_id is not None: | 
| 1934.1.8
by John Arbash Meinel Passing around the append function rather than the list shaves off another 10%, down to 400ms | 135 | append(' revision_id="') | 
| 1934.1.9
by John Arbash Meinel Caching the trailing " and directly appending, down another 50ms, 275ms cached, 354ms uncached | 136 | append(_encode_and_escape(inv.revision_id)) | 
| 1934.1.8
by John Arbash Meinel Passing around the append function rather than the list shaves off another 10%, down to 400ms | 137 | append('>\n') | 
| 1934.1.3
by John Arbash Meinel [merge] robert's custom XML serializer, and cleanup for benchmarks and iter_entries() differences | 138 | |
| 1934.1.8
by John Arbash Meinel Passing around the append function rather than the list shaves off another 10%, down to 400ms | 139 | def _append_entry(self, append, ie): | 
| 1934.1.3
by John Arbash Meinel [merge] robert's custom XML serializer, and cleanup for benchmarks and iter_entries() differences | 140 | """Convert InventoryEntry to XML element and append to output.""" | 
| 141 |         # TODO: should just be a plain assertion
 | |
| 142 | assert InventoryEntry.versionable_kind(ie.kind), \ | |
| 143 | 'unsupported entry kind %s' % ie.kind | |
| 144 | ||
| 1934.1.8
by John Arbash Meinel Passing around the append function rather than the list shaves off another 10%, down to 400ms | 145 | append("<") | 
| 146 | append(ie.kind) | |
| 1934.1.3
by John Arbash Meinel [merge] robert's custom XML serializer, and cleanup for benchmarks and iter_entries() differences | 147 | if ie.executable: | 
| 1934.1.8
by John Arbash Meinel Passing around the append function rather than the list shaves off another 10%, down to 400ms | 148 | append(' executable="yes"') | 
| 149 | append(' file_id="') | |
| 1934.1.9
by John Arbash Meinel Caching the trailing " and directly appending, down another 50ms, 275ms cached, 354ms uncached | 150 | append(_encode_and_escape(ie.file_id)) | 
| 1934.1.8
by John Arbash Meinel Passing around the append function rather than the list shaves off another 10%, down to 400ms | 151 | append(' name="') | 
| 1934.1.9
by John Arbash Meinel Caching the trailing " and directly appending, down another 50ms, 275ms cached, 354ms uncached | 152 | append(_encode_and_escape(ie.name)) | 
| 1934.1.3
by John Arbash Meinel [merge] robert's custom XML serializer, and cleanup for benchmarks and iter_entries() differences | 153 | if ie.parent_id != ROOT_ID: | 
| 154 | assert isinstance(ie.parent_id, basestring) | |
| 1934.1.8
by John Arbash Meinel Passing around the append function rather than the list shaves off another 10%, down to 400ms | 155 | append(' parent_id="') | 
| 1934.1.9
by John Arbash Meinel Caching the trailing " and directly appending, down another 50ms, 275ms cached, 354ms uncached | 156 | append(_encode_and_escape(ie.parent_id)) | 
| 1934.1.3
by John Arbash Meinel [merge] robert's custom XML serializer, and cleanup for benchmarks and iter_entries() differences | 157 | if ie.revision is not None: | 
| 1934.1.8
by John Arbash Meinel Passing around the append function rather than the list shaves off another 10%, down to 400ms | 158 | append(' revision="') | 
| 1934.1.9
by John Arbash Meinel Caching the trailing " and directly appending, down another 50ms, 275ms cached, 354ms uncached | 159 | append(_encode_and_escape(ie.revision)) | 
| 1934.1.3
by John Arbash Meinel [merge] robert's custom XML serializer, and cleanup for benchmarks and iter_entries() differences | 160 | if ie.symlink_target is not None: | 
| 1934.1.8
by John Arbash Meinel Passing around the append function rather than the list shaves off another 10%, down to 400ms | 161 | append(' symlink_target="') | 
| 1934.1.9
by John Arbash Meinel Caching the trailing " and directly appending, down another 50ms, 275ms cached, 354ms uncached | 162 | append(_encode_and_escape(ie.symlink_target)) | 
| 1934.1.3
by John Arbash Meinel [merge] robert's custom XML serializer, and cleanup for benchmarks and iter_entries() differences | 163 | if ie.text_sha1 is not None: | 
| 1934.1.15
by John Arbash Meinel One field was incorrect, need text_sha1 not text_size | 164 | append(' text_sha1="') | 
| 1934.1.8
by John Arbash Meinel Passing around the append function rather than the list shaves off another 10%, down to 400ms | 165 | append(ie.text_sha1) | 
| 166 | append('"') | |
| 1934.1.3
by John Arbash Meinel [merge] robert's custom XML serializer, and cleanup for benchmarks and iter_entries() differences | 167 | if ie.text_size is not None: | 
| 1934.1.8
by John Arbash Meinel Passing around the append function rather than the list shaves off another 10%, down to 400ms | 168 | append(' text_size="%d"' % ie.text_size) | 
| 169 | append(" />\n") | |
| 1934.1.3
by John Arbash Meinel [merge] robert's custom XML serializer, and cleanup for benchmarks and iter_entries() differences | 170 |         return
 | 
| 171 | ||
| 1189
by Martin Pool - BROKEN: partial support for commit into weave | 172 | def _pack_revision(self, rev): | 
| 173 | """Revision object -> xml tree""" | |
| 174 | root = Element('revision', | |
| 175 | committer = rev.committer, | |
| 176 | timestamp = '%.9f' % rev.timestamp, | |
| 177 | revision_id = rev.revision_id, | |
| 178 | inventory_sha1 = rev.inventory_sha1, | |
| 1393.1.59
by Martin Pool - put 'format=5' on inventory and revision xml | 179 | format='5', | 
| 1189
by Martin Pool - BROKEN: partial support for commit into weave | 180 |                        )
 | 
| 1913.1.1
by John Arbash Meinel Fix bug #55783 | 181 | if rev.timezone is not None: | 
| 1189
by Martin Pool - BROKEN: partial support for commit into weave | 182 | root.set('timezone', str(rev.timezone)) | 
| 183 | root.text = '\n' | |
| 184 | msg = SubElement(root, 'message') | |
| 185 | msg.text = rev.message | |
| 186 | msg.tail = '\n' | |
| 1313
by Martin Pool - rename to Revision.parent_ids to avoid confusion with old usage | 187 | if rev.parent_ids: | 
| 1189
by Martin Pool - BROKEN: partial support for commit into weave | 188 | pelts = SubElement(root, 'parents') | 
| 189 | pelts.tail = pelts.text = '\n' | |
| 1313
by Martin Pool - rename to Revision.parent_ids to avoid confusion with old usage | 190 | for parent_id in rev.parent_ids: | 
| 1311
by Martin Pool - remove RevisionReference; just hold parent ids directly | 191 | assert isinstance(parent_id, basestring) | 
| 1189
by Martin Pool - BROKEN: partial support for commit into weave | 192 | p = SubElement(pelts, 'revision_ref') | 
| 193 | p.tail = '\n' | |
| 1311
by Martin Pool - remove RevisionReference; just hold parent ids directly | 194 | p.set('revision_id', parent_id) | 
| 1185.16.36
by Martin Pool - store revision properties in revision xml | 195 | if rev.properties: | 
| 196 | self._pack_revision_properties(rev, root) | |
| 1189
by Martin Pool - BROKEN: partial support for commit into weave | 197 | return root | 
| 1185.16.36
by Martin Pool - store revision properties in revision xml | 198 | |
| 199 | def _pack_revision_properties(self, rev, under_element): | |
| 200 | top_elt = SubElement(under_element, 'properties') | |
| 201 | for prop_name, prop_value in sorted(rev.properties.items()): | |
| 202 | assert isinstance(prop_name, basestring) | |
| 203 | assert isinstance(prop_value, basestring) | |
| 204 | prop_elt = SubElement(top_elt, 'property') | |
| 205 | prop_elt.set('name', prop_name) | |
| 206 | prop_elt.text = prop_value | |
| 207 | prop_elt.tail = '\n' | |
| 208 | top_elt.tail = '\n' | |
| 209 | ||
| 1189
by Martin Pool - BROKEN: partial support for commit into weave | 210 | def _unpack_inventory(self, elt): | 
| 211 | """Construct from XML Element | |
| 212 |         """
 | |
| 213 | assert elt.tag == 'inventory' | |
| 214 | root_id = elt.get('file_id') or ROOT_ID | |
| 1393.1.59
by Martin Pool - put 'format=5' on inventory and revision xml | 215 | format = elt.get('format') | 
| 216 | if format is not None: | |
| 217 | if format != '5': | |
| 218 | raise BzrError("invalid format version %r on inventory" | |
| 219 | % format) | |
| 1638.1.2
by Robert Collins Change the basis-inventory file to not have the revision-id in the file name. | 220 | revision_id = elt.get('revision_id') | 
| 1911.2.6
by John Arbash Meinel Cache revision ids and file ids as part of xml processing. A custom xml parser could just call decode/encode directly. | 221 | if revision_id is not None: | 
| 222 | revision_id = cache_utf8.get_cached_unicode(revision_id) | |
| 1638.1.2
by Robert Collins Change the basis-inventory file to not have the revision-id in the file name. | 223 | inv = Inventory(root_id, revision_id=revision_id) | 
| 1189
by Martin Pool - BROKEN: partial support for commit into weave | 224 | for e in elt: | 
| 225 | ie = self._unpack_entry(e) | |
| 226 | if ie.parent_id == ROOT_ID: | |
| 227 | ie.parent_id = root_id | |
| 228 | inv.add(ie) | |
| 229 | return inv | |
| 230 | ||
| 231 | def _unpack_entry(self, elt): | |
| 232 | kind = elt.tag | |
| 1399.1.6
by Robert Collins move exporting functionality into inventory.py - uncovers bug in symlink support | 233 | if not InventoryEntry.versionable_kind(kind): | 
| 1092.2.20
by Robert Collins symlink and weaves, whaddya know | 234 | raise AssertionError('unsupported entry kind %s' % kind) | 
| 1189
by Martin Pool - BROKEN: partial support for commit into weave | 235 | |
| 1911.2.6
by John Arbash Meinel Cache revision ids and file ids as part of xml processing. A custom xml parser could just call decode/encode directly. | 236 | get_cached = cache_utf8.get_cached_unicode | 
| 237 | ||
| 1189
by Martin Pool - BROKEN: partial support for commit into weave | 238 | parent_id = elt.get('parent_id') | 
| 239 | if parent_id == None: | |
| 240 | parent_id = ROOT_ID | |
| 1934.1.20
by John Arbash Meinel Document why we aren't caching file ids at the moment | 241 |         # TODO: jam 20060817 At present, caching file ids costs us too 
 | 
| 242 |         #       much time. It slows down overall read performances from
 | |
| 243 |         #       approx 500ms to 700ms. And doesn't improve future reads.
 | |
| 244 |         #       it might be because revision ids and file ids are mixing.
 | |
| 245 |         #       Consider caching *just* the file ids, for a limited period
 | |
| 246 |         #       of time.
 | |
| 1934.1.18
by John Arbash Meinel Caching revision_ids costs us a little (512 vs 475), but caching file-ids costs us a lot (780 vs 512), so disabling caching of file ids for now | 247 |         #parent_id = get_cached(parent_id)
 | 
| 248 |         #file_id = get_cached(elt.get('file_id'))
 | |
| 249 | file_id = elt.get('file_id') | |
| 1189
by Martin Pool - BROKEN: partial support for commit into weave | 250 | |
| 1399.1.8
by Robert Collins factor out inventory directory logic into 'InventoryDirectory' class | 251 | if kind == 'directory': | 
| 1911.2.6
by John Arbash Meinel Cache revision ids and file ids as part of xml processing. A custom xml parser could just call decode/encode directly. | 252 | ie = inventory.InventoryDirectory(file_id, | 
| 1399.1.8
by Robert Collins factor out inventory directory logic into 'InventoryDirectory' class | 253 | elt.get('name'), | 
| 254 | parent_id) | |
| 1399.1.9
by Robert Collins factor out file related logic from InventoryEntry to InventoryFile | 255 | elif kind == 'file': | 
| 1911.2.6
by John Arbash Meinel Cache revision ids and file ids as part of xml processing. A custom xml parser could just call decode/encode directly. | 256 | ie = inventory.InventoryFile(file_id, | 
| 1399.1.9
by Robert Collins factor out file related logic from InventoryEntry to InventoryFile | 257 | elt.get('name'), | 
| 258 | parent_id) | |
| 259 | ie.text_sha1 = elt.get('text_sha1') | |
| 260 | if elt.get('executable') == 'yes': | |
| 261 | ie.executable = True | |
| 262 | v = elt.get('text_size') | |
| 263 | ie.text_size = v and int(v) | |
| 1399.1.10
by Robert Collins remove kind from the InventoryEntry constructor - only child classes should be created now | 264 | elif kind == 'symlink': | 
| 1911.2.6
by John Arbash Meinel Cache revision ids and file ids as part of xml processing. A custom xml parser could just call decode/encode directly. | 265 | ie = inventory.InventoryLink(file_id, | 
| 1399.1.10
by Robert Collins remove kind from the InventoryEntry constructor - only child classes should be created now | 266 | elt.get('name'), | 
| 267 | parent_id) | |
| 268 | ie.symlink_target = elt.get('symlink_target') | |
| 1399.1.8
by Robert Collins factor out inventory directory logic into 'InventoryDirectory' class | 269 | else: | 
| 1399.1.10
by Robert Collins remove kind from the InventoryEntry constructor - only child classes should be created now | 270 | raise BzrError("unknown kind %r" % kind) | 
| 1911.2.6
by John Arbash Meinel Cache revision ids and file ids as part of xml processing. A custom xml parser could just call decode/encode directly. | 271 | revision = elt.get('revision') | 
| 272 | if revision is not None: | |
| 273 | revision = get_cached(revision) | |
| 274 | ie.revision = revision | |
| 1189
by Martin Pool - BROKEN: partial support for commit into weave | 275 | |
| 276 | return ie | |
| 277 | ||
| 278 | def _unpack_revision(self, elt): | |
| 279 | """XML Element -> Revision object""" | |
| 280 | assert elt.tag == 'revision' | |
| 1393.1.59
by Martin Pool - put 'format=5' on inventory and revision xml | 281 | format = elt.get('format') | 
| 282 | if format is not None: | |
| 283 | if format != '5': | |
| 284 | raise BzrError("invalid format version %r on inventory" | |
| 285 | % format) | |
| 1911.2.6
by John Arbash Meinel Cache revision ids and file ids as part of xml processing. A custom xml parser could just call decode/encode directly. | 286 | get_cached = cache_utf8.get_cached_unicode | 
| 1189
by Martin Pool - BROKEN: partial support for commit into weave | 287 | rev = Revision(committer = elt.get('committer'), | 
| 288 | timestamp = float(elt.get('timestamp')), | |
| 1911.2.6
by John Arbash Meinel Cache revision ids and file ids as part of xml processing. A custom xml parser could just call decode/encode directly. | 289 | revision_id = get_cached(elt.get('revision_id')), | 
| 1189
by Martin Pool - BROKEN: partial support for commit into weave | 290 | inventory_sha1 = elt.get('inventory_sha1') | 
| 291 |                        )
 | |
| 292 | parents = elt.find('parents') or [] | |
| 293 | for p in parents: | |
| 294 | assert p.tag == 'revision_ref', \ | |
| 295 | "bad parent node tag %r" % p.tag | |
| 1911.2.6
by John Arbash Meinel Cache revision ids and file ids as part of xml processing. A custom xml parser could just call decode/encode directly. | 296 | rev.parent_ids.append(get_cached(p.get('revision_id'))) | 
| 1185.16.37
by Martin Pool - properties are retrieved when revisions are loaded | 297 | self._unpack_revision_properties(elt, rev) | 
| 1189
by Martin Pool - BROKEN: partial support for commit into weave | 298 | v = elt.get('timezone') | 
| 1913.1.1
by John Arbash Meinel Fix bug #55783 | 299 | if v is None: | 
| 300 | rev.timezone = 0 | |
| 301 | else: | |
| 302 | rev.timezone = int(v) | |
| 1189
by Martin Pool - BROKEN: partial support for commit into weave | 303 | rev.message = elt.findtext('message') # text of <message> | 
| 304 | return rev | |
| 305 | ||
| 1185.16.37
by Martin Pool - properties are retrieved when revisions are loaded | 306 | def _unpack_revision_properties(self, elt, rev): | 
| 307 | """Unpack properties onto a revision.""" | |
| 308 | props_elt = elt.find('properties') | |
| 309 | assert len(rev.properties) == 0 | |
| 310 | if not props_elt: | |
| 311 |             return
 | |
| 312 | for prop_elt in props_elt: | |
| 313 | assert prop_elt.tag == 'property', \ | |
| 1773.4.1
by Martin Pool Add pyflakes makefile target; fix many warnings | 314 | "bad tag under properties list: %r" % prop_elt.tag | 
| 1185.16.37
by Martin Pool - properties are retrieved when revisions are loaded | 315 | name = prop_elt.get('name') | 
| 316 | value = prop_elt.text | |
| 1886.1.1
by John Arbash Meinel Fix bug #47782, | 317 |             # If a property had an empty value ('') cElementTree reads
 | 
| 318 |             # that back as None, convert it back to '', so that all
 | |
| 319 |             # properties have string values
 | |
| 320 | if value is None: | |
| 321 | value = '' | |
| 1185.16.37
by Martin Pool - properties are retrieved when revisions are loaded | 322 | assert name not in rev.properties, \ | 
| 1773.4.1
by Martin Pool Add pyflakes makefile target; fix many warnings | 323 | "repeated property %r" % name | 
| 1185.16.37
by Martin Pool - properties are retrieved when revisions are loaded | 324 | rev.properties[name] = value | 
| 325 | ||
| 326 | ||
| 1189
by Martin Pool - BROKEN: partial support for commit into weave | 327 | serializer_v5 = Serializer_v5() |