17
17
from __future__ import absolute_import
19
from .lazy_import import lazy_import
19
from bzrlib.lazy_import import lazy_import
20
20
lazy_import(globals(), """
31
33
revision as _mod_revision,
32
34
testament as _mod_testament,
35
from breezy.bundle import serializer
36
from breezy.i18n import gettext
38
from bzrlib.bundle import serializer
39
from bzrlib.i18n import gettext
44
from .decorators import only_raises
45
from .inter import InterObject
46
from .lock import _RelockDebugMixin, LogicalLockResult
49
from bzrlib.decorators import needs_read_lock, needs_write_lock, only_raises
50
from bzrlib.inter import InterObject
51
from bzrlib.lock import _RelockDebugMixin, LogicalLockResult
52
from bzrlib.trace import (
53
53
log_exception_quietly, note, mutter, mutter_callsite, warning)
144
142
raise ValueError('Invalid value for %s: %r' % (context, text))
146
144
def _validate_revprops(self, revprops):
147
for key, value in viewitems(revprops):
145
for key, value in revprops.iteritems():
148
146
# We know that the XML serializers do not round trip '\r'
149
147
# correctly, so refuse to accept them
150
if not isinstance(value, (text_type, str)):
148
if not isinstance(value, basestring):
151
149
raise ValueError('revision property (%s) is not a valid'
152
150
' (unicode) string: %r' % (key, value))
153
151
self._validate_unicode_text(value,
198
196
:raises: CannotSetRevisionId
200
if not self.repository._format.supports_setting_revision_ids:
201
if revision_id is not None:
202
raise CannotSetRevisionId()
204
if revision_id is None:
198
if self._new_revision_id is None:
205
199
self._new_revision_id = self._gen_revision_id()
206
200
self.random_revid = True
208
self._new_revision_id = revision_id
209
202
self.random_revid = False
204
def will_record_deletes(self):
205
"""Tell the commit builder that deletes are being notified.
207
This enables the accumulation of an inventory delta; for the resulting
208
commit to be valid, deletes against the basis MUST be recorded via
209
builder.record_delete().
211
raise NotImplementedError(self.will_record_deletes)
211
213
def record_iter_changes(self, tree, basis_revision_id, iter_changes):
212
214
"""Record a new tree via iter_changes.
508
511
revisions: The total revision count in the repository.
509
512
size: An estimate disk size of the repository in bytes.
511
with self.lock_read():
513
if revid and committers:
514
result['committers'] = 0
515
if revid and revid != _mod_revision.NULL_REVISION:
516
graph = self.get_graph()
518
all_committers = set()
519
revisions = [r for (r, p) in graph.iter_ancestry([revid])
520
if r != _mod_revision.NULL_REVISION]
523
# ignore the revisions in the middle - just grab first and last
524
revisions = revisions[0], revisions[-1]
525
for revision in self.get_revisions(revisions):
526
if not last_revision:
527
last_revision = revision
529
all_committers.add(revision.committer)
530
first_revision = revision
532
result['committers'] = len(all_committers)
533
result['firstrev'] = (first_revision.timestamp,
534
first_revision.timezone)
535
result['latestrev'] = (last_revision.timestamp,
536
last_revision.timezone)
515
if revid and committers:
516
result['committers'] = 0
517
if revid and revid != _mod_revision.NULL_REVISION:
518
graph = self.get_graph()
520
all_committers = set()
521
revisions = [r for (r, p) in graph.iter_ancestry([revid])
522
if r != _mod_revision.NULL_REVISION]
525
# ignore the revisions in the middle - just grab first and last
526
revisions = revisions[0], revisions[-1]
527
for revision in self.get_revisions(revisions):
528
if not last_revision:
529
last_revision = revision
531
all_committers.add(revision.committer)
532
first_revision = revision
534
result['committers'] = len(all_committers)
535
result['firstrev'] = (first_revision.timestamp,
536
first_revision.timezone)
537
result['latestrev'] = (last_revision.timestamp,
538
last_revision.timezone)
539
541
def find_branches(self, using=False):
540
542
"""Find branches underneath this repository.
573
575
ret.extend(repository.find_branches())
576
579
def search_missing_revision_ids(self, other,
580
revision_id=symbol_versioning.DEPRECATED_PARAMETER,
577
581
find_ghosts=True, revision_ids=None, if_present_ids=None,
579
583
"""Return the revision ids that other has that this does not.
581
585
These are returned in topological order.
583
revision_ids: only return revision ids included by revision_id.
587
revision_id: only return revision ids included by revision_id.
585
with self.lock_read():
586
return InterRepository.get(other, self).search_missing_revision_ids(
587
find_ghosts=find_ghosts, revision_ids=revision_ids,
588
if_present_ids=if_present_ids, limit=limit)
589
if symbol_versioning.deprecated_passed(revision_id):
590
symbol_versioning.warn(
591
'search_missing_revision_ids(revision_id=...) was '
592
'deprecated in 2.4. Use revision_ids=[...] instead.',
593
DeprecationWarning, stacklevel=3)
594
if revision_ids is not None:
595
raise AssertionError(
596
'revision_ids is mutually exclusive with revision_id')
597
if revision_id is not None:
598
revision_ids = [revision_id]
599
return InterRepository.get(other, self).search_missing_revision_ids(
600
find_ghosts=find_ghosts, revision_ids=revision_ids,
601
if_present_ids=if_present_ids, limit=limit)
781
794
def sprout(self, to_bzrdir, revision_id=None):
782
795
"""Create a descendent repository for new development.
784
797
Unlike clone, this does not copy the settings of the repository.
786
with self.lock_read():
787
dest_repo = self._create_sprouting_repo(to_bzrdir, shared=False)
788
dest_repo.fetch(self, revision_id=revision_id)
799
dest_repo = self._create_sprouting_repo(to_bzrdir, shared=False)
800
dest_repo.fetch(self, revision_id=revision_id)
791
def _create_sprouting_repo(self, a_controldir, shared):
793
a_controldir._format, self.controldir._format.__class__):
803
def _create_sprouting_repo(self, a_bzrdir, shared):
804
if not isinstance(a_bzrdir._format, self.bzrdir._format.__class__):
794
805
# use target default format.
795
dest_repo = a_controldir.create_repository()
806
dest_repo = a_bzrdir.create_repository()
797
808
# Most control formats need the repository to be specifically
798
809
# created, but on some old all-in-one formats it's not needed
800
dest_repo = self._format.initialize(
801
a_controldir, shared=shared)
811
dest_repo = self._format.initialize(a_bzrdir, shared=shared)
802
812
except errors.UninitializableFormat:
803
dest_repo = a_controldir.open_repository()
813
dest_repo = a_bzrdir.open_repository()
806
817
def has_revision(self, revision_id):
807
818
"""True if this repository has a copy of the revision."""
808
with self.lock_read():
809
return revision_id in self.has_revisions((revision_id,))
819
return revision_id in self.has_revisions((revision_id,))
811
822
def has_revisions(self, revision_ids):
812
823
"""Probe to find out the presence of multiple revisions.
834
845
def get_revisions(self, revision_ids):
835
846
"""Get many revisions at once.
837
Repositories that need to check data on every revision read should
848
Repositories that need to check data on every revision read should
838
849
subclass this method.
841
for revid, rev in self.iter_revisions(revision_ids):
843
raise errors.NoSuchRevision(self, revid)
845
return [revs[revid] for revid in revision_ids]
847
def iter_revisions(self, revision_ids):
848
"""Iterate over revision objects.
850
:param revision_ids: An iterable of revisions to examine. None may be
851
passed to request all revisions known to the repository. Note that
852
not all repositories can find unreferenced revisions; for those
853
repositories only referenced ones will be returned.
854
:return: An iterator of (revid, revision) tuples. Absent revisions (
855
those asked for but not available) are returned as (revid, None).
856
N.B.: Revisions are not necessarily yielded in order.
858
raise NotImplementedError(self.iter_revisions)
851
raise NotImplementedError(self.get_revisions)
860
853
def get_deltas_for_revisions(self, revisions, specific_fileids=None):
861
854
"""Produce a generator of revision deltas.
868
861
so that only those file-ids, their parents and their
869
862
children are included.
871
raise NotImplementedError(self.get_deltas_for_revisions)
864
# Get the revision-ids of interest
865
required_trees = set()
866
for revision in revisions:
867
required_trees.add(revision.revision_id)
868
required_trees.update(revision.parent_ids[:1])
870
# Get the matching filtered trees. Note that it's more
871
# efficient to pass filtered trees to changes_from() rather
872
# than doing the filtering afterwards. changes_from() could
873
# arguably do the filtering itself but it's path-based, not
874
# file-id based, so filtering before or afterwards is
876
if specific_fileids is None:
877
trees = dict((t.get_revision_id(), t) for
878
t in self.revision_trees(required_trees))
880
trees = dict((t.get_revision_id(), t) for
881
t in self._filtered_revision_trees(required_trees,
884
# Calculate the deltas
885
for revision in revisions:
886
if not revision.parent_ids:
887
old_tree = self.revision_tree(_mod_revision.NULL_REVISION)
889
old_tree = trees[revision.parent_ids[0]]
890
yield trees[revision.revision_id].changes_from(old_tree)
873
893
def get_revision_delta(self, revision_id, specific_fileids=None):
874
894
"""Return the delta for one revision.
880
900
so that only those file-ids, their parents and their
881
901
children are included.
883
with self.lock_read():
884
r = self.get_revision(revision_id)
885
return list(self.get_deltas_for_revisions(
886
[r], specific_fileids=specific_fileids))[0]
903
r = self.get_revision(revision_id)
904
return list(self.get_deltas_for_revisions([r],
905
specific_fileids=specific_fileids))[0]
888
908
def store_revision_signature(self, gpg_strategy, plaintext, revision_id):
889
with self.lock_write():
890
signature = gpg_strategy.sign(plaintext, gpg.MODE_CLEAR)
891
self.add_signature_text(revision_id, signature)
909
signature = gpg_strategy.sign(plaintext)
910
self.add_signature_text(revision_id, signature)
893
912
def add_signature_text(self, revision_id, signature):
894
913
"""Store a signature text for a revision.
1085
1120
"""Returns the policy for making working trees on new branches."""
1086
1121
raise NotImplementedError(self.make_working_trees)
1088
1124
def sign_revision(self, revision_id, gpg_strategy):
1089
with self.lock_write():
1090
testament = _mod_testament.Testament.from_revision(self, revision_id)
1091
plaintext = testament.as_short_text()
1092
self.store_revision_signature(gpg_strategy, plaintext, revision_id)
1125
testament = _mod_testament.Testament.from_revision(self, revision_id)
1126
plaintext = testament.as_short_text()
1127
self.store_revision_signature(gpg_strategy, plaintext, revision_id)
1094
1130
def verify_revision_signature(self, revision_id, gpg_strategy):
1095
1131
"""Verify the signature on a revision.
1100
1136
:return: gpg.SIGNATURE_VALID or a failed SIGNATURE_ value
1102
with self.lock_read():
1103
if not self.has_signature_for_revision_id(revision_id):
1104
return gpg.SIGNATURE_NOT_SIGNED, None
1105
signature = self.get_signature_text(revision_id)
1107
testament = _mod_testament.Testament.from_revision(self, revision_id)
1109
(status, key, signed_plaintext) = gpg_strategy.verify(signature)
1110
if testament.as_short_text() != signed_plaintext:
1111
return gpg.SIGNATURE_NOT_VALID, None
1112
return (status, key)
1138
if not self.has_signature_for_revision_id(revision_id):
1139
return gpg.SIGNATURE_NOT_SIGNED, None
1140
signature = self.get_signature_text(revision_id)
1142
testament = _mod_testament.Testament.from_revision(self, revision_id)
1143
plaintext = testament.as_short_text()
1145
return gpg_strategy.verify(signature, plaintext)
1114
1148
def verify_revision_signatures(self, revision_ids, gpg_strategy):
1115
1149
"""Verify revision signatures for a number of revisions.
1189
1222
raise errors.NonAsciiRevisionId(method, self)
1225
class MetaDirRepository(Repository):
1226
"""Repositories in the new meta-dir layout.
1228
:ivar _transport: Transport for access to repository control files,
1229
typically pointing to .bzr/repository.
1232
def __init__(self, _format, a_bzrdir, control_files):
1233
super(MetaDirRepository, self).__init__(_format, a_bzrdir, control_files)
1234
self._transport = control_files._transport
1236
def is_shared(self):
1237
"""Return True if this repository is flagged as a shared repository."""
1238
return self._transport.has('shared-storage')
1241
def set_make_working_trees(self, new_value):
1242
"""Set the policy flag for making working trees when creating branches.
1244
This only applies to branches that use this repository.
1246
The default is 'True'.
1247
:param new_value: True to restore the default, False to disable making
1252
self._transport.delete('no-working-trees')
1253
except errors.NoSuchFile:
1256
self._transport.put_bytes('no-working-trees', '',
1257
mode=self.bzrdir._get_file_mode())
1259
def make_working_trees(self):
1260
"""Returns the policy for making working trees on new branches."""
1261
return not self._transport.has('no-working-trees')
1264
def update_feature_flags(self, updated_flags):
1265
"""Update the feature flags for this branch.
1267
:param updated_flags: Dictionary mapping feature names to necessities
1268
A necessity can be None to indicate the feature should be removed
1270
self._format._update_feature_flags(updated_flags)
1271
self.control_transport.put_bytes('format', self._format.as_string())
1192
1274
class RepositoryFormatRegistry(controldir.ControlComponentFormatRegistry):
1193
1275
"""Repository format registry."""
1195
1277
def get_default(self):
1196
1278
"""Return the current default format."""
1197
return controldir.format_registry.make_controldir('default').repository_format
1279
return controldir.format_registry.make_bzrdir('default').repository_format
1200
1282
network_format_registry = registry.FormatRegistry()
1461
class RepositoryFormatMetaDir(bzrdir.BzrFormat, RepositoryFormat):
1462
"""Common base class for the new repositories using the metadir layout."""
1464
rich_root_data = False
1465
supports_tree_reference = False
1466
supports_external_lookups = False
1467
supports_leaving_lock = True
1468
supports_nesting_repositories = True
1471
def _matchingbzrdir(self):
1472
matching = bzrdir.BzrDirMetaFormat1()
1473
matching.repository_format = self
1477
RepositoryFormat.__init__(self)
1478
bzrdir.BzrFormat.__init__(self)
1480
def _create_control_files(self, a_bzrdir):
1481
"""Create the required files and the initial control_files object."""
1482
# FIXME: RBC 20060125 don't peek under the covers
1483
# NB: no need to escape relative paths that are url safe.
1484
repository_transport = a_bzrdir.get_repository_transport(self)
1485
control_files = lockable_files.LockableFiles(repository_transport,
1486
'lock', lockdir.LockDir)
1487
control_files.create_lock()
1488
return control_files
1490
def _upload_blank_content(self, a_bzrdir, dirs, files, utf8_files, shared):
1491
"""Upload the initial blank content."""
1492
control_files = self._create_control_files(a_bzrdir)
1493
control_files.lock_write()
1494
transport = control_files._transport
1496
utf8_files += [('shared-storage', '')]
1498
transport.mkdir_multi(dirs, mode=a_bzrdir._get_dir_mode())
1499
for (filename, content_stream) in files:
1500
transport.put_file(filename, content_stream,
1501
mode=a_bzrdir._get_file_mode())
1502
for (filename, content_bytes) in utf8_files:
1503
transport.put_bytes_non_atomic(filename, content_bytes,
1504
mode=a_bzrdir._get_file_mode())
1506
control_files.unlock()
1509
def find_format(klass, a_bzrdir):
1510
"""Return the format for the repository object in a_bzrdir.
1512
This is used by bzr native formats that have a "format" file in
1513
the repository. Other methods may be used by different types of
1517
transport = a_bzrdir.get_repository_transport(None)
1518
format_string = transport.get_bytes("format")
1519
except errors.NoSuchFile:
1520
raise errors.NoRepositoryPresent(a_bzrdir)
1521
return klass._find_format(format_registry, 'repository', format_string)
1523
def check_support_status(self, allow_unsupported, recommend_upgrade=True,
1525
RepositoryFormat.check_support_status(self,
1526
allow_unsupported=allow_unsupported, recommend_upgrade=recommend_upgrade,
1528
bzrdir.BzrFormat.check_support_status(self, allow_unsupported=allow_unsupported,
1529
recommend_upgrade=recommend_upgrade, basedir=basedir)
1390
1532
# formats which have no format string are not discoverable or independently
1391
1533
# creatable on disk, so are not registered in format_registry. They're
1392
# all in breezy.bzr.knitreponow. When an instance of one of these is
1534
# all in bzrlib.repofmt.knitreponow. When an instance of one of these is
1393
1535
# needed, it's constructed directly by the ControlDir. Non-native formats where
1394
1536
# the repository is not separately opened are similar.
1396
1538
format_registry.register_lazy(
1397
b'Bazaar-NG Knit Repository Format 1',
1398
'breezy.bzr.knitrepo',
1539
'Bazaar-NG Knit Repository Format 1',
1540
'bzrlib.repofmt.knitrepo',
1399
1541
'RepositoryFormatKnit1',
1402
1544
format_registry.register_lazy(
1403
b'Bazaar Knit Repository Format 3 (bzr 0.15)\n',
1404
'breezy.bzr.knitrepo',
1545
'Bazaar Knit Repository Format 3 (bzr 0.15)\n',
1546
'bzrlib.repofmt.knitrepo',
1405
1547
'RepositoryFormatKnit3',
1408
1550
format_registry.register_lazy(
1409
b'Bazaar Knit Repository Format 4 (bzr 1.0)\n',
1410
'breezy.bzr.knitrepo',
1551
'Bazaar Knit Repository Format 4 (bzr 1.0)\n',
1552
'bzrlib.repofmt.knitrepo',
1411
1553
'RepositoryFormatKnit4',
1415
1557
# post-subtrees to allow ease of testing.
1416
1558
# NOTE: These are experimental in 0.92. Stable in 1.0 and above
1417
1559
format_registry.register_lazy(
1418
b'Bazaar pack repository format 1 (needs bzr 0.92)\n',
1419
'breezy.bzr.knitpack_repo',
1560
'Bazaar pack repository format 1 (needs bzr 0.92)\n',
1561
'bzrlib.repofmt.knitpack_repo',
1420
1562
'RepositoryFormatKnitPack1',
1422
1564
format_registry.register_lazy(
1423
b'Bazaar pack repository format 1 with subtree support (needs bzr 0.92)\n',
1424
'breezy.bzr.knitpack_repo',
1565
'Bazaar pack repository format 1 with subtree support (needs bzr 0.92)\n',
1566
'bzrlib.repofmt.knitpack_repo',
1425
1567
'RepositoryFormatKnitPack3',
1427
1569
format_registry.register_lazy(
1428
b'Bazaar pack repository format 1 with rich root (needs bzr 1.0)\n',
1429
'breezy.bzr.knitpack_repo',
1570
'Bazaar pack repository format 1 with rich root (needs bzr 1.0)\n',
1571
'bzrlib.repofmt.knitpack_repo',
1430
1572
'RepositoryFormatKnitPack4',
1432
1574
format_registry.register_lazy(
1433
b'Bazaar RepositoryFormatKnitPack5 (bzr 1.6)\n',
1434
'breezy.bzr.knitpack_repo',
1575
'Bazaar RepositoryFormatKnitPack5 (bzr 1.6)\n',
1576
'bzrlib.repofmt.knitpack_repo',
1435
1577
'RepositoryFormatKnitPack5',
1437
1579
format_registry.register_lazy(
1438
b'Bazaar RepositoryFormatKnitPack5RichRoot (bzr 1.6.1)\n',
1439
'breezy.bzr.knitpack_repo',
1580
'Bazaar RepositoryFormatKnitPack5RichRoot (bzr 1.6.1)\n',
1581
'bzrlib.repofmt.knitpack_repo',
1440
1582
'RepositoryFormatKnitPack5RichRoot',
1442
1584
format_registry.register_lazy(
1443
b'Bazaar RepositoryFormatKnitPack5RichRoot (bzr 1.6)\n',
1444
'breezy.bzr.knitpack_repo',
1585
'Bazaar RepositoryFormatKnitPack5RichRoot (bzr 1.6)\n',
1586
'bzrlib.repofmt.knitpack_repo',
1445
1587
'RepositoryFormatKnitPack5RichRootBroken',
1447
1589
format_registry.register_lazy(
1448
b'Bazaar RepositoryFormatKnitPack6 (bzr 1.9)\n',
1449
'breezy.bzr.knitpack_repo',
1590
'Bazaar RepositoryFormatKnitPack6 (bzr 1.9)\n',
1591
'bzrlib.repofmt.knitpack_repo',
1450
1592
'RepositoryFormatKnitPack6',
1452
1594
format_registry.register_lazy(
1453
b'Bazaar RepositoryFormatKnitPack6RichRoot (bzr 1.9)\n',
1454
'breezy.bzr.knitpack_repo',
1595
'Bazaar RepositoryFormatKnitPack6RichRoot (bzr 1.9)\n',
1596
'bzrlib.repofmt.knitpack_repo',
1455
1597
'RepositoryFormatKnitPack6RichRoot',
1457
1599
format_registry.register_lazy(
1458
b'Bazaar repository format 2a (needs bzr 1.16 or later)\n',
1459
'breezy.bzr.groupcompress_repo',
1600
'Bazaar repository format 2a (needs bzr 1.16 or later)\n',
1601
'bzrlib.repofmt.groupcompress_repo',
1460
1602
'RepositoryFormat2a',
1463
1605
# Development formats.
1464
1606
# Check their docstrings to see if/when they are obsolete.
1465
1607
format_registry.register_lazy(
1466
(b"Bazaar development format 2 with subtree support "
1467
b"(needs bzr.dev from before 1.8)\n"),
1468
'breezy.bzr.knitpack_repo',
1608
("Bazaar development format 2 with subtree support "
1609
"(needs bzr.dev from before 1.8)\n"),
1610
'bzrlib.repofmt.knitpack_repo',
1469
1611
'RepositoryFormatPackDevelopment2Subtree',
1471
1613
format_registry.register_lazy(
1472
b'Bazaar development format 8\n',
1473
'breezy.bzr.groupcompress_repo',
1614
'Bazaar development format 8\n',
1615
'bzrlib.repofmt.groupcompress_repo',
1474
1616
'RepositoryFormat2aSubtree',
1519
1661
raise NotImplementedError(self.fetch)
1521
def search_missing_revision_ids(
1522
self, find_ghosts=True, revision_ids=None, if_present_ids=None,
1664
def search_missing_revision_ids(self,
1665
revision_id=symbol_versioning.DEPRECATED_PARAMETER,
1666
find_ghosts=True, revision_ids=None, if_present_ids=None,
1524
1668
"""Return the revision ids that source has that target does not.
1670
:param revision_id: only return revision ids included by this
1526
1672
:param revision_ids: return revision ids included by these
1527
1673
revision_ids. NoSuchRevision will be raised if any of these
1528
1674
revisions are not present.
1582
1728
:param to_convert: The disk object to convert.
1583
1729
:param pb: a progress bar to use for progress information.
1585
with ui.ui_factory.nested_progress_bar() as pb:
1588
# this is only useful with metadir layouts - separated repo content.
1589
# trigger an assertion if not such
1590
repo._format.get_format_string()
1591
self.repo_dir = repo.controldir
1592
pb.update(gettext('Moving repository to repository.backup'))
1593
self.repo_dir.transport.move('repository', 'repository.backup')
1594
backup_transport = self.repo_dir.transport.clone('repository.backup')
1595
repo._format.check_conversion_target(self.target_format)
1596
self.source_repo = repo._format.open(self.repo_dir,
1598
_override_transport=backup_transport)
1599
pb.update(gettext('Creating new repository'))
1600
converted = self.target_format.initialize(self.repo_dir,
1601
self.source_repo.is_shared())
1602
converted.lock_write()
1604
pb.update(gettext('Copying content'))
1605
self.source_repo.copy_content_into(converted)
1608
pb.update(gettext('Deleting old repository content'))
1609
self.repo_dir.transport.delete_tree('repository.backup')
1610
ui.ui_factory.note(gettext('repository converted'))
1731
pb = ui.ui_factory.nested_progress_bar()
1734
# this is only useful with metadir layouts - separated repo content.
1735
# trigger an assertion if not such
1736
repo._format.get_format_string()
1737
self.repo_dir = repo.bzrdir
1738
pb.update(gettext('Moving repository to repository.backup'))
1739
self.repo_dir.transport.move('repository', 'repository.backup')
1740
backup_transport = self.repo_dir.transport.clone('repository.backup')
1741
repo._format.check_conversion_target(self.target_format)
1742
self.source_repo = repo._format.open(self.repo_dir,
1744
_override_transport=backup_transport)
1745
pb.update(gettext('Creating new repository'))
1746
converted = self.target_format.initialize(self.repo_dir,
1747
self.source_repo.is_shared())
1748
converted.lock_write()
1750
pb.update(gettext('Copying content'))
1751
self.source_repo.copy_content_into(converted)
1754
pb.update(gettext('Deleting old repository content'))
1755
self.repo_dir.transport.delete_tree('repository.backup')
1756
ui.ui_factory.note(gettext('repository converted'))
1613
1760
def _strip_NULL_ghosts(revision_graph):