/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/repository.py

Merge from bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
33
33
    gpg,
34
34
    graph,
35
35
    knit,
 
36
    lazy_regex,
36
37
    lockable_files,
37
38
    lockdir,
38
39
    osutils,
82
83
    remote) disk.
83
84
    """
84
85
 
 
86
    _file_ids_altered_regex = lazy_regex.lazy_compile(
 
87
        r'file_id="(?P<file_id>[^"]+)"'
 
88
        r'.*revision="(?P<revision_id>[^"]+)"'
 
89
        )
 
90
 
85
91
    @needs_write_lock
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
438
444
        # line.
 
445
        unescape_revid_cache = {}
 
446
        unescape_fileid_cache = {}
 
447
 
 
448
        # Move several functions to be local variables, since this is a long
 
449
        # running loop.
 
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()
440
454
        try:
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)
446
 
                assert end>= 0
447
 
                file_id = _unescape_xml(line[start:end])
448
 
 
449
 
                start = line.find('revision="')+10
450
 
                if start < 10: continue
451
 
                end = line.find('"', start)
452
 
                assert end>= 0
453
 
                revision_id = _unescape_xml(line[start:end])
 
456
                                        selected_revision_ids, pb=pb):
 
457
                match = search(line)
 
458
                if match is None:
 
459
                    continue
 
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)
456
465
        finally:
457
466
            pb.finished()
458
467
        return result
729
738
    def supports_rich_root(self):
730
739
        return self._format.rich_root_data
731
740
 
 
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):
 
747
                try:
 
748
                    revision_id.encode('ascii')
 
749
                except UnicodeEncodeError:
 
750
                    raise errors.NonAsciiRevisionId(method, self)
 
751
 
732
752
 
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)
765
785
 
 
786
    def get_commit_builder(self, branch, parents, config, timestamp=None,
 
787
                           timezone=None, committer=None, revprops=None,
 
788
                           revision_id=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)
 
792
 
766
793
    @needs_read_lock
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')
875
902
 
876
903
 
 
904
class WeaveMetaDirRepository(MetaDirRepository):
 
905
    """A subclass of MetaDirRepository to set weave specific policy."""
 
906
 
 
907
    def get_commit_builder(self, branch, parents, config, timestamp=None,
 
908
                           timezone=None, committer=None, revprops=None,
 
909
                           revision_id=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)
 
913
 
 
914
 
877
915
class KnitRepository(MetaDirRepository):
878
916
    """Knit format repository."""
879
917
 
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,
1536
 
                                 a_bzrdir=a_bzrdir,
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,
 
1574
            a_bzrdir=a_bzrdir,
 
1575
            control_files=control_files,
 
1576
            _revision_store=_revision_store,
 
1577
            control_store=control_store,
 
1578
            text_store=text_store)
1541
1579
 
1542
1580
 
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
 
1657
        # already exist.
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.
2364
2404
        
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.
2368
2408
 
2369
 
        :raises: UnsupportedOperation
 
2409
        :raises: CannotSetRevisionId
2370
2410
        """
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)
 
2577
 
 
2578
 
 
2579
def _unescape_xml_cached(data, cache):
 
2580
    try:
 
2581
        return cache[data]
 
2582
    except KeyError:
 
2583
        unescaped = _unescape_xml(data)
 
2584
        cache[data] = unescaped
 
2585
        return unescaped