305
305
Currently no check is made that the format of this repository and
306
306
the bzrdir format are compatible. FIXME RBC 20060201.
308
:return: The newly created destination repository.
308
310
if not isinstance(a_bzrdir._format, self.bzrdir._format.__class__):
309
311
# use target default format.
310
result = a_bzrdir.create_repository()
311
# FIXME RBC 20060209 split out the repository type to avoid this check ?
312
elif isinstance(a_bzrdir._format,
313
(bzrdir.BzrDirFormat4,
314
bzrdir.BzrDirFormat5,
315
bzrdir.BzrDirFormat6)):
316
result = a_bzrdir.open_repository()
312
dest_repo = a_bzrdir.create_repository()
318
result = self._format.initialize(a_bzrdir, shared=self.is_shared())
319
self.copy_content_into(result, revision_id, basis)
314
# Most control formats need the repository to be specifically
315
# created, but on some old all-in-one formats it's not needed
317
dest_repo = self._format.initialize(a_bzrdir, shared=self.is_shared())
318
except errors.UninitializableFormat:
319
dest_repo = a_bzrdir.open_repository()
320
self.copy_content_into(dest_repo, revision_id, basis)
323
324
def has_revision(self, revision_id):
779
780
raise errors.NonAsciiRevisionId(method, self)
782
class AllInOneRepository(Repository):
783
"""Legacy support - the repository behaviour for all-in-one branches."""
785
def __init__(self, _format, a_bzrdir, _revision_store, control_store, text_store):
786
# we reuse one control files instance.
787
dir_mode = a_bzrdir._control_files._dir_mode
788
file_mode = a_bzrdir._control_files._file_mode
790
def get_store(name, compressed=True, prefixed=False):
791
# FIXME: This approach of assuming stores are all entirely compressed
792
# or entirely uncompressed is tidy, but breaks upgrade from
793
# some existing branches where there's a mixture; we probably
794
# still want the option to look for both.
795
relpath = a_bzrdir._control_files._escape(name)
796
store = TextStore(a_bzrdir._control_files._transport.clone(relpath),
797
prefixed=prefixed, compressed=compressed,
800
#if self._transport.should_cache():
801
# cache_path = os.path.join(self.cache_root, name)
802
# os.mkdir(cache_path)
803
# store = bzrlib.store.CachedStore(store, cache_path)
806
# not broken out yet because the controlweaves|inventory_store
807
# and text_store | weave_store bits are still different.
808
if isinstance(_format, RepositoryFormat4):
809
# cannot remove these - there is still no consistent api
810
# which allows access to this old info.
811
self.inventory_store = get_store('inventory-store')
812
text_store = get_store('text-store')
813
super(AllInOneRepository, self).__init__(_format, a_bzrdir, a_bzrdir._control_files, _revision_store, control_store, text_store)
815
def get_commit_builder(self, branch, parents, config, timestamp=None,
816
timezone=None, committer=None, revprops=None,
818
self._check_ascii_revisionid(revision_id, self.get_commit_builder)
819
return Repository.get_commit_builder(self, branch, parents, config,
820
timestamp, timezone, committer, revprops, revision_id)
824
"""AllInOne repositories cannot be shared."""
828
def set_make_working_trees(self, new_value):
829
"""Set the policy flag for making working trees when creating branches.
831
This only applies to branches that use this repository.
833
The default is 'True'.
834
:param new_value: True to restore the default, False to disable making
837
raise NotImplementedError(self.set_make_working_trees)
839
def make_working_trees(self):
840
"""Returns the policy for making working trees on new branches."""
844
783
def install_revision(repository, rev, revision_tree):
845
784
"""Install all revision data into a repository."""
846
785
present_parents = []
1306
1234
raise NotImplementedError(self.open)
1309
class PreSplitOutRepositoryFormat(RepositoryFormat):
1310
"""Base class for the pre split out repository formats."""
1312
rich_root_data = False
1314
def initialize(self, a_bzrdir, shared=False, _internal=False):
1315
"""Create a weave repository.
1317
TODO: when creating split out bzr branch formats, move this to a common
1318
base for Format5, Format6. or something like that.
1321
raise errors.IncompatibleFormat(self, a_bzrdir._format)
1324
# always initialized when the bzrdir is.
1325
return self.open(a_bzrdir, _found=True)
1327
# Create an empty weave
1329
weavefile.write_weave_v5(weave.Weave(), sio)
1330
empty_weave = sio.getvalue()
1332
mutter('creating repository in %s.', a_bzrdir.transport.base)
1333
dirs = ['revision-store', 'weaves']
1334
files = [('inventory.weave', StringIO(empty_weave)),
1337
# FIXME: RBC 20060125 don't peek under the covers
1338
# NB: no need to escape relative paths that are url safe.
1339
control_files = lockable_files.LockableFiles(a_bzrdir.transport,
1340
'branch-lock', lockable_files.TransportLock)
1341
control_files.create_lock()
1342
control_files.lock_write()
1343
control_files._transport.mkdir_multi(dirs,
1344
mode=control_files._dir_mode)
1346
for file, content in files:
1347
control_files.put(file, content)
1349
control_files.unlock()
1350
return self.open(a_bzrdir, _found=True)
1352
def _get_control_store(self, repo_transport, control_files):
1353
"""Return the control store for this repository."""
1354
return self._get_versioned_file_store('',
1359
def _get_text_store(self, transport, control_files):
1360
"""Get a store for file texts for this format."""
1361
raise NotImplementedError(self._get_text_store)
1363
def open(self, a_bzrdir, _found=False):
1364
"""See RepositoryFormat.open()."""
1366
# we are being called directly and must probe.
1367
raise NotImplementedError
1369
repo_transport = a_bzrdir.get_repository_transport(None)
1370
control_files = a_bzrdir._control_files
1371
text_store = self._get_text_store(repo_transport, control_files)
1372
control_store = self._get_control_store(repo_transport, control_files)
1373
_revision_store = self._get_revision_store(repo_transport, control_files)
1374
return AllInOneRepository(_format=self,
1376
_revision_store=_revision_store,
1377
control_store=control_store,
1378
text_store=text_store)
1380
def check_conversion_target(self, target_format):
1384
class RepositoryFormat4(PreSplitOutRepositoryFormat):
1385
"""Bzr repository format 4.
1387
This repository format has:
1389
- TextStores for texts, inventories,revisions.
1391
This format is deprecated: it indexes texts using a text id which is
1392
removed in format 5; initialization and write support for this format
1397
super(RepositoryFormat4, self).__init__()
1398
self._matchingbzrdir = bzrdir.BzrDirFormat4()
1400
def get_format_description(self):
1401
"""See RepositoryFormat.get_format_description()."""
1402
return "Repository format 4"
1404
def initialize(self, url, shared=False, _internal=False):
1405
"""Format 4 branches cannot be created."""
1406
raise errors.UninitializableFormat(self)
1408
def is_supported(self):
1409
"""Format 4 is not supported.
1411
It is not supported because the model changed from 4 to 5 and the
1412
conversion logic is expensive - so doing it on the fly was not
1417
def _get_control_store(self, repo_transport, control_files):
1418
"""Format 4 repositories have no formal control store at this point.
1420
This will cause any control-file-needing apis to fail - this is desired.
1424
def _get_revision_store(self, repo_transport, control_files):
1425
"""See RepositoryFormat._get_revision_store()."""
1426
from bzrlib.xml4 import serializer_v4
1427
return self._get_text_rev_store(repo_transport,
1430
serializer=serializer_v4)
1432
def _get_text_store(self, transport, control_files):
1433
"""See RepositoryFormat._get_text_store()."""
1436
class RepositoryFormat5(PreSplitOutRepositoryFormat):
1437
"""Bzr control format 5.
1439
This repository format has:
1440
- weaves for file texts and inventory
1442
- TextStores for revisions and signatures.
1446
super(RepositoryFormat5, self).__init__()
1447
self._matchingbzrdir = bzrdir.BzrDirFormat5()
1449
def get_format_description(self):
1450
"""See RepositoryFormat.get_format_description()."""
1451
return "Weave repository format 5"
1453
def _get_revision_store(self, repo_transport, control_files):
1454
"""See RepositoryFormat._get_revision_store()."""
1455
"""Return the revision store object for this a_bzrdir."""
1456
return self._get_text_rev_store(repo_transport,
1461
def _get_text_store(self, transport, control_files):
1462
"""See RepositoryFormat._get_text_store()."""
1463
return self._get_versioned_file_store('weaves', transport, control_files, prefixed=False)
1466
class RepositoryFormat6(PreSplitOutRepositoryFormat):
1467
"""Bzr control format 6.
1469
This repository format has:
1470
- weaves for file texts and inventory
1471
- hash subdirectory based stores.
1472
- TextStores for revisions and signatures.
1476
super(RepositoryFormat6, self).__init__()
1477
self._matchingbzrdir = bzrdir.BzrDirFormat6()
1479
def get_format_description(self):
1480
"""See RepositoryFormat.get_format_description()."""
1481
return "Weave repository format 6"
1483
def _get_revision_store(self, repo_transport, control_files):
1484
"""See RepositoryFormat._get_revision_store()."""
1485
return self._get_text_rev_store(repo_transport,
1491
def _get_text_store(self, transport, control_files):
1492
"""See RepositoryFormat._get_text_store()."""
1493
return self._get_versioned_file_store('weaves', transport, control_files)
1496
1237
class MetaDirRepositoryFormat(RepositoryFormat):
1497
1238
"""Common base class for the new repositories using the metadir layout."""
1529
1270
control_files.unlock()
1532
class RepositoryFormat7(MetaDirRepositoryFormat):
1533
"""Bzr repository 7.
1535
This repository format has:
1536
- weaves for file texts and inventory
1537
- hash subdirectory based stores.
1538
- TextStores for revisions and signatures.
1539
- a format marker of its own
1540
- an optional 'shared-storage' flag
1541
- an optional 'no-working-trees' flag
1544
def _get_control_store(self, repo_transport, control_files):
1545
"""Return the control store for this repository."""
1546
return self._get_versioned_file_store('',
1551
def get_format_string(self):
1552
"""See RepositoryFormat.get_format_string()."""
1553
return "Bazaar-NG Repository format 7"
1555
def get_format_description(self):
1556
"""See RepositoryFormat.get_format_description()."""
1557
return "Weave repository format 7"
1559
def check_conversion_target(self, target_format):
1562
def _get_revision_store(self, repo_transport, control_files):
1563
"""See RepositoryFormat._get_revision_store()."""
1564
return self._get_text_rev_store(repo_transport,
1571
def _get_text_store(self, transport, control_files):
1572
"""See RepositoryFormat._get_text_store()."""
1573
return self._get_versioned_file_store('weaves',
1577
def initialize(self, a_bzrdir, shared=False):
1578
"""Create a weave repository.
1580
:param shared: If true the repository will be initialized as a shared
1583
# Create an empty weave
1585
weavefile.write_weave_v5(weave.Weave(), sio)
1586
empty_weave = sio.getvalue()
1588
mutter('creating repository in %s.', a_bzrdir.transport.base)
1589
dirs = ['revision-store', 'weaves']
1590
files = [('inventory.weave', StringIO(empty_weave)),
1592
utf8_files = [('format', self.get_format_string())]
1594
self._upload_blank_content(a_bzrdir, dirs, files, utf8_files, shared)
1595
return self.open(a_bzrdir=a_bzrdir, _found=True)
1597
def open(self, a_bzrdir, _found=False, _override_transport=None):
1598
"""See RepositoryFormat.open().
1600
:param _override_transport: INTERNAL USE ONLY. Allows opening the
1601
repository at a slightly different url
1602
than normal. I.e. during 'upgrade'.
1605
format = RepositoryFormat.find_format(a_bzrdir)
1606
assert format.__class__ == self.__class__
1607
if _override_transport is not None:
1608
repo_transport = _override_transport
1610
repo_transport = a_bzrdir.get_repository_transport(None)
1611
control_files = lockable_files.LockableFiles(repo_transport,
1612
'lock', lockdir.LockDir)
1613
text_store = self._get_text_store(repo_transport, control_files)
1614
control_store = self._get_control_store(repo_transport, control_files)
1615
_revision_store = self._get_revision_store(repo_transport, control_files)
1616
return WeaveMetaDirRepository(_format=self,
1618
control_files=control_files,
1619
_revision_store=_revision_store,
1620
control_store=control_store,
1621
text_store=text_store)
1624
1273
class RepositoryFormatKnit(MetaDirRepositoryFormat):
1625
1274
"""Bzr repository knit format (generalized).
1945
1595
return f.count_copied, f.failed_revisions
1948
class InterWeaveRepo(InterSameDataRepository):
1949
"""Optimised code paths between Weave based repositories."""
1951
_matching_repo_format = RepositoryFormat7()
1952
"""Repository format for testing with."""
1955
def is_compatible(source, target):
1956
"""Be compatible with known Weave formats.
1958
We don't test for the stores being of specific types because that
1959
could lead to confusing results, and there is no need to be
1963
return (isinstance(source._format, (RepositoryFormat5,
1965
RepositoryFormat7)) and
1966
isinstance(target._format, (RepositoryFormat5,
1968
RepositoryFormat7)))
1969
except AttributeError:
1973
def copy_content(self, revision_id=None, basis=None):
1974
"""See InterRepository.copy_content()."""
1975
# weave specific optimised path:
1976
if basis is not None:
1977
# copy the basis in, then fetch remaining data.
1978
basis.copy_content_into(self.target, revision_id)
1979
# the basis copy_content_into could miss-set this.
1981
self.target.set_make_working_trees(self.source.make_working_trees())
1982
except NotImplementedError:
1984
self.target.fetch(self.source, revision_id=revision_id)
1987
self.target.set_make_working_trees(self.source.make_working_trees())
1988
except NotImplementedError:
1990
# FIXME do not peek!
1991
if self.source.control_files._transport.listable():
1992
pb = ui.ui_factory.nested_progress_bar()
1994
self.target.weave_store.copy_all_ids(
1995
self.source.weave_store,
1997
from_transaction=self.source.get_transaction(),
1998
to_transaction=self.target.get_transaction())
1999
pb.update('copying inventory', 0, 1)
2000
self.target.control_weaves.copy_multi(
2001
self.source.control_weaves, ['inventory'],
2002
from_transaction=self.source.get_transaction(),
2003
to_transaction=self.target.get_transaction())
2004
self.target._revision_store.text_store.copy_all_ids(
2005
self.source._revision_store.text_store,
2010
self.target.fetch(self.source, revision_id=revision_id)
2013
def fetch(self, revision_id=None, pb=None):
2014
"""See InterRepository.fetch()."""
2015
from bzrlib.fetch import GenericRepoFetcher
2016
mutter("Using fetch logic to copy between %s(%s) and %s(%s)",
2017
self.source, self.source._format, self.target, self.target._format)
2018
f = GenericRepoFetcher(to_repository=self.target,
2019
from_repository=self.source,
2020
last_revision=revision_id,
2022
return f.count_copied, f.failed_revisions
2025
def missing_revision_ids(self, revision_id=None):
2026
"""See InterRepository.missing_revision_ids()."""
2027
# we want all revisions to satisfy revision_id in source.
2028
# but we don't want to stat every file here and there.
2029
# we want then, all revisions other needs to satisfy revision_id
2030
# checked, but not those that we have locally.
2031
# so the first thing is to get a subset of the revisions to
2032
# satisfy revision_id in source, and then eliminate those that
2033
# we do already have.
2034
# this is slow on high latency connection to self, but as as this
2035
# disk format scales terribly for push anyway due to rewriting
2036
# inventory.weave, this is considered acceptable.
2038
if revision_id is not None:
2039
source_ids = self.source.get_ancestry(revision_id)
2040
assert source_ids[0] is None
2043
source_ids = self.source._all_possible_ids()
2044
source_ids_set = set(source_ids)
2045
# source_ids is the worst possible case we may need to pull.
2046
# now we want to filter source_ids against what we actually
2047
# have in target, but don't try to check for existence where we know
2048
# we do not have a revision as that would be pointless.
2049
target_ids = set(self.target._all_possible_ids())
2050
possibly_present_revisions = target_ids.intersection(source_ids_set)
2051
actually_present_revisions = set(self.target._eliminate_revisions_not_present(possibly_present_revisions))
2052
required_revisions = source_ids_set.difference(actually_present_revisions)
2053
required_topo_revisions = [rev_id for rev_id in source_ids if rev_id in required_revisions]
2054
if revision_id is not None:
2055
# we used get_ancestry to determine source_ids then we are assured all
2056
# revisions referenced are present as they are installed in topological order.
2057
# and the tip revision was validated by get_ancestry.
2058
return required_topo_revisions
2060
# if we just grabbed the possibly available ids, then
2061
# we only have an estimate of whats available and need to validate
2062
# that against the revision records.
2063
return self.source._eliminate_revisions_not_present(required_topo_revisions)
2066
1598
class InterKnitRepo(InterSameDataRepository):
2067
1599
"""Optimised code paths between Knit based repositories."""