86
_file_ids_altered_regex = lazy_regex.lazy_compile(
87
r'file_id="(?P<file_id>[^"]+)"'
88
r'.*revision="(?P<revision_id>[^"]+)"'
86
92
def add_inventory(self, revid, inv, parents):
87
93
"""Add the inventory inv to the repository as revid.
436
442
# revisions. We don't need to see all lines in the inventory because
437
443
# only those added in an inventory in rev X can contain a revision=X
445
unescape_revid_cache = {}
446
unescape_fileid_cache = {}
448
# Move several functions to be local variables, since this is a long
450
search = self._file_ids_altered_regex.search
451
unescape = _unescape_xml_cached
452
setdefault = result.setdefault
439
453
pb = ui.ui_factory.nested_progress_bar()
441
455
for line in w.iter_lines_added_or_present_in_versions(
442
selected_revision_ids, pb=pb):
443
start = line.find('file_id="')+9
444
if start < 9: continue
445
end = line.find('"', start)
447
file_id = _unescape_xml(line[start:end])
449
start = line.find('revision="')+10
450
if start < 10: continue
451
end = line.find('"', start)
453
revision_id = _unescape_xml(line[start:end])
456
selected_revision_ids, pb=pb):
460
file_id, revision_id = match.group('file_id', 'revision_id')
461
revision_id = unescape(revision_id, unescape_revid_cache)
454
462
if revision_id in selected_revision_ids:
455
result.setdefault(file_id, set()).add(revision_id)
463
file_id = unescape(file_id, unescape_fileid_cache)
464
setdefault(file_id, set()).add(revision_id)
729
738
def supports_rich_root(self):
730
739
return self._format.rich_root_data
741
def _check_ascii_revisionid(self, revision_id, method):
742
"""Private helper for ascii-only repositories."""
743
# weave repositories refuse to store revisionids that are non-ascii.
744
if revision_id is not None:
745
# weaves require ascii revision ids.
746
if isinstance(revision_id, unicode):
748
revision_id.encode('ascii')
749
except UnicodeEncodeError:
750
raise errors.NonAsciiRevisionId(method, self)
733
753
class AllInOneRepository(Repository):
734
754
"""Legacy support - the repository behaviour for all-in-one branches."""
763
783
text_store = get_store('text-store')
764
784
super(AllInOneRepository, self).__init__(_format, a_bzrdir, a_bzrdir._control_files, _revision_store, control_store, text_store)
786
def get_commit_builder(self, branch, parents, config, timestamp=None,
787
timezone=None, committer=None, revprops=None,
789
self._check_ascii_revisionid(revision_id, self.get_commit_builder)
790
return Repository.get_commit_builder(self, branch, parents, config,
791
timestamp, timezone, committer, revprops, revision_id)
767
794
def is_shared(self):
768
795
"""AllInOne repositories cannot be shared."""
874
901
return not self.control_files._transport.has('no-working-trees')
904
class WeaveMetaDirRepository(MetaDirRepository):
905
"""A subclass of MetaDirRepository to set weave specific policy."""
907
def get_commit_builder(self, branch, parents, config, timestamp=None,
908
timezone=None, committer=None, revprops=None,
910
self._check_ascii_revisionid(revision_id, self.get_commit_builder)
911
return MetaDirRepository.get_commit_builder(self, branch, parents,
912
config, timestamp, timezone, committer, revprops, revision_id)
877
915
class KnitRepository(MetaDirRepository):
878
916
"""Knit format repository."""
1532
1570
text_store = self._get_text_store(repo_transport, control_files)
1533
1571
control_store = self._get_control_store(repo_transport, control_files)
1534
1572
_revision_store = self._get_revision_store(repo_transport, control_files)
1535
return MetaDirRepository(_format=self,
1537
control_files=control_files,
1538
_revision_store=_revision_store,
1539
control_store=control_store,
1540
text_store=text_store)
1573
return WeaveMetaDirRepository(_format=self,
1575
control_files=control_files,
1576
_revision_store=_revision_store,
1577
control_store=control_store,
1578
text_store=text_store)
1543
1581
class RepositoryFormatKnit(MetaDirRepositoryFormat):
1615
1653
# trigger a write of the inventory store.
1616
1654
control_store.get_weave_or_empty('inventory', transaction)
1617
1655
_revision_store = self._get_revision_store(repo_transport, control_files)
1656
# the revision id here is irrelevant: it will not be stored, and cannot
1618
1658
_revision_store.has_revision_id('A', transaction)
1619
1659
_revision_store.get_signature_file(transaction)
1620
1660
return self.open(a_bzrdir=a_bzrdir, _found=True)
2363
2403
"""Create a revision id if None was supplied.
2365
2405
If the repository can not support user-specified revision ids
2366
they should override this function and raise UnsupportedOperation
2406
they should override this function and raise CannotSetRevisionId
2367
2407
if _new_revision_id is not None.
2369
:raises: UnsupportedOperation
2409
:raises: CannotSetRevisionId
2371
2411
if self._new_revision_id is None:
2372
2412
self._new_revision_id = self._gen_revision_id()
2534
2574
if _unescape_re is None:
2535
2575
_unescape_re = re.compile('\&([^;]*);')
2536
2576
return _unescape_re.sub(_unescaper, data)
2579
def _unescape_xml_cached(data, cache):
2583
unescaped = _unescape_xml(data)
2584
cache[data] = unescaped