92
def add_inventory(self, revid, inv, parents):
93
"""Add the inventory inv to the repository as revid.
85
def add_inventory(self, revision_id, inv, parents):
86
"""Add the inventory inv to the repository as revision_id.
95
:param parents: The revision ids of the parents that revid
88
:param parents: The revision ids of the parents that revision_id
96
89
is known to have and are in the repository already.
98
91
returns the sha1 of the serialized inventory.
100
assert inv.revision_id is None or inv.revision_id == revid, \
93
revision_id = osutils.safe_revision_id(revision_id)
94
_mod_revision.check_not_reserved_id(revision_id)
95
assert inv.revision_id is None or inv.revision_id == revision_id, \
101
96
"Mismatch between inventory revision" \
102
" id and insertion revid (%r, %r)" % (inv.revision_id, revid)
97
" id and insertion revid (%r, %r)" % (inv.revision_id, revision_id)
103
98
assert inv.root is not None
104
99
inv_text = self.serialise_inventory(inv)
105
100
inv_sha1 = osutils.sha_string(inv_text)
106
101
inv_vf = self.control_weaves.get_weave('inventory',
107
102
self.get_transaction())
108
self._inventory_add_lines(inv_vf, revid, parents, osutils.split_lines(inv_text))
103
self._inventory_add_lines(inv_vf, revision_id, parents,
104
osutils.split_lines(inv_text))
111
def _inventory_add_lines(self, inv_vf, revid, parents, lines):
107
def _inventory_add_lines(self, inv_vf, revision_id, parents, lines):
112
108
final_parents = []
113
109
for parent in parents:
114
110
if parent in inv_vf:
115
111
final_parents.append(parent)
117
inv_vf.add_lines(revid, final_parents, lines)
113
inv_vf.add_lines(revision_id, final_parents, lines)
119
115
@needs_write_lock
120
def add_revision(self, rev_id, rev, inv=None, config=None):
121
"""Add rev to the revision store as rev_id.
116
def add_revision(self, revision_id, rev, inv=None, config=None):
117
"""Add rev to the revision store as revision_id.
123
:param rev_id: the revision id to use.
119
:param revision_id: the revision id to use.
124
120
:param rev: The revision object.
125
121
:param inv: The inventory for the revision. if None, it will be looked
126
122
up in the inventory storer
239
257
def get_physical_lock_status(self):
240
258
return self.control_files.get_physical_lock_status()
260
def leave_lock_in_place(self):
261
"""Tell this repository not to release the physical lock when this
264
If lock_write doesn't return a token, then this method is not supported.
266
self.control_files.leave_in_place()
268
def dont_leave_lock_in_place(self):
269
"""Tell this repository to release the physical lock when this
270
object is unlocked, even if it didn't originally acquire it.
272
If lock_write doesn't return a token, then this method is not supported.
274
self.control_files.dont_leave_in_place()
277
def gather_stats(self, revid=None, committers=None):
278
"""Gather statistics from a revision id.
280
:param revid: The revision id to gather statistics from, if None, then
281
no revision specific statistics are gathered.
282
:param committers: Optional parameter controlling whether to grab
283
a count of committers from the revision specific statistics.
284
:return: A dictionary of statistics. Currently this contains:
285
committers: The number of committers if requested.
286
firstrev: A tuple with timestamp, timezone for the penultimate left
287
most ancestor of revid, if revid is not the NULL_REVISION.
288
latestrev: A tuple with timestamp, timezone for revid, if revid is
289
not the NULL_REVISION.
290
revisions: The total revision count in the repository.
291
size: An estimate disk size of the repository in bytes.
294
if revid and committers:
295
result['committers'] = 0
296
if revid and revid != _mod_revision.NULL_REVISION:
298
all_committers = set()
299
revisions = self.get_ancestry(revid)
300
# pop the leading None
302
first_revision = None
304
# ignore the revisions in the middle - just grab first and last
305
revisions = revisions[0], revisions[-1]
306
for revision in self.get_revisions(revisions):
307
if not first_revision:
308
first_revision = revision
310
all_committers.add(revision.committer)
311
last_revision = revision
313
result['committers'] = len(all_committers)
314
result['firstrev'] = (first_revision.timestamp,
315
first_revision.timezone)
316
result['latestrev'] = (last_revision.timestamp,
317
last_revision.timezone)
319
# now gather global repository information
320
if self.bzrdir.root_transport.listable():
321
c, t = self._revision_store.total_size(self.get_transaction())
322
result['revisions'] = c
243
327
def missing_revision_ids(self, other, revision_id=None):
244
328
"""Return the revision ids that other has that this does not.
748
923
revision_id.encode('ascii')
749
924
except UnicodeEncodeError:
750
925
raise errors.NonAsciiRevisionId(method, self)
753
class AllInOneRepository(Repository):
754
"""Legacy support - the repository behaviour for all-in-one branches."""
756
def __init__(self, _format, a_bzrdir, _revision_store, control_store, text_store):
757
# we reuse one control files instance.
758
dir_mode = a_bzrdir._control_files._dir_mode
759
file_mode = a_bzrdir._control_files._file_mode
761
def get_store(name, compressed=True, prefixed=False):
762
# FIXME: This approach of assuming stores are all entirely compressed
763
# or entirely uncompressed is tidy, but breaks upgrade from
764
# some existing branches where there's a mixture; we probably
765
# still want the option to look for both.
766
relpath = a_bzrdir._control_files._escape(name)
767
store = TextStore(a_bzrdir._control_files._transport.clone(relpath),
768
prefixed=prefixed, compressed=compressed,
771
#if self._transport.should_cache():
772
# cache_path = os.path.join(self.cache_root, name)
773
# os.mkdir(cache_path)
774
# store = bzrlib.store.CachedStore(store, cache_path)
777
# not broken out yet because the controlweaves|inventory_store
778
# and text_store | weave_store bits are still different.
779
if isinstance(_format, RepositoryFormat4):
780
# cannot remove these - there is still no consistent api
781
# which allows access to this old info.
782
self.inventory_store = get_store('inventory-store')
783
text_store = get_store('text-store')
784
super(AllInOneRepository, self).__init__(_format, a_bzrdir, a_bzrdir._control_files, _revision_store, control_store, text_store)
786
def get_commit_builder(self, branch, parents, config, timestamp=None,
787
timezone=None, committer=None, revprops=None,
789
self._check_ascii_revisionid(revision_id, self.get_commit_builder)
790
return Repository.get_commit_builder(self, branch, parents, config,
791
timestamp, timezone, committer, revprops, revision_id)
795
"""AllInOne repositories cannot be shared."""
799
def set_make_working_trees(self, new_value):
800
"""Set the policy flag for making working trees when creating branches.
802
This only applies to branches that use this repository.
804
The default is 'True'.
805
:param new_value: True to restore the default, False to disable making
808
raise NotImplementedError(self.set_make_working_trees)
810
def make_working_trees(self):
811
"""Returns the policy for making working trees on new branches."""
928
revision_id.decode('ascii')
929
except UnicodeDecodeError:
930
raise errors.NonAsciiRevisionId(method, self)
934
# remove these delegates a while after bzr 0.15
935
def __make_delegated(name, from_module):
936
def _deprecated_repository_forwarder():
937
symbol_versioning.warn('%s moved to %s in bzr 0.15'
938
% (name, from_module),
941
m = __import__(from_module, globals(), locals(), [name])
943
return getattr(m, name)
944
except AttributeError:
945
raise AttributeError('module %s has no name %s'
947
globals()[name] = _deprecated_repository_forwarder
950
'AllInOneRepository',
951
'WeaveMetaDirRepository',
952
'PreSplitOutRepositoryFormat',
958
__make_delegated(_name, 'bzrlib.repofmt.weaverepo')
962
'RepositoryFormatKnit',
963
'RepositoryFormatKnit1',
965
__make_delegated(_name, 'bzrlib.repofmt.knitrepo')
815
968
def install_revision(repository, rev, revision_tree):
901
1054
return not self.control_files._transport.has('no-working-trees')
904
class WeaveMetaDirRepository(MetaDirRepository):
905
"""A subclass of MetaDirRepository to set weave specific policy."""
907
def get_commit_builder(self, branch, parents, config, timestamp=None,
908
timezone=None, committer=None, revprops=None,
910
self._check_ascii_revisionid(revision_id, self.get_commit_builder)
911
return MetaDirRepository.get_commit_builder(self, branch, parents,
912
config, timestamp, timezone, committer, revprops, revision_id)
915
class KnitRepository(MetaDirRepository):
916
"""Knit format repository."""
918
def _warn_if_deprecated(self):
919
# This class isn't deprecated
922
def _inventory_add_lines(self, inv_vf, revid, parents, lines):
923
inv_vf.add_lines_with_ghosts(revid, parents, lines)
926
def _all_revision_ids(self):
927
"""See Repository.all_revision_ids()."""
928
# Knits get the revision graph from the index of the revision knit, so
929
# it's always possible even if they're on an unlistable transport.
930
return self._revision_store.all_revision_ids(self.get_transaction())
932
def fileid_involved_between_revs(self, from_revid, to_revid):
933
"""Find file_id(s) which are involved in the changes between revisions.
935
This determines the set of revisions which are involved, and then
936
finds all file ids affected by those revisions.
938
vf = self._get_revision_vf()
939
from_set = set(vf.get_ancestry(from_revid))
940
to_set = set(vf.get_ancestry(to_revid))
941
changed = to_set.difference(from_set)
942
return self._fileid_involved_by_set(changed)
944
def fileid_involved(self, last_revid=None):
945
"""Find all file_ids modified in the ancestry of last_revid.
947
:param last_revid: If None, last_revision() will be used.
950
changed = set(self.all_revision_ids())
952
changed = set(self.get_ancestry(last_revid))
955
return self._fileid_involved_by_set(changed)
958
def get_ancestry(self, revision_id):
959
"""Return a list of revision-ids integrated by a revision.
961
This is topologically sorted.
963
if revision_id is None:
965
vf = self._get_revision_vf()
967
return [None] + vf.get_ancestry(revision_id)
968
except errors.RevisionNotPresent:
969
raise errors.NoSuchRevision(self, revision_id)
972
def get_revision(self, revision_id):
973
"""Return the Revision object for a named revision"""
974
return self.get_revision_reconcile(revision_id)
977
def get_revision_graph(self, revision_id=None):
978
"""Return a dictionary containing the revision graph.
980
:param revision_id: The revision_id to get a graph from. If None, then
981
the entire revision graph is returned. This is a deprecated mode of
982
operation and will be removed in the future.
983
:return: a dictionary of revision_id->revision_parents_list.
985
# special case NULL_REVISION
986
if revision_id == _mod_revision.NULL_REVISION:
988
a_weave = self._get_revision_vf()
989
entire_graph = a_weave.get_graph()
990
if revision_id is None:
991
return a_weave.get_graph()
992
elif revision_id not in a_weave:
993
raise errors.NoSuchRevision(self, revision_id)
995
# add what can be reached from revision_id
997
pending = set([revision_id])
998
while len(pending) > 0:
1000
result[node] = a_weave.get_parents(node)
1001
for revision_id in result[node]:
1002
if revision_id not in result:
1003
pending.add(revision_id)
1007
def get_revision_graph_with_ghosts(self, revision_ids=None):
1008
"""Return a graph of the revisions with ghosts marked as applicable.
1010
:param revision_ids: an iterable of revisions to graph or None for all.
1011
:return: a Graph object with the graph reachable from revision_ids.
1013
result = graph.Graph()
1014
vf = self._get_revision_vf()
1015
versions = set(vf.versions())
1016
if not revision_ids:
1017
pending = set(self.all_revision_ids())
1020
pending = set(revision_ids)
1021
# special case NULL_REVISION
1022
if _mod_revision.NULL_REVISION in pending:
1023
pending.remove(_mod_revision.NULL_REVISION)
1024
required = set(pending)
1027
revision_id = pending.pop()
1028
if not revision_id in versions:
1029
if revision_id in required:
1030
raise errors.NoSuchRevision(self, revision_id)
1032
result.add_ghost(revision_id)
1033
# mark it as done so we don't try for it again.
1034
done.add(revision_id)
1036
parent_ids = vf.get_parents_with_ghosts(revision_id)
1037
for parent_id in parent_ids:
1038
# is this queued or done ?
1039
if (parent_id not in pending and
1040
parent_id not in done):
1042
pending.add(parent_id)
1043
result.add_node(revision_id, parent_ids)
1044
done.add(revision_id)
1047
def _get_revision_vf(self):
1048
""":return: a versioned file containing the revisions."""
1049
vf = self._revision_store.get_revision_file(self.get_transaction())
1053
def reconcile(self, other=None, thorough=False):
1054
"""Reconcile this repository."""
1055
from bzrlib.reconcile import KnitReconciler
1056
reconciler = KnitReconciler(self, thorough=thorough)
1057
reconciler.reconcile()
1057
class RepositoryFormatRegistry(registry.Registry):
1058
"""Registry of RepositoryFormats.
1061
def get(self, format_string):
1062
r = registry.Registry.get(self, format_string)
1060
def revision_parents(self, revision_id):
1061
return self._get_revision_vf().get_parents(revision_id)
1064
class KnitRepository2(KnitRepository):
1066
def __init__(self, _format, a_bzrdir, control_files, _revision_store,
1067
control_store, text_store):
1068
KnitRepository.__init__(self, _format, a_bzrdir, control_files,
1069
_revision_store, control_store, text_store)
1070
self._serializer = xml6.serializer_v6
1072
def deserialise_inventory(self, revision_id, xml):
1073
"""Transform the xml into an inventory object.
1075
:param revision_id: The expected revision id of the inventory.
1076
:param xml: A serialised inventory.
1078
result = self._serializer.read_inventory_from_string(xml)
1079
assert result.root.revision is not None
1082
def serialise_inventory(self, inv):
1083
"""Transform the inventory object into XML text.
1085
:param revision_id: The expected revision id of the inventory.
1086
:param xml: A serialised inventory.
1088
assert inv.revision_id is not None
1089
assert inv.root.revision is not None
1090
return KnitRepository.serialise_inventory(self, inv)
1092
def get_commit_builder(self, branch, parents, config, timestamp=None,
1093
timezone=None, committer=None, revprops=None,
1095
"""Obtain a CommitBuilder for this repository.
1097
:param branch: Branch to commit to.
1098
:param parents: Revision ids of the parents of the new revision.
1099
:param config: Configuration to use.
1100
:param timestamp: Optional timestamp recorded for commit.
1101
:param timezone: Optional timezone for timestamp.
1102
:param committer: Optional committer to set for commit.
1103
:param revprops: Optional dictionary of revision properties.
1104
:param revision_id: Optional revision id.
1106
return RootCommitBuilder(self, parents, config, timestamp, timezone,
1107
committer, revprops, revision_id)
1068
format_registry = RepositoryFormatRegistry()
1069
"""Registry of formats, indexed by their identifying format string.
1071
This can contain either format instances themselves, or classes/factories that
1072
can be called to obtain one.
1076
#####################################################################
1077
# Repository Formats
1110
1079
class RepositoryFormat(object):
1111
1080
"""A repository format.
1248
1238
raise NotImplementedError(self.open)
1251
def register_format(klass, format):
1252
klass._formats[format.get_format_string()] = format
1255
def set_default_format(klass, format):
1256
klass._default_format = format
1259
def unregister_format(klass, format):
1260
assert klass._formats[format.get_format_string()] is format
1261
del klass._formats[format.get_format_string()]
1264
class PreSplitOutRepositoryFormat(RepositoryFormat):
1265
"""Base class for the pre split out repository formats."""
1267
rich_root_data = False
1269
def initialize(self, a_bzrdir, shared=False, _internal=False):
1270
"""Create a weave repository.
1272
TODO: when creating split out bzr branch formats, move this to a common
1273
base for Format5, Format6. or something like that.
1276
raise errors.IncompatibleFormat(self, a_bzrdir._format)
1279
# always initialized when the bzrdir is.
1280
return self.open(a_bzrdir, _found=True)
1282
# Create an empty weave
1284
weavefile.write_weave_v5(weave.Weave(), sio)
1285
empty_weave = sio.getvalue()
1287
mutter('creating repository in %s.', a_bzrdir.transport.base)
1288
dirs = ['revision-store', 'weaves']
1289
files = [('inventory.weave', StringIO(empty_weave)),
1292
# FIXME: RBC 20060125 don't peek under the covers
1293
# NB: no need to escape relative paths that are url safe.
1294
control_files = lockable_files.LockableFiles(a_bzrdir.transport,
1295
'branch-lock', lockable_files.TransportLock)
1296
control_files.create_lock()
1297
control_files.lock_write()
1298
control_files._transport.mkdir_multi(dirs,
1299
mode=control_files._dir_mode)
1301
for file, content in files:
1302
control_files.put(file, content)
1304
control_files.unlock()
1305
return self.open(a_bzrdir, _found=True)
1307
def _get_control_store(self, repo_transport, control_files):
1308
"""Return the control store for this repository."""
1309
return self._get_versioned_file_store('',
1314
def _get_text_store(self, transport, control_files):
1315
"""Get a store for file texts for this format."""
1316
raise NotImplementedError(self._get_text_store)
1318
def open(self, a_bzrdir, _found=False):
1319
"""See RepositoryFormat.open()."""
1321
# we are being called directly and must probe.
1322
raise NotImplementedError
1324
repo_transport = a_bzrdir.get_repository_transport(None)
1325
control_files = a_bzrdir._control_files
1326
text_store = self._get_text_store(repo_transport, control_files)
1327
control_store = self._get_control_store(repo_transport, control_files)
1328
_revision_store = self._get_revision_store(repo_transport, control_files)
1329
return AllInOneRepository(_format=self,
1331
_revision_store=_revision_store,
1332
control_store=control_store,
1333
text_store=text_store)
1335
def check_conversion_target(self, target_format):
1339
class RepositoryFormat4(PreSplitOutRepositoryFormat):
1340
"""Bzr repository format 4.
1342
This repository format has:
1344
- TextStores for texts, inventories,revisions.
1346
This format is deprecated: it indexes texts using a text id which is
1347
removed in format 5; initialization and write support for this format
1352
super(RepositoryFormat4, self).__init__()
1353
self._matchingbzrdir = bzrdir.BzrDirFormat4()
1355
def get_format_description(self):
1356
"""See RepositoryFormat.get_format_description()."""
1357
return "Repository format 4"
1359
def initialize(self, url, shared=False, _internal=False):
1360
"""Format 4 branches cannot be created."""
1361
raise errors.UninitializableFormat(self)
1363
def is_supported(self):
1364
"""Format 4 is not supported.
1366
It is not supported because the model changed from 4 to 5 and the
1367
conversion logic is expensive - so doing it on the fly was not
1372
def _get_control_store(self, repo_transport, control_files):
1373
"""Format 4 repositories have no formal control store at this point.
1375
This will cause any control-file-needing apis to fail - this is desired.
1379
def _get_revision_store(self, repo_transport, control_files):
1380
"""See RepositoryFormat._get_revision_store()."""
1381
from bzrlib.xml4 import serializer_v4
1382
return self._get_text_rev_store(repo_transport,
1385
serializer=serializer_v4)
1387
def _get_text_store(self, transport, control_files):
1388
"""See RepositoryFormat._get_text_store()."""
1391
class RepositoryFormat5(PreSplitOutRepositoryFormat):
1392
"""Bzr control format 5.
1394
This repository format has:
1395
- weaves for file texts and inventory
1397
- TextStores for revisions and signatures.
1401
super(RepositoryFormat5, self).__init__()
1402
self._matchingbzrdir = bzrdir.BzrDirFormat5()
1404
def get_format_description(self):
1405
"""See RepositoryFormat.get_format_description()."""
1406
return "Weave repository format 5"
1408
def _get_revision_store(self, repo_transport, control_files):
1409
"""See RepositoryFormat._get_revision_store()."""
1410
"""Return the revision store object for this a_bzrdir."""
1411
return self._get_text_rev_store(repo_transport,
1416
def _get_text_store(self, transport, control_files):
1417
"""See RepositoryFormat._get_text_store()."""
1418
return self._get_versioned_file_store('weaves', transport, control_files, prefixed=False)
1421
class RepositoryFormat6(PreSplitOutRepositoryFormat):
1422
"""Bzr control format 6.
1424
This repository format has:
1425
- weaves for file texts and inventory
1426
- hash subdirectory based stores.
1427
- TextStores for revisions and signatures.
1431
super(RepositoryFormat6, self).__init__()
1432
self._matchingbzrdir = bzrdir.BzrDirFormat6()
1434
def get_format_description(self):
1435
"""See RepositoryFormat.get_format_description()."""
1436
return "Weave repository format 6"
1438
def _get_revision_store(self, repo_transport, control_files):
1439
"""See RepositoryFormat._get_revision_store()."""
1440
return self._get_text_rev_store(repo_transport,
1446
def _get_text_store(self, transport, control_files):
1447
"""See RepositoryFormat._get_text_store()."""
1448
return self._get_versioned_file_store('weaves', transport, control_files)
1451
1241
class MetaDirRepositoryFormat(RepositoryFormat):
1452
1242
"""Common base class for the new repositories using the metadir layout."""
1454
1244
rich_root_data = False
1245
supports_tree_reference = False
1246
_matchingbzrdir = bzrdir.BzrDirMetaFormat1()
1456
1248
def __init__(self):
1457
1249
super(MetaDirRepositoryFormat, self).__init__()
1458
self._matchingbzrdir = bzrdir.BzrDirMetaFormat1()
1460
1251
def _create_control_files(self, a_bzrdir):
1461
1252
"""Create the required files and the initial control_files object."""
1484
1275
control_files.unlock()
1487
class RepositoryFormat7(MetaDirRepositoryFormat):
1488
"""Bzr repository 7.
1490
This repository format has:
1491
- weaves for file texts and inventory
1492
- hash subdirectory based stores.
1493
- TextStores for revisions and signatures.
1494
- a format marker of its own
1495
- an optional 'shared-storage' flag
1496
- an optional 'no-working-trees' flag
1499
def _get_control_store(self, repo_transport, control_files):
1500
"""Return the control store for this repository."""
1501
return self._get_versioned_file_store('',
1506
def get_format_string(self):
1507
"""See RepositoryFormat.get_format_string()."""
1508
return "Bazaar-NG Repository format 7"
1510
def get_format_description(self):
1511
"""See RepositoryFormat.get_format_description()."""
1512
return "Weave repository format 7"
1514
def check_conversion_target(self, target_format):
1517
def _get_revision_store(self, repo_transport, control_files):
1518
"""See RepositoryFormat._get_revision_store()."""
1519
return self._get_text_rev_store(repo_transport,
1526
def _get_text_store(self, transport, control_files):
1527
"""See RepositoryFormat._get_text_store()."""
1528
return self._get_versioned_file_store('weaves',
1532
def initialize(self, a_bzrdir, shared=False):
1533
"""Create a weave repository.
1535
:param shared: If true the repository will be initialized as a shared
1538
# Create an empty weave
1540
weavefile.write_weave_v5(weave.Weave(), sio)
1541
empty_weave = sio.getvalue()
1543
mutter('creating repository in %s.', a_bzrdir.transport.base)
1544
dirs = ['revision-store', 'weaves']
1545
files = [('inventory.weave', StringIO(empty_weave)),
1547
utf8_files = [('format', self.get_format_string())]
1549
self._upload_blank_content(a_bzrdir, dirs, files, utf8_files, shared)
1550
return self.open(a_bzrdir=a_bzrdir, _found=True)
1552
def open(self, a_bzrdir, _found=False, _override_transport=None):
1553
"""See RepositoryFormat.open().
1555
:param _override_transport: INTERNAL USE ONLY. Allows opening the
1556
repository at a slightly different url
1557
than normal. I.e. during 'upgrade'.
1560
format = RepositoryFormat.find_format(a_bzrdir)
1561
assert format.__class__ == self.__class__
1562
if _override_transport is not None:
1563
repo_transport = _override_transport
1565
repo_transport = a_bzrdir.get_repository_transport(None)
1566
control_files = lockable_files.LockableFiles(repo_transport,
1567
'lock', lockdir.LockDir)
1568
text_store = self._get_text_store(repo_transport, control_files)
1569
control_store = self._get_control_store(repo_transport, control_files)
1570
_revision_store = self._get_revision_store(repo_transport, control_files)
1571
return WeaveMetaDirRepository(_format=self,
1573
control_files=control_files,
1574
_revision_store=_revision_store,
1575
control_store=control_store,
1576
text_store=text_store)
1579
class RepositoryFormatKnit(MetaDirRepositoryFormat):
1580
"""Bzr repository knit format (generalized).
1582
This repository format has:
1583
- knits for file texts and inventory
1584
- hash subdirectory based stores.
1585
- knits for revisions and signatures
1586
- TextStores for revisions and signatures.
1587
- a format marker of its own
1588
- an optional 'shared-storage' flag
1589
- an optional 'no-working-trees' flag
1593
def _get_control_store(self, repo_transport, control_files):
1594
"""Return the control store for this repository."""
1595
return VersionedFileStore(
1598
file_mode=control_files._file_mode,
1599
versionedfile_class=knit.KnitVersionedFile,
1600
versionedfile_kwargs={'factory':knit.KnitPlainFactory()},
1603
def _get_revision_store(self, repo_transport, control_files):
1604
"""See RepositoryFormat._get_revision_store()."""
1605
from bzrlib.store.revision.knit import KnitRevisionStore
1606
versioned_file_store = VersionedFileStore(
1608
file_mode=control_files._file_mode,
1611
versionedfile_class=knit.KnitVersionedFile,
1612
versionedfile_kwargs={'delta':False,
1613
'factory':knit.KnitPlainFactory(),
1617
return KnitRevisionStore(versioned_file_store)
1619
def _get_text_store(self, transport, control_files):
1620
"""See RepositoryFormat._get_text_store()."""
1621
return self._get_versioned_file_store('knits',
1624
versionedfile_class=knit.KnitVersionedFile,
1625
versionedfile_kwargs={
1626
'create_parent_dir':True,
1627
'delay_create':True,
1628
'dir_mode':control_files._dir_mode,
1632
def initialize(self, a_bzrdir, shared=False):
1633
"""Create a knit format 1 repository.
1635
:param a_bzrdir: bzrdir to contain the new repository; must already
1637
:param shared: If true the repository will be initialized as a shared
1640
mutter('creating repository in %s.', a_bzrdir.transport.base)
1641
dirs = ['revision-store', 'knits']
1643
utf8_files = [('format', self.get_format_string())]
1645
self._upload_blank_content(a_bzrdir, dirs, files, utf8_files, shared)
1646
repo_transport = a_bzrdir.get_repository_transport(None)
1647
control_files = lockable_files.LockableFiles(repo_transport,
1648
'lock', lockdir.LockDir)
1649
control_store = self._get_control_store(repo_transport, control_files)
1650
transaction = transactions.WriteTransaction()
1651
# trigger a write of the inventory store.
1652
control_store.get_weave_or_empty('inventory', transaction)
1653
_revision_store = self._get_revision_store(repo_transport, control_files)
1654
# the revision id here is irrelevant: it will not be stored, and cannot
1656
_revision_store.has_revision_id('A', transaction)
1657
_revision_store.get_signature_file(transaction)
1658
return self.open(a_bzrdir=a_bzrdir, _found=True)
1660
def open(self, a_bzrdir, _found=False, _override_transport=None):
1661
"""See RepositoryFormat.open().
1663
:param _override_transport: INTERNAL USE ONLY. Allows opening the
1664
repository at a slightly different url
1665
than normal. I.e. during 'upgrade'.
1668
format = RepositoryFormat.find_format(a_bzrdir)
1669
assert format.__class__ == self.__class__
1670
if _override_transport is not None:
1671
repo_transport = _override_transport
1673
repo_transport = a_bzrdir.get_repository_transport(None)
1674
control_files = lockable_files.LockableFiles(repo_transport,
1675
'lock', lockdir.LockDir)
1676
text_store = self._get_text_store(repo_transport, control_files)
1677
control_store = self._get_control_store(repo_transport, control_files)
1678
_revision_store = self._get_revision_store(repo_transport, control_files)
1679
return KnitRepository(_format=self,
1681
control_files=control_files,
1682
_revision_store=_revision_store,
1683
control_store=control_store,
1684
text_store=text_store)
1687
class RepositoryFormatKnit1(RepositoryFormatKnit):
1688
"""Bzr repository knit format 1.
1690
This repository format has:
1691
- knits for file texts and inventory
1692
- hash subdirectory based stores.
1693
- knits for revisions and signatures
1694
- TextStores for revisions and signatures.
1695
- a format marker of its own
1696
- an optional 'shared-storage' flag
1697
- an optional 'no-working-trees' flag
1700
This format was introduced in bzr 0.8.
1702
def get_format_string(self):
1703
"""See RepositoryFormat.get_format_string()."""
1704
return "Bazaar-NG Knit Repository Format 1"
1706
def get_format_description(self):
1707
"""See RepositoryFormat.get_format_description()."""
1708
return "Knit repository format 1"
1710
def check_conversion_target(self, target_format):
1714
class RepositoryFormatKnit2(RepositoryFormatKnit):
1715
"""Bzr repository knit format 2.
1717
THIS FORMAT IS EXPERIMENTAL
1718
This repository format has:
1719
- knits for file texts and inventory
1720
- hash subdirectory based stores.
1721
- knits for revisions and signatures
1722
- TextStores for revisions and signatures.
1723
- a format marker of its own
1724
- an optional 'shared-storage' flag
1725
- an optional 'no-working-trees' flag
1727
- Support for recording full info about the tree root
1731
rich_root_data = True
1733
def get_format_string(self):
1734
"""See RepositoryFormat.get_format_string()."""
1735
return "Bazaar Knit Repository Format 2\n"
1737
def get_format_description(self):
1738
"""See RepositoryFormat.get_format_description()."""
1739
return "Knit repository format 2"
1741
def check_conversion_target(self, target_format):
1742
if not target_format.rich_root_data:
1743
raise errors.BadConversionTarget(
1744
'Does not support rich root data.', target_format)
1746
def open(self, a_bzrdir, _found=False, _override_transport=None):
1747
"""See RepositoryFormat.open().
1749
:param _override_transport: INTERNAL USE ONLY. Allows opening the
1750
repository at a slightly different url
1751
than normal. I.e. during 'upgrade'.
1754
format = RepositoryFormat.find_format(a_bzrdir)
1755
assert format.__class__ == self.__class__
1756
if _override_transport is not None:
1757
repo_transport = _override_transport
1759
repo_transport = a_bzrdir.get_repository_transport(None)
1760
control_files = lockable_files.LockableFiles(repo_transport, 'lock',
1762
text_store = self._get_text_store(repo_transport, control_files)
1763
control_store = self._get_control_store(repo_transport, control_files)
1764
_revision_store = self._get_revision_store(repo_transport, control_files)
1765
return KnitRepository2(_format=self,
1767
control_files=control_files,
1768
_revision_store=_revision_store,
1769
control_store=control_store,
1770
text_store=text_store)
1774
1278
# formats which have no format string are not discoverable
1775
# and not independently creatable, so are not registered.
1776
RepositoryFormat.register_format(RepositoryFormat7())
1777
_default_format = RepositoryFormatKnit1()
1778
RepositoryFormat.register_format(_default_format)
1779
RepositoryFormat.register_format(RepositoryFormatKnit2())
1780
RepositoryFormat.set_default_format(_default_format)
1781
_legacy_formats = [RepositoryFormat4(),
1782
RepositoryFormat5(),
1783
RepositoryFormat6()]
1279
# and not independently creatable, so are not registered. They're
1280
# all in bzrlib.repofmt.weaverepo now. When an instance of one of these is
1281
# needed, it's constructed directly by the BzrDir. Non-native formats where
1282
# the repository is not separately opened are similar.
1284
format_registry.register_lazy(
1285
'Bazaar-NG Repository format 7',
1286
'bzrlib.repofmt.weaverepo',
1289
# KEEP in sync with bzrdir.format_registry default, which controls the overall
1290
# default control directory format
1292
format_registry.register_lazy(
1293
'Bazaar-NG Knit Repository Format 1',
1294
'bzrlib.repofmt.knitrepo',
1295
'RepositoryFormatKnit1',
1297
format_registry.default_key = 'Bazaar-NG Knit Repository Format 1'
1299
format_registry.register_lazy(
1300
'Bazaar Knit Repository Format 3 (bzr 0.15)\n',
1301
'bzrlib.repofmt.knitrepo',
1302
'RepositoryFormatKnit3',
1786
1306
class InterRepository(InterObject):
1925
1455
@needs_write_lock
1926
def copy_content(self, revision_id=None, basis=None):
1456
def copy_content(self, revision_id=None):
1927
1457
"""See InterRepository.copy_content()."""
1928
1458
# weave specific optimised path:
1929
if basis is not None:
1930
# copy the basis in, then fetch remaining data.
1931
basis.copy_content_into(self.target, revision_id)
1932
# the basis copy_content_into could miss-set this.
1459
# TODO: jam 20070210 Internal, should be an assert, not translate
1460
revision_id = osutils.safe_revision_id(revision_id)
1462
self.target.set_make_working_trees(self.source.make_working_trees())
1463
except NotImplementedError:
1465
# FIXME do not peek!
1466
if self.source.control_files._transport.listable():
1467
pb = ui.ui_factory.nested_progress_bar()
1934
self.target.set_make_working_trees(self.source.make_working_trees())
1935
except NotImplementedError:
1469
self.target.weave_store.copy_all_ids(
1470
self.source.weave_store,
1472
from_transaction=self.source.get_transaction(),
1473
to_transaction=self.target.get_transaction())
1474
pb.update('copying inventory', 0, 1)
1475
self.target.control_weaves.copy_multi(
1476
self.source.control_weaves, ['inventory'],
1477
from_transaction=self.source.get_transaction(),
1478
to_transaction=self.target.get_transaction())
1479
self.target._revision_store.text_store.copy_all_ids(
1480
self.source._revision_store.text_store,
1937
1485
self.target.fetch(self.source, revision_id=revision_id)
1940
self.target.set_make_working_trees(self.source.make_working_trees())
1941
except NotImplementedError:
1943
# FIXME do not peek!
1944
if self.source.control_files._transport.listable():
1945
pb = ui.ui_factory.nested_progress_bar()
1947
self.target.weave_store.copy_all_ids(
1948
self.source.weave_store,
1950
from_transaction=self.source.get_transaction(),
1951
to_transaction=self.target.get_transaction())
1952
pb.update('copying inventory', 0, 1)
1953
self.target.control_weaves.copy_multi(
1954
self.source.control_weaves, ['inventory'],
1955
from_transaction=self.source.get_transaction(),
1956
to_transaction=self.target.get_transaction())
1957
self.target._revision_store.text_store.copy_all_ids(
1958
self.source._revision_store.text_store,
1963
self.target.fetch(self.source, revision_id=revision_id)
1965
1487
@needs_write_lock
1966
1488
def fetch(self, revision_id=None, pb=None):