73
74
record_root_entry = True
74
75
# whether this commit builder supports the record_entry_contents interface
75
76
supports_record_entry_contents = False
77
# whether this commit builder will automatically update the branch that is
79
updates_branch = False
77
def __init__(self, repository, parents, config, timestamp=None,
81
def __init__(self, repository, parents, config_stack, timestamp=None,
78
82
timezone=None, committer=None, revprops=None,
79
83
revision_id=None, lossy=False):
80
84
"""Initiate a CommitBuilder.
89
93
:param lossy: Whether to discard data that can not be natively
90
94
represented, when pushing to a foreign VCS
96
self._config_stack = config_stack
93
97
self._lossy = lossy
95
99
if committer is None:
96
self._committer = self._config.username()
100
self._committer = self._config_stack.get('email')
97
101
elif not isinstance(committer, unicode):
98
102
self._committer = committer.decode() # throw if non-ascii
281
285
mutter('abort_write_group failed')
282
286
log_exception_quietly()
283
note('bzr: ERROR (ignored): %s', exc)
287
note(gettext('bzr: ERROR (ignored): %s'), exc)
284
288
self._write_group = None
286
290
def _abort_write_group(self):
341
345
self.control_files.break_lock()
344
def _eliminate_revisions_not_present(self, revision_ids):
345
"""Check every revision id in revision_ids to see if we have it.
347
Returns a set of the present revisions.
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()
356
def create(a_bzrdir):
357
"""Construct the current default format repository in a_bzrdir."""
358
return RepositoryFormat.get_default_format().initialize(a_bzrdir)
348
def create(controldir):
349
"""Construct the current default format repository in controldir."""
350
return RepositoryFormat.get_default_format().initialize(controldir)
360
def __init__(self, _format, a_bzrdir, control_files):
352
def __init__(self, _format, controldir, control_files):
361
353
"""instantiate a Repository.
363
355
:param _format: The format of the repository on disk.
364
:param a_bzrdir: The BzrDir of the repository.
356
:param controldir: The ControlDir of the repository.
365
357
:param control_files: Control files to use for locking, etc.
367
359
# In the future we will have a single api for all stores for
370
362
super(Repository, self).__init__()
371
363
self._format = _format
372
364
# the following are part of the public API for Repository:
373
self.bzrdir = a_bzrdir
365
self.bzrdir = controldir
374
366
self.control_files = control_files
375
self._transport = control_files._transport
376
self.base = self._transport.base
378
368
self._write_group = None
379
369
# Additional places to query for data.
418
408
if self.__class__ is not other.__class__:
420
return (self._transport.base == other._transport.base)
410
return (self.control_url == other.control_url)
422
412
def is_in_write_group(self):
423
413
"""Return True if there is an open write group.
560
550
def __init__(self):
561
551
self.first_call = True
563
def __call__(self, bzrdir):
564
# On the first call, the parameter is always the bzrdir
553
def __call__(self, controldir):
554
# On the first call, the parameter is always the controldir
565
555
# containing the current repo.
566
556
if not self.first_call:
568
repository = bzrdir.open_repository()
558
repository = controldir.open_repository()
569
559
except errors.NoRepositoryPresent:
572
562
return False, ([], repository)
573
563
self.first_call = False
574
value = (bzrdir.list_branches(), None)
564
value = (controldir.list_branches(), None)
575
565
return True, value
578
for branches, repository in bzrdir.BzrDir.find_bzrdirs(
568
for branches, repository in controldir.ControlDir.find_bzrdirs(
579
569
self.user_transport, evaluate=Evaluator()):
580
570
if branches is not None:
581
571
ret.extend(branches)
615
605
For instance, if the repository is at URL/.bzr/repository,
616
606
Repository.open(URL) -> a Repository instance.
618
control = bzrdir.BzrDir.open(base)
608
control = controldir.ControlDir.open(base)
619
609
return control.open_repository()
621
611
def copy_content_into(self, destination, revision_id=None):
679
675
def _resume_write_group(self, tokens):
680
676
raise errors.UnsuspendableWriteGroup(self)
682
def fetch(self, source, revision_id=None, find_ghosts=False,
678
def fetch(self, source, revision_id=None, find_ghosts=False):
684
679
"""Fetch the content required to construct revision_id from source.
686
If revision_id is None and fetch_spec is None, then all content is
681
If revision_id is None, then all content is copied.
689
683
fetch() may not be used when the repository is in a write group -
690
684
either finish the current write group before using fetch, or use
696
690
:param revision_id: If specified, all the content needed for this
697
691
revision ID will be copied to the target. Fetch will determine for
698
692
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
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
694
if self.is_in_write_group():
708
695
raise errors.InternalBzrError(
709
696
"May not fetch while in a write group.")
711
698
# TODO: lift out to somewhere common with RemoteRepository
712
699
# <https://bugs.launchpad.net/bzr/+bug/401646>
713
700
if (self.has_same_location(source)
714
and fetch_spec is None
715
701
and self._has_same_fallbacks(source)):
716
702
# check that last_revision is in 'from' and then return a
720
706
self.get_revision(revision_id)
722
708
inter = InterRepository.get(source, self)
723
return inter.fetch(revision_id=revision_id,
724
find_ghosts=find_ghosts, fetch_spec=fetch_spec)
709
return inter.fetch(revision_id=revision_id, find_ghosts=find_ghosts)
726
711
def create_bundle(self, target, base, fileobj, format=None):
727
712
return serializer.write_bundle(self, target, base, fileobj, format)
729
def get_commit_builder(self, branch, parents, config, timestamp=None,
714
def get_commit_builder(self, branch, parents, config_stack, timestamp=None,
730
715
timezone=None, committer=None, revprops=None,
731
716
revision_id=None, lossy=False):
732
717
"""Obtain a CommitBuilder for this repository.
734
719
:param branch: Branch to commit to.
735
720
:param parents: Revision ids of the parents of the new revision.
736
:param config: Configuration to use.
721
:param config_stack: Configuration stack to use.
737
722
:param timestamp: Optional timestamp recorded for commit.
738
723
:param timezone: Optional timezone for timestamp.
739
724
:param committer: Optional committer to set for commit.
762
def clone(self, a_bzrdir, revision_id=None):
763
"""Clone this repository into a_bzrdir using the current format.
747
def clone(self, controldir, revision_id=None):
748
"""Clone this repository into controldir using the current format.
765
750
Currently no check is made that the format of this repository and
766
751
the bzrdir format are compatible. FIXME RBC 20060201.
770
755
# TODO: deprecate after 0.16; cloning this with all its settings is
771
756
# probably not very useful -- mbp 20070423
772
dest_repo = self._create_sprouting_repo(a_bzrdir, shared=self.is_shared())
757
dest_repo = self._create_sprouting_repo(
758
controldir, shared=self.is_shared())
773
759
self.copy_content_into(dest_repo, revision_id)
942
928
parent_ids.discard(_mod_revision.NULL_REVISION)
943
929
return parent_ids
945
def fileids_altered_by_revision_ids(self, revision_ids):
946
"""Find the file ids and versions affected by revisions.
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.
953
raise NotImplementedError(self.fileids_altered_by_revision_ids)
955
931
def iter_files_bytes(self, desired_files):
956
932
"""Iterate through file versions.
1171
1147
[parents_provider, other_repository._make_parents_provider()])
1172
1148
return graph.Graph(parents_provider)
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)
1187
1150
@needs_write_lock
1188
1151
def set_make_working_trees(self, new_value):
1189
1152
"""Set the policy flag for making working trees when creating branches.
1207
1170
self.store_revision_signature(gpg_strategy, plaintext, revision_id)
1209
1172
@needs_read_lock
1210
def verify_revision(self, revision_id, gpg_strategy):
1173
def verify_revision_signature(self, revision_id, gpg_strategy):
1211
1174
"""Verify the signature on a revision.
1213
1176
:param revision_id: the revision to verify
1335
1298
def get_default(self):
1336
1299
"""Return the current default format."""
1337
from bzrlib import bzrdir
1338
return bzrdir.format_registry.make_bzrdir('default').repository_format
1300
return controldir.format_registry.make_bzrdir('default').repository_format
1341
1303
network_format_registry = registry.FormatRegistry()
1386
1348
Common instance attributes:
1387
_matchingbzrdir - the bzrdir format that the repository format was
1349
_matchingbzrdir - the controldir format that the repository format was
1388
1350
originally written to work with. This can be used if manually
1389
1351
constructing a bzrdir and repository, or more commonly for test suite
1390
1352
parameterization.
1430
1392
rich_root_data = None
1431
1393
# Does this format support explicitly versioned directories?
1432
1394
supports_versioned_directories = None
1395
# Can other repositories be nested into one of this format?
1396
supports_nesting_repositories = None
1397
# Is it possible for revisions to be present without being referenced
1399
supports_unreferenced_revisions = None
1434
1401
def __repr__(self):
1435
1402
return "%s()" % self.__class__.__name__
1442
1409
return not self == other
1445
def find_format(klass, a_bzrdir):
1446
"""Return the format for the repository object in a_bzrdir.
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
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)
1459
raise errors.UnknownFormatError(format=format_string,
1463
1412
@symbol_versioning.deprecated_method(symbol_versioning.deprecated_in((2, 4, 0)))
1464
1413
def register_format(klass, format):
1465
1414
format_registry.register(format)
1475
1424
"""Return the current default format."""
1476
1425
return format_registry.get_default()
1478
def get_format_string(self):
1479
"""Return the ASCII format string that identifies this format.
1481
Note that in pre format ?? repositories the format string is
1482
not permitted nor written to disk.
1484
raise NotImplementedError(self.get_format_string)
1486
1427
def get_format_description(self):
1487
1428
"""Return the short description for this format."""
1488
1429
raise NotImplementedError(self.get_format_description)
1490
def initialize(self, a_bzrdir, shared=False):
1491
"""Initialize a repository of this format in a_bzrdir.
1431
def initialize(self, controldir, shared=False):
1432
"""Initialize a repository of this format in controldir.
1493
:param a_bzrdir: The bzrdir to put the new repository in it.
1434
:param controldir: The controldir to put the new repository in it.
1494
1435
:param shared: The repository should be initialized as a sharable one.
1495
1436
:returns: The new repository object.
1497
1438
This may raise UninitializableFormat if shared repository are not
1498
compatible the a_bzrdir.
1439
compatible the controldir.
1500
1441
raise NotImplementedError(self.initialize)
1537
1478
'Does not support nested trees', target_format,
1538
1479
from_format=self)
1540
def open(self, a_bzrdir, _found=False):
1541
"""Return an instance of this format for the bzrdir a_bzrdir.
1481
def open(self, controldir, _found=False):
1482
"""Return an instance of this format for a controldir.
1543
1484
_found is a private parameter, do not use it.
1545
1486
raise NotImplementedError(self.open)
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']
1488
def _run_post_repo_init_hooks(self, repository, controldir, shared):
1489
from bzrlib.controldir import ControlDir, RepoInitHookParams
1490
hooks = ControlDir.hooks['post_repo_init']
1552
params = RepoInitHookParams(repository, self, a_bzrdir, shared)
1493
params = RepoInitHookParams(repository, self, controldir, shared)
1553
1494
for hook in hooks:
1557
class MetaDirRepositoryFormat(RepositoryFormat):
1498
class RepositoryFormatMetaDir(bzrdir.BzrDirMetaComponentFormat, RepositoryFormat):
1558
1499
"""Common base class for the new repositories using the metadir layout."""
1560
1501
rich_root_data = False
1561
1502
supports_tree_reference = False
1562
1503
supports_external_lookups = False
1563
1504
supports_leaving_lock = True
1505
supports_nesting_repositories = True
1566
1508
def _matchingbzrdir(self):
1569
1511
return matching
1571
1513
def __init__(self):
1572
super(MetaDirRepositoryFormat, self).__init__()
1514
RepositoryFormat.__init__(self)
1515
bzrdir.BzrDirMetaComponentFormat.__init__(self)
1574
1517
def _create_control_files(self, a_bzrdir):
1575
1518
"""Create the required files and the initial control_files object."""
1600
1543
control_files.unlock()
1602
def network_name(self):
1603
"""Metadir formats have matching disk and network format strings."""
1604
return self.get_format_string()
1546
def find_format(klass, a_bzrdir):
1547
"""Return the format for the repository object in a_bzrdir.
1549
This is used by bzr native formats that have a "format" file in
1550
the repository. Other methods may be used by different types of
1554
transport = a_bzrdir.get_repository_transport(None)
1555
format_string = transport.get_bytes("format")
1556
except errors.NoSuchFile:
1557
raise errors.NoRepositoryPresent(a_bzrdir)
1558
return klass._find_format(format_registry, 'repository', format_string)
1607
1561
# formats which have no format string are not discoverable or independently
1608
1562
# creatable on disk, so are not registered in format_registry. They're
1609
1563
# 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
1564
# needed, it's constructed directly by the ControlDir. Non-native formats where
1611
1565
# the repository is not separately opened are similar.
1613
1567
format_registry.register_lazy(
1724
1678
self.target.fetch(self.source, revision_id=revision_id)
1726
1680
@needs_write_lock
1727
def fetch(self, revision_id=None, find_ghosts=False,
1681
def fetch(self, revision_id=None, find_ghosts=False):
1729
1682
"""Fetch the content required to construct revision_id.
1731
1684
The content is copied from self.source to self.target.
1811
1764
# trigger an assertion if not such
1812
1765
repo._format.get_format_string()
1813
1766
self.repo_dir = repo.bzrdir
1814
pb.update('Moving repository to repository.backup')
1767
pb.update(gettext('Moving repository to repository.backup'))
1815
1768
self.repo_dir.transport.move('repository', 'repository.backup')
1816
1769
backup_transport = self.repo_dir.transport.clone('repository.backup')
1817
1770
repo._format.check_conversion_target(self.target_format)
1818
1771
self.source_repo = repo._format.open(self.repo_dir,
1820
1773
_override_transport=backup_transport)
1821
pb.update('Creating new repository')
1774
pb.update(gettext('Creating new repository'))
1822
1775
converted = self.target_format.initialize(self.repo_dir,
1823
1776
self.source_repo.is_shared())
1824
1777
converted.lock_write()
1826
pb.update('Copying content')
1779
pb.update(gettext('Copying content'))
1827
1780
self.source_repo.copy_content_into(converted)
1829
1782
converted.unlock()
1830
pb.update('Deleting old repository content')
1783
pb.update(gettext('Deleting old repository content'))
1831
1784
self.repo_dir.transport.delete_tree('repository.backup')
1832
ui.ui_factory.note('repository converted')
1785
ui.ui_factory.note(gettext('repository converted'))