~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/repository.py

  • Committer: Patch Queue Manager
  • Date: 2012-03-28 16:13:49 UTC
  • mfrom: (6499.2.3 948339-config-caching)
  • Revision ID: pqm@pqm.ubuntu.com-20120328161349-2gsc0g11fcu43hlc
(vila) Properly share mutable config sections and save the branch config
 only during the final unlock (Vincent Ladeuil)

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
 
17
from __future__ import absolute_import
 
18
 
17
19
from bzrlib.lazy_import import lazy_import
18
20
lazy_import(globals(), """
19
21
import itertools
20
22
import time
21
23
 
22
24
from bzrlib import (
23
 
    bzrdir,
24
25
    config,
25
26
    controldir,
26
27
    debug,
35
36
    gpg,
36
37
    )
37
38
from bzrlib.bundle import serializer
 
39
from bzrlib.i18n import gettext
38
40
""")
39
41
 
40
42
from bzrlib import (
 
43
    bzrdir,
41
44
    errors,
42
45
    registry,
43
46
    symbol_versioning,
73
76
    record_root_entry = True
74
77
    # whether this commit builder supports the record_entry_contents interface
75
78
    supports_record_entry_contents = False
 
79
    # whether this commit builder will automatically update the branch that is
 
80
    # being committed to
 
81
    updates_branch = False
76
82
 
77
 
    def __init__(self, repository, parents, config, timestamp=None,
 
83
    def __init__(self, repository, parents, config_stack, timestamp=None,
78
84
                 timezone=None, committer=None, revprops=None,
79
85
                 revision_id=None, lossy=False):
80
86
        """Initiate a CommitBuilder.
89
95
        :param lossy: Whether to discard data that can not be natively
90
96
            represented, when pushing to a foreign VCS 
91
97
        """
92
 
        self._config = config
 
98
        self._config_stack = config_stack
93
99
        self._lossy = lossy
94
100
 
95
101
        if committer is None:
96
 
            self._committer = self._config.username()
 
102
            self._committer = self._config_stack.get('email')
97
103
        elif not isinstance(committer, unicode):
98
104
            self._committer = committer.decode() # throw if non-ascii
99
105
        else:
280
286
                raise
281
287
            mutter('abort_write_group failed')
282
288
            log_exception_quietly()
283
 
            note('bzr: ERROR (ignored): %s', exc)
 
289
            note(gettext('bzr: ERROR (ignored): %s'), exc)
284
290
        self._write_group = None
285
291
 
286
292
    def _abort_write_group(self):
340
346
        """
341
347
        self.control_files.break_lock()
342
348
 
343
 
    @needs_read_lock
344
 
    def _eliminate_revisions_not_present(self, revision_ids):
345
 
        """Check every revision id in revision_ids to see if we have it.
346
 
 
347
 
        Returns a set of the present revisions.
348
 
        """
349
 
        result = []
350
 
        graph = self.get_graph()
351
 
        parent_map = graph.get_parent_map(revision_ids)
352
 
        # The old API returned a list, should this actually be a set?
353
 
        return parent_map.keys()
354
 
 
355
349
    @staticmethod
356
 
    def create(a_bzrdir):
357
 
        """Construct the current default format repository in a_bzrdir."""
358
 
        return RepositoryFormat.get_default_format().initialize(a_bzrdir)
 
350
    def create(controldir):
 
351
        """Construct the current default format repository in controldir."""
 
352
        return RepositoryFormat.get_default_format().initialize(controldir)
359
353
 
360
 
    def __init__(self, _format, a_bzrdir, control_files):
 
354
    def __init__(self, _format, controldir, control_files):
361
355
        """instantiate a Repository.
362
356
 
363
357
        :param _format: The format of the repository on disk.
364
 
        :param a_bzrdir: The BzrDir of the repository.
 
358
        :param controldir: The ControlDir of the repository.
365
359
        :param control_files: Control files to use for locking, etc.
366
360
        """
367
361
        # In the future we will have a single api for all stores for
370
364
        super(Repository, self).__init__()
371
365
        self._format = _format
372
366
        # the following are part of the public API for Repository:
373
 
        self.bzrdir = a_bzrdir
 
367
        self.bzrdir = controldir
374
368
        self.control_files = control_files
375
 
        self._transport = control_files._transport
376
 
        self.base = self._transport.base
377
369
        # for tests
378
370
        self._write_group = None
379
371
        # Additional places to query for data.
417
409
        """
418
410
        if self.__class__ is not other.__class__:
419
411
            return False
420
 
        return (self._transport.base == other._transport.base)
 
412
        return (self.control_url == other.control_url)
421
413
 
422
414
    def is_in_write_group(self):
423
415
        """Return True if there is an open write group.
560
552
            def __init__(self):
561
553
                self.first_call = True
562
554
 
563
 
            def __call__(self, bzrdir):
564
 
                # On the first call, the parameter is always the bzrdir
 
555
            def __call__(self, controldir):
 
556
                # On the first call, the parameter is always the controldir
565
557
                # containing the current repo.
566
558
                if not self.first_call:
567
559
                    try:
568
 
                        repository = bzrdir.open_repository()
 
560
                        repository = controldir.open_repository()
569
561
                    except errors.NoRepositoryPresent:
570
562
                        pass
571
563
                    else:
572
564
                        return False, ([], repository)
573
565
                self.first_call = False
574
 
                value = (bzrdir.list_branches(), None)
 
566
                value = (controldir.list_branches(), None)
575
567
                return True, value
576
568
 
577
569
        ret = []
578
 
        for branches, repository in bzrdir.BzrDir.find_bzrdirs(
 
570
        for branches, repository in controldir.ControlDir.find_bzrdirs(
579
571
                self.user_transport, evaluate=Evaluator()):
580
572
            if branches is not None:
581
573
                ret.extend(branches)
615
607
        For instance, if the repository is at URL/.bzr/repository,
616
608
        Repository.open(URL) -> a Repository instance.
617
609
        """
618
 
        control = bzrdir.BzrDir.open(base)
 
610
        control = controldir.ControlDir.open(base)
619
611
        return control.open_repository()
620
612
 
621
613
    def copy_content_into(self, destination, revision_id=None):
652
644
        """
653
645
 
654
646
    def suspend_write_group(self):
 
647
        """Suspend a write group.
 
648
 
 
649
        :raise UnsuspendableWriteGroup: If the write group can not be
 
650
            suspended.
 
651
        :return: List of tokens
 
652
        """
655
653
        raise errors.UnsuspendableWriteGroup(self)
656
654
 
657
655
    def refresh_data(self):
679
677
    def _resume_write_group(self, tokens):
680
678
        raise errors.UnsuspendableWriteGroup(self)
681
679
 
682
 
    def fetch(self, source, revision_id=None, find_ghosts=False,
683
 
            fetch_spec=None):
 
680
    def fetch(self, source, revision_id=None, find_ghosts=False):
684
681
        """Fetch the content required to construct revision_id from source.
685
682
 
686
 
        If revision_id is None and fetch_spec is None, then all content is
687
 
        copied.
 
683
        If revision_id is None, then all content is copied.
688
684
 
689
685
        fetch() may not be used when the repository is in a write group -
690
686
        either finish the current write group before using fetch, or use
696
692
        :param revision_id: If specified, all the content needed for this
697
693
            revision ID will be copied to the target.  Fetch will determine for
698
694
            itself which content needs to be copied.
699
 
        :param fetch_spec: If specified, a SearchResult or
700
 
            PendingAncestryResult that describes which revisions to copy.  This
701
 
            allows copying multiple heads at once.  Mutually exclusive with
702
 
            revision_id.
703
695
        """
704
 
        if fetch_spec is not None and revision_id is not None:
705
 
            raise AssertionError(
706
 
                "fetch_spec and revision_id are mutually exclusive.")
707
696
        if self.is_in_write_group():
708
697
            raise errors.InternalBzrError(
709
698
                "May not fetch while in a write group.")
711
700
        # TODO: lift out to somewhere common with RemoteRepository
712
701
        # <https://bugs.launchpad.net/bzr/+bug/401646>
713
702
        if (self.has_same_location(source)
714
 
            and fetch_spec is None
715
703
            and self._has_same_fallbacks(source)):
716
704
            # check that last_revision is in 'from' and then return a
717
705
            # no-operation.
720
708
                self.get_revision(revision_id)
721
709
            return 0, []
722
710
        inter = InterRepository.get(source, self)
723
 
        return inter.fetch(revision_id=revision_id,
724
 
            find_ghosts=find_ghosts, fetch_spec=fetch_spec)
 
711
        return inter.fetch(revision_id=revision_id, find_ghosts=find_ghosts)
725
712
 
726
713
    def create_bundle(self, target, base, fileobj, format=None):
727
714
        return serializer.write_bundle(self, target, base, fileobj, format)
728
715
 
729
 
    def get_commit_builder(self, branch, parents, config, timestamp=None,
 
716
    def get_commit_builder(self, branch, parents, config_stack, timestamp=None,
730
717
                           timezone=None, committer=None, revprops=None,
731
718
                           revision_id=None, lossy=False):
732
719
        """Obtain a CommitBuilder for this repository.
733
720
 
734
721
        :param branch: Branch to commit to.
735
722
        :param parents: Revision ids of the parents of the new revision.
736
 
        :param config: Configuration to use.
 
723
        :param config_stack: Configuration stack to use.
737
724
        :param timestamp: Optional timestamp recorded for commit.
738
725
        :param timezone: Optional timezone for timestamp.
739
726
        :param committer: Optional committer to set for commit.
759
746
                repo.unlock()
760
747
 
761
748
    @needs_read_lock
762
 
    def clone(self, a_bzrdir, revision_id=None):
763
 
        """Clone this repository into a_bzrdir using the current format.
 
749
    def clone(self, controldir, revision_id=None):
 
750
        """Clone this repository into controldir using the current format.
764
751
 
765
752
        Currently no check is made that the format of this repository and
766
753
        the bzrdir format are compatible. FIXME RBC 20060201.
769
756
        """
770
757
        # TODO: deprecate after 0.16; cloning this with all its settings is
771
758
        # probably not very useful -- mbp 20070423
772
 
        dest_repo = self._create_sprouting_repo(a_bzrdir, shared=self.is_shared())
 
759
        dest_repo = self._create_sprouting_repo(
 
760
            controldir, shared=self.is_shared())
773
761
        self.copy_content_into(dest_repo, revision_id)
774
762
        return dest_repo
775
763
 
942
930
        parent_ids.discard(_mod_revision.NULL_REVISION)
943
931
        return parent_ids
944
932
 
945
 
    def fileids_altered_by_revision_ids(self, revision_ids):
946
 
        """Find the file ids and versions affected by revisions.
947
 
 
948
 
        :param revisions: an iterable containing revision ids.
949
 
        :return: a dictionary mapping altered file-ids to an iterable of
950
 
            revision_ids. Each altered file-ids has the exact revision_ids
951
 
            that altered it listed explicitly.
952
 
        """
953
 
        raise NotImplementedError(self.fileids_altered_by_revision_ids)
954
 
 
955
933
    def iter_files_bytes(self, desired_files):
956
934
        """Iterate through file versions.
957
935
 
1171
1149
                [parents_provider, other_repository._make_parents_provider()])
1172
1150
        return graph.Graph(parents_provider)
1173
1151
 
1174
 
    def revision_ids_to_search_result(self, result_set):
1175
 
        """Convert a set of revision ids to a graph SearchResult."""
1176
 
        result_parents = set()
1177
 
        for parents in self.get_graph().get_parent_map(
1178
 
            result_set).itervalues():
1179
 
            result_parents.update(parents)
1180
 
        included_keys = result_set.intersection(result_parents)
1181
 
        start_keys = result_set.difference(included_keys)
1182
 
        exclude_keys = result_parents.difference(result_set)
1183
 
        result = graph.SearchResult(start_keys, exclude_keys,
1184
 
            len(result_set), result_set)
1185
 
        return result
1186
 
 
1187
1152
    @needs_write_lock
1188
1153
    def set_make_working_trees(self, new_value):
1189
1154
        """Set the policy flag for making working trees when creating branches.
1207
1172
        self.store_revision_signature(gpg_strategy, plaintext, revision_id)
1208
1173
 
1209
1174
    @needs_read_lock
1210
 
    def verify_revision(self, revision_id, gpg_strategy):
 
1175
    def verify_revision_signature(self, revision_id, gpg_strategy):
1211
1176
        """Verify the signature on a revision.
1212
 
        
 
1177
 
1213
1178
        :param revision_id: the revision to verify
1214
1179
        :gpg_strategy: the GPGStrategy object to used
1215
 
        
 
1180
 
1216
1181
        :return: gpg.SIGNATURE_VALID or a failed SIGNATURE_ value
1217
1182
        """
1218
1183
        if not self.has_signature_for_revision_id(revision_id):
1224
1189
 
1225
1190
        return gpg_strategy.verify(signature, plaintext)
1226
1191
 
 
1192
    @needs_read_lock
 
1193
    def verify_revision_signatures(self, revision_ids, gpg_strategy):
 
1194
        """Verify revision signatures for a number of revisions.
 
1195
 
 
1196
        :param revision_id: the revision to verify
 
1197
        :gpg_strategy: the GPGStrategy object to used
 
1198
        :return: Iterator over tuples with revision id, result and keys
 
1199
        """
 
1200
        for revid in revision_ids:
 
1201
            (result, key) = self.verify_revision_signature(revid, gpg_strategy)
 
1202
            yield revid, result, key
 
1203
 
1227
1204
    def has_signature_for_revision_id(self, revision_id):
1228
1205
        """Query for a revision signature for revision_id in the repository."""
1229
1206
        raise NotImplementedError(self.has_signature_for_revision_id)
1259
1236
            return
1260
1237
        try:
1261
1238
            if branch is None:
1262
 
                conf = config.GlobalConfig()
 
1239
                conf = config.GlobalStack()
1263
1240
            else:
1264
 
                conf = branch.get_config()
1265
 
            if conf.suppress_warning('format_deprecation'):
 
1241
                conf = branch.get_config_stack()
 
1242
            if 'format_deprecation' in conf.get('suppress_warnings'):
1266
1243
                return
1267
1244
            warning("Format %s for %s is deprecated -"
1268
1245
                    " please use 'bzr upgrade' to get better performance"
1328
1305
        """Returns the policy for making working trees on new branches."""
1329
1306
        return not self._transport.has('no-working-trees')
1330
1307
 
 
1308
    @needs_write_lock
 
1309
    def update_feature_flags(self, updated_flags):
 
1310
        """Update the feature flags for this branch.
 
1311
 
 
1312
        :param updated_flags: Dictionary mapping feature names to necessities
 
1313
            A necessity can be None to indicate the feature should be removed
 
1314
        """
 
1315
        self._format._update_feature_flags(updated_flags)
 
1316
        self.control_transport.put_bytes('format', self._format.as_string())
 
1317
 
1331
1318
 
1332
1319
class RepositoryFormatRegistry(controldir.ControlComponentFormatRegistry):
1333
1320
    """Repository format registry."""
1334
1321
 
1335
1322
    def get_default(self):
1336
1323
        """Return the current default format."""
1337
 
        from bzrlib import bzrdir
1338
 
        return bzrdir.format_registry.make_bzrdir('default').repository_format
 
1324
        return controldir.format_registry.make_bzrdir('default').repository_format
1339
1325
 
1340
1326
 
1341
1327
network_format_registry = registry.FormatRegistry()
1384
1370
    created.
1385
1371
 
1386
1372
    Common instance attributes:
1387
 
    _matchingbzrdir - the bzrdir format that the repository format was
 
1373
    _matchingbzrdir - the controldir format that the repository format was
1388
1374
    originally written to work with. This can be used if manually
1389
1375
    constructing a bzrdir and repository, or more commonly for test suite
1390
1376
    parameterization.
1430
1416
    rich_root_data = None
1431
1417
    # Does this format support explicitly versioned directories?
1432
1418
    supports_versioned_directories = None
 
1419
    # Can other repositories be nested into one of this format?
 
1420
    supports_nesting_repositories = None
 
1421
    # Is it possible for revisions to be present without being referenced
 
1422
    # somewhere ?
 
1423
    supports_unreferenced_revisions = None
1433
1424
 
1434
1425
    def __repr__(self):
1435
1426
        return "%s()" % self.__class__.__name__
1442
1433
        return not self == other
1443
1434
 
1444
1435
    @classmethod
1445
 
    def find_format(klass, a_bzrdir):
1446
 
        """Return the format for the repository object in a_bzrdir.
1447
 
 
1448
 
        This is used by bzr native formats that have a "format" file in
1449
 
        the repository.  Other methods may be used by different types of
1450
 
        control directory.
1451
 
        """
1452
 
        try:
1453
 
            transport = a_bzrdir.get_repository_transport(None)
1454
 
            format_string = transport.get_bytes("format")
1455
 
            return format_registry.get(format_string)
1456
 
        except errors.NoSuchFile:
1457
 
            raise errors.NoRepositoryPresent(a_bzrdir)
1458
 
        except KeyError:
1459
 
            raise errors.UnknownFormatError(format=format_string,
1460
 
                                            kind='repository')
1461
 
 
1462
 
    @classmethod
1463
1436
    @symbol_versioning.deprecated_method(symbol_versioning.deprecated_in((2, 4, 0)))
1464
1437
    def register_format(klass, format):
1465
1438
        format_registry.register(format)
1475
1448
        """Return the current default format."""
1476
1449
        return format_registry.get_default()
1477
1450
 
1478
 
    def get_format_string(self):
1479
 
        """Return the ASCII format string that identifies this format.
1480
 
 
1481
 
        Note that in pre format ?? repositories the format string is
1482
 
        not permitted nor written to disk.
1483
 
        """
1484
 
        raise NotImplementedError(self.get_format_string)
1485
 
 
1486
1451
    def get_format_description(self):
1487
1452
        """Return the short description for this format."""
1488
1453
        raise NotImplementedError(self.get_format_description)
1489
1454
 
1490
 
    def initialize(self, a_bzrdir, shared=False):
1491
 
        """Initialize a repository of this format in a_bzrdir.
 
1455
    def initialize(self, controldir, shared=False):
 
1456
        """Initialize a repository of this format in controldir.
1492
1457
 
1493
 
        :param a_bzrdir: The bzrdir to put the new repository in it.
 
1458
        :param controldir: The controldir to put the new repository in it.
1494
1459
        :param shared: The repository should be initialized as a sharable one.
1495
1460
        :returns: The new repository object.
1496
1461
 
1497
1462
        This may raise UninitializableFormat if shared repository are not
1498
 
        compatible the a_bzrdir.
 
1463
        compatible the controldir.
1499
1464
        """
1500
1465
        raise NotImplementedError(self.initialize)
1501
1466
 
1537
1502
                'Does not support nested trees', target_format,
1538
1503
                from_format=self)
1539
1504
 
1540
 
    def open(self, a_bzrdir, _found=False):
1541
 
        """Return an instance of this format for the bzrdir a_bzrdir.
 
1505
    def open(self, controldir, _found=False):
 
1506
        """Return an instance of this format for a controldir.
1542
1507
 
1543
1508
        _found is a private parameter, do not use it.
1544
1509
        """
1545
1510
        raise NotImplementedError(self.open)
1546
1511
 
1547
 
    def _run_post_repo_init_hooks(self, repository, a_bzrdir, shared):
1548
 
        from bzrlib.bzrdir import BzrDir, RepoInitHookParams
1549
 
        hooks = BzrDir.hooks['post_repo_init']
 
1512
    def _run_post_repo_init_hooks(self, repository, controldir, shared):
 
1513
        from bzrlib.controldir import ControlDir, RepoInitHookParams
 
1514
        hooks = ControlDir.hooks['post_repo_init']
1550
1515
        if not hooks:
1551
1516
            return
1552
 
        params = RepoInitHookParams(repository, self, a_bzrdir, shared)
 
1517
        params = RepoInitHookParams(repository, self, controldir, shared)
1553
1518
        for hook in hooks:
1554
1519
            hook(params)
1555
1520
 
1556
1521
 
1557
 
class MetaDirRepositoryFormat(RepositoryFormat):
 
1522
class RepositoryFormatMetaDir(bzrdir.BzrFormat, RepositoryFormat):
1558
1523
    """Common base class for the new repositories using the metadir layout."""
1559
1524
 
1560
1525
    rich_root_data = False
1561
1526
    supports_tree_reference = False
1562
1527
    supports_external_lookups = False
1563
1528
    supports_leaving_lock = True
 
1529
    supports_nesting_repositories = True
1564
1530
 
1565
1531
    @property
1566
1532
    def _matchingbzrdir(self):
1569
1535
        return matching
1570
1536
 
1571
1537
    def __init__(self):
1572
 
        super(MetaDirRepositoryFormat, self).__init__()
 
1538
        RepositoryFormat.__init__(self)
 
1539
        bzrdir.BzrFormat.__init__(self)
1573
1540
 
1574
1541
    def _create_control_files(self, a_bzrdir):
1575
1542
        """Create the required files and the initial control_files object."""
1599
1566
        finally:
1600
1567
            control_files.unlock()
1601
1568
 
1602
 
    def network_name(self):
1603
 
        """Metadir formats have matching disk and network format strings."""
1604
 
        return self.get_format_string()
 
1569
    @classmethod
 
1570
    def find_format(klass, a_bzrdir):
 
1571
        """Return the format for the repository object in a_bzrdir.
 
1572
 
 
1573
        This is used by bzr native formats that have a "format" file in
 
1574
        the repository.  Other methods may be used by different types of
 
1575
        control directory.
 
1576
        """
 
1577
        try:
 
1578
            transport = a_bzrdir.get_repository_transport(None)
 
1579
            format_string = transport.get_bytes("format")
 
1580
        except errors.NoSuchFile:
 
1581
            raise errors.NoRepositoryPresent(a_bzrdir)
 
1582
        return klass._find_format(format_registry, 'repository', format_string)
 
1583
 
 
1584
    def check_support_status(self, allow_unsupported, recommend_upgrade=True,
 
1585
            basedir=None):
 
1586
        RepositoryFormat.check_support_status(self,
 
1587
            allow_unsupported=allow_unsupported, recommend_upgrade=recommend_upgrade,
 
1588
            basedir=basedir)
 
1589
        bzrdir.BzrFormat.check_support_status(self, allow_unsupported=allow_unsupported,
 
1590
            recommend_upgrade=recommend_upgrade, basedir=basedir)
1605
1591
 
1606
1592
 
1607
1593
# formats which have no format string are not discoverable or independently
1608
1594
# creatable on disk, so are not registered in format_registry.  They're
1609
1595
# all in bzrlib.repofmt.knitreponow.  When an instance of one of these is
1610
 
# needed, it's constructed directly by the BzrDir.  Non-native formats where
 
1596
# needed, it's constructed directly by the ControlDir.  Non-native formats where
1611
1597
# the repository is not separately opened are similar.
1612
1598
 
1613
1599
format_registry.register_lazy(
1724
1710
        self.target.fetch(self.source, revision_id=revision_id)
1725
1711
 
1726
1712
    @needs_write_lock
1727
 
    def fetch(self, revision_id=None, find_ghosts=False,
1728
 
            fetch_spec=None):
 
1713
    def fetch(self, revision_id=None, find_ghosts=False):
1729
1714
        """Fetch the content required to construct revision_id.
1730
1715
 
1731
1716
        The content is copied from self.source to self.target.
1811
1796
        # trigger an assertion if not such
1812
1797
        repo._format.get_format_string()
1813
1798
        self.repo_dir = repo.bzrdir
1814
 
        pb.update('Moving repository to repository.backup')
 
1799
        pb.update(gettext('Moving repository to repository.backup'))
1815
1800
        self.repo_dir.transport.move('repository', 'repository.backup')
1816
1801
        backup_transport =  self.repo_dir.transport.clone('repository.backup')
1817
1802
        repo._format.check_conversion_target(self.target_format)
1818
1803
        self.source_repo = repo._format.open(self.repo_dir,
1819
1804
            _found=True,
1820
1805
            _override_transport=backup_transport)
1821
 
        pb.update('Creating new repository')
 
1806
        pb.update(gettext('Creating new repository'))
1822
1807
        converted = self.target_format.initialize(self.repo_dir,
1823
1808
                                                  self.source_repo.is_shared())
1824
1809
        converted.lock_write()
1825
1810
        try:
1826
 
            pb.update('Copying content')
 
1811
            pb.update(gettext('Copying content'))
1827
1812
            self.source_repo.copy_content_into(converted)
1828
1813
        finally:
1829
1814
            converted.unlock()
1830
 
        pb.update('Deleting old repository content')
 
1815
        pb.update(gettext('Deleting old repository content'))
1831
1816
        self.repo_dir.transport.delete_tree('repository.backup')
1832
 
        ui.ui_factory.note('repository converted')
 
1817
        ui.ui_factory.note(gettext('repository converted'))
1833
1818
        pb.finished()
1834
1819
 
1835
1820
 
1901
1886
        for list_part in self.list_parts:
1902
1887
            full_list.extend(list_part)
1903
1888
        return iter(full_list)
 
1889
 
 
1890
    def __repr__(self):
 
1891
        return "%s.%s(%s)" % (self.__module__, self.__class__.__name__,
 
1892
                              self.list_parts)