~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/repository.py

Merge description into dont-add-conflict-helpers

Show diffs side-by-side

added added

removed removed

Lines of Context:
1027
1027
 
1028
1028
        :seealso: add_inventory, for the contract.
1029
1029
        """
1030
 
        inv_lines = self._serializer.write_inventory_to_lines(inv)
 
1030
        inv_lines = self._serialise_inventory_to_lines(inv)
1031
1031
        return self._inventory_add_lines(revision_id, parents,
1032
1032
            inv_lines, check_content=False)
1033
1033
 
1240
1240
        """Check a single text from this repository."""
1241
1241
        if kind == 'inventories':
1242
1242
            rev_id = record.key[0]
1243
 
            inv = self._deserialise_inventory(rev_id,
 
1243
            inv = self.deserialise_inventory(rev_id,
1244
1244
                record.get_bytes_as('fulltext'))
1245
1245
            if last_object is not None:
1246
1246
                delta = inv._make_delta(last_object)
1484
1484
        :param using: If True, list only branches using this repository.
1485
1485
        """
1486
1486
        if using and not self.is_shared():
1487
 
            return self.bzrdir.list_branches()
 
1487
            try:
 
1488
                return [self.bzrdir.open_branch()]
 
1489
            except errors.NotBranchError:
 
1490
                return []
1488
1491
        class Evaluator(object):
1489
1492
 
1490
1493
            def __init__(self):
1499
1502
                    except errors.NoRepositoryPresent:
1500
1503
                        pass
1501
1504
                    else:
1502
 
                        return False, ([], repository)
 
1505
                        return False, (None, repository)
1503
1506
                self.first_call = False
1504
 
                value = (bzrdir.list_branches(), None)
 
1507
                try:
 
1508
                    value = (bzrdir.open_branch(), None)
 
1509
                except errors.NotBranchError:
 
1510
                    value = (None, None)
1505
1511
                return True, value
1506
1512
 
1507
 
        ret = []
1508
 
        for branches, repository in bzrdir.BzrDir.find_bzrdirs(
 
1513
        branches = []
 
1514
        for branch, repository in bzrdir.BzrDir.find_bzrdirs(
1509
1515
                self.bzrdir.root_transport, evaluate=Evaluator()):
1510
 
            if branches is not None:
1511
 
                ret.extend(branches)
 
1516
            if branch is not None:
 
1517
                branches.append(branch)
1512
1518
            if not using and repository is not None:
1513
 
                ret.extend(repository.find_branches())
1514
 
        return ret
 
1519
                branches.extend(repository.find_branches())
 
1520
        return branches
1515
1521
 
1516
1522
    @needs_read_lock
1517
1523
    def search_missing_revision_ids(self, other, revision_id=None, find_ghosts=True):
1895
1901
                rev = self._serializer.read_revision_from_string(text)
1896
1902
                yield (revid, rev)
1897
1903
 
 
1904
    @needs_read_lock
 
1905
    def get_revision_xml(self, revision_id):
 
1906
        # TODO: jam 20070210 This shouldn't be necessary since get_revision
 
1907
        #       would have already do it.
 
1908
        # TODO: jam 20070210 Just use _serializer.write_revision_to_string()
 
1909
        # TODO: this can't just be replaced by:
 
1910
        # return self._serializer.write_revision_to_string(
 
1911
        #     self.get_revision(revision_id))
 
1912
        # as cStringIO preservers the encoding unlike write_revision_to_string
 
1913
        # or some other call down the path.
 
1914
        rev = self.get_revision(revision_id)
 
1915
        rev_tmp = cStringIO.StringIO()
 
1916
        # the current serializer..
 
1917
        self._serializer.write_revision(rev, rev_tmp)
 
1918
        rev_tmp.seek(0)
 
1919
        return rev_tmp.getvalue()
 
1920
 
1898
1921
    def get_deltas_for_revisions(self, revisions, specific_fileids=None):
1899
1922
        """Produce a generator of revision deltas.
1900
1923
 
2142
2165
        """
2143
2166
        selected_keys = set((revid,) for revid in revision_ids)
2144
2167
        w = _inv_weave or self.inventories
2145
 
        return self._find_file_ids_from_xml_inventory_lines(
2146
 
            w.iter_lines_added_or_present_in_keys(
2147
 
                selected_keys, pb=None),
2148
 
            selected_keys)
 
2168
        pb = ui.ui_factory.nested_progress_bar()
 
2169
        try:
 
2170
            return self._find_file_ids_from_xml_inventory_lines(
 
2171
                w.iter_lines_added_or_present_in_keys(
 
2172
                    selected_keys, pb=pb),
 
2173
                selected_keys)
 
2174
        finally:
 
2175
            pb.finished()
2149
2176
 
2150
2177
    def iter_files_bytes(self, desired_files):
2151
2178
        """Iterate through file versions.
2361
2388
        """single-document based inventory iteration."""
2362
2389
        inv_xmls = self._iter_inventory_xmls(revision_ids, ordering)
2363
2390
        for text, revision_id in inv_xmls:
2364
 
            yield self._deserialise_inventory(revision_id, text)
 
2391
            yield self.deserialise_inventory(revision_id, text)
2365
2392
 
2366
2393
    def _iter_inventory_xmls(self, revision_ids, ordering):
2367
2394
        if ordering is None:
2399
2426
                        next_key = None
2400
2427
                        break
2401
2428
 
2402
 
    def _deserialise_inventory(self, revision_id, xml):
 
2429
    def deserialise_inventory(self, revision_id, xml):
2403
2430
        """Transform the xml into an inventory object.
2404
2431
 
2405
2432
        :param revision_id: The expected revision id of the inventory.
2413
2440
                result.revision_id, revision_id))
2414
2441
        return result
2415
2442
 
 
2443
    def serialise_inventory(self, inv):
 
2444
        return self._serializer.write_inventory_to_string(inv)
 
2445
 
 
2446
    def _serialise_inventory_to_lines(self, inv):
 
2447
        return self._serializer.write_inventory_to_lines(inv)
 
2448
 
2416
2449
    def get_serializer_format(self):
2417
2450
        return self._serializer.format_num
2418
2451
 
2419
2452
    @needs_read_lock
2420
 
    def _get_inventory_xml(self, revision_id):
2421
 
        """Get serialized inventory as a string."""
 
2453
    def get_inventory_xml(self, revision_id):
 
2454
        """Get inventory XML as a file object."""
2422
2455
        texts = self._iter_inventory_xmls([revision_id], 'unordered')
2423
2456
        try:
2424
2457
            text, revision_id = texts.next()
2426
2459
            raise errors.HistoryMissing(self, 'inventory', revision_id)
2427
2460
        return text
2428
2461
 
 
2462
    @needs_read_lock
 
2463
    def get_inventory_sha1(self, revision_id):
 
2464
        """Return the sha1 hash of the inventory entry
 
2465
        """
 
2466
        return self.get_revision(revision_id).inventory_sha1
 
2467
 
2429
2468
    def get_rev_id_for_revno(self, revno, known_pair):
2430
2469
        """Return the revision id of a revno, given a later (revno, revid)
2431
2470
        pair in the same history.
2482
2521
            else:
2483
2522
                next_id = parents[0]
2484
2523
 
 
2524
    @needs_read_lock
 
2525
    def get_revision_inventory(self, revision_id):
 
2526
        """Return inventory of a past revision."""
 
2527
        # TODO: Unify this with get_inventory()
 
2528
        # bzr 0.0.6 and later imposes the constraint that the inventory_id
 
2529
        # must be the same as its revision, so this is trivial.
 
2530
        if revision_id is None:
 
2531
            # This does not make sense: if there is no revision,
 
2532
            # then it is the current tree inventory surely ?!
 
2533
            # and thus get_root_id() is something that looks at the last
 
2534
            # commit on the branch, and the get_root_id is an inventory check.
 
2535
            raise NotImplementedError
 
2536
            # return Inventory(self.get_root_id())
 
2537
        else:
 
2538
            return self.get_inventory(revision_id)
 
2539
 
2485
2540
    def is_shared(self):
2486
2541
        """Return True if this repository is flagged as a shared repository."""
2487
2542
        raise NotImplementedError(self.is_shared)
2521
2576
            return RevisionTree(self, Inventory(root_id=None),
2522
2577
                                _mod_revision.NULL_REVISION)
2523
2578
        else:
2524
 
            inv = self.get_inventory(revision_id)
 
2579
            inv = self.get_revision_inventory(revision_id)
2525
2580
            return RevisionTree(self, inv, revision_id)
2526
2581
 
2527
2582
    def revision_trees(self, revision_ids):
3030
3085
    pack_compresses = False
3031
3086
    # Does the repository inventory storage understand references to trees?
3032
3087
    supports_tree_reference = None
3033
 
    # Is the format experimental ?
3034
 
    experimental = False
3035
3088
 
3036
3089
    def __str__(self):
3037
3090
        return "<%s>" % self.__class__.__name__
3368
3421
 
3369
3422
        :param revision_id: if None all content is copied, if NULL_REVISION no
3370
3423
                            content is copied.
3371
 
        :param pb: ignored.
 
3424
        :param pb: optional progress bar to use for progress reports. If not
 
3425
                   provided a default one will be created.
3372
3426
        :return: None.
3373
3427
        """
3374
 
        ui.ui_factory.warn_experimental_format_fetch(self)
3375
3428
        f = _mod_fetch.RepoFetcher(to_repository=self.target,
3376
3429
                               from_repository=self.source,
3377
3430
                               last_revision=revision_id,
3378
3431
                               fetch_spec=fetch_spec,
3379
 
                               find_ghosts=find_ghosts)
 
3432
                               pb=pb, find_ghosts=find_ghosts)
3380
3433
 
3381
3434
    def _walk_to_common_revisions(self, revision_ids):
3382
3435
        """Walk out from revision_ids in source to revisions target has.
3962
4015
        # streaming.
3963
4016
        ui.ui_factory.warn_cross_format_fetch(self.source._format,
3964
4017
            self.target._format)
3965
 
        ui.ui_factory.warn_experimental_format_fetch(self)
3966
4018
        if (not self.source.supports_rich_root()
3967
4019
            and self.target.supports_rich_root()):
3968
4020
            self._converting_to_rich_root = True
4043
4095
        :param to_convert: The disk object to convert.
4044
4096
        :param pb: a progress bar to use for progress information.
4045
4097
        """
4046
 
        pb = ui.ui_factory.nested_progress_bar()
 
4098
        self.pb = pb
4047
4099
        self.count = 0
4048
4100
        self.total = 4
4049
4101
        # this is only useful with metadir layouts - separated repo content.
4050
4102
        # trigger an assertion if not such
4051
4103
        repo._format.get_format_string()
4052
4104
        self.repo_dir = repo.bzrdir
4053
 
        pb.update('Moving repository to repository.backup')
 
4105
        self.step('Moving repository to repository.backup')
4054
4106
        self.repo_dir.transport.move('repository', 'repository.backup')
4055
4107
        backup_transport =  self.repo_dir.transport.clone('repository.backup')
4056
4108
        repo._format.check_conversion_target(self.target_format)
4057
4109
        self.source_repo = repo._format.open(self.repo_dir,
4058
4110
            _found=True,
4059
4111
            _override_transport=backup_transport)
4060
 
        pb.update('Creating new repository')
 
4112
        self.step('Creating new repository')
4061
4113
        converted = self.target_format.initialize(self.repo_dir,
4062
4114
                                                  self.source_repo.is_shared())
4063
4115
        converted.lock_write()
4064
4116
        try:
4065
 
            pb.update('Copying content')
 
4117
            self.step('Copying content')
4066
4118
            self.source_repo.copy_content_into(converted)
4067
4119
        finally:
4068
4120
            converted.unlock()
4069
 
        pb.update('Deleting old repository content')
 
4121
        self.step('Deleting old repository content')
4070
4122
        self.repo_dir.transport.delete_tree('repository.backup')
4071
4123
        ui.ui_factory.note('repository converted')
4072
 
        pb.finished()
 
4124
 
 
4125
    def step(self, message):
 
4126
        """Update the pb by a step."""
 
4127
        self.count +=1
 
4128
        self.pb.update(message, self.count, self.total)
4073
4129
 
4074
4130
 
4075
4131
_unescape_map = {