79
_file_ids_altered_regex = lazy_regex.lazy_compile(
80
r'file_id="(?P<file_id>[^"]+)"'
81
r'.*revision="(?P<revision_id>[^"]+)"'
85
def add_inventory(self, revid, inv, parents):
86
"""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.
88
:param parents: The revision ids of the parents that revid
88
:param parents: The revision ids of the parents that revision_id
89
89
is known to have and are in the repository already.
91
91
returns the sha1 of the serialized inventory.
93
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, \
94
96
"Mismatch between inventory revision" \
95
" id and insertion revid (%r, %r)" % (inv.revision_id, revid)
97
" id and insertion revid (%r, %r)" % (inv.revision_id, revision_id)
96
98
assert inv.root is not None
97
99
inv_text = self.serialise_inventory(inv)
98
100
inv_sha1 = osutils.sha_string(inv_text)
99
101
inv_vf = self.control_weaves.get_weave('inventory',
100
102
self.get_transaction())
101
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))
104
def _inventory_add_lines(self, inv_vf, revid, parents, lines):
107
def _inventory_add_lines(self, inv_vf, revision_id, parents, lines):
105
108
final_parents = []
106
109
for parent in parents:
107
110
if parent in inv_vf:
108
111
final_parents.append(parent)
110
inv_vf.add_lines(revid, final_parents, lines)
113
inv_vf.add_lines(revision_id, final_parents, lines)
112
115
@needs_write_lock
113
def add_revision(self, rev_id, rev, inv=None, config=None):
114
"""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.
116
:param rev_id: the revision id to use.
119
:param revision_id: the revision id to use.
117
120
:param rev: The revision object.
118
121
:param inv: The inventory for the revision. if None, it will be looked
119
122
up in the inventory storer
232
257
def get_physical_lock_status(self):
233
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
236
327
def missing_revision_ids(self, other, revision_id=None):
237
328
"""Return the revision ids that other has that this does not.
728
929
def supports_rich_root(self):
729
930
return self._format.rich_root_data
732
class AllInOneRepository(Repository):
733
"""Legacy support - the repository behaviour for all-in-one branches."""
735
def __init__(self, _format, a_bzrdir, _revision_store, control_store, text_store):
736
# we reuse one control files instance.
737
dir_mode = a_bzrdir._control_files._dir_mode
738
file_mode = a_bzrdir._control_files._file_mode
740
def get_store(name, compressed=True, prefixed=False):
741
# FIXME: This approach of assuming stores are all entirely compressed
742
# or entirely uncompressed is tidy, but breaks upgrade from
743
# some existing branches where there's a mixture; we probably
744
# still want the option to look for both.
745
relpath = a_bzrdir._control_files._escape(name)
746
store = TextStore(a_bzrdir._control_files._transport.clone(relpath),
747
prefixed=prefixed, compressed=compressed,
750
#if self._transport.should_cache():
751
# cache_path = os.path.join(self.cache_root, name)
752
# os.mkdir(cache_path)
753
# store = bzrlib.store.CachedStore(store, cache_path)
756
# not broken out yet because the controlweaves|inventory_store
757
# and text_store | weave_store bits are still different.
758
if isinstance(_format, RepositoryFormat4):
759
# cannot remove these - there is still no consistent api
760
# which allows access to this old info.
761
self.inventory_store = get_store('inventory-store')
762
text_store = get_store('text-store')
763
super(AllInOneRepository, self).__init__(_format, a_bzrdir, a_bzrdir._control_files, _revision_store, control_store, text_store)
767
"""AllInOne repositories cannot be shared."""
771
def set_make_working_trees(self, new_value):
772
"""Set the policy flag for making working trees when creating branches.
774
This only applies to branches that use this repository.
776
The default is 'True'.
777
:param new_value: True to restore the default, False to disable making
780
raise NotImplementedError(self.set_make_working_trees)
782
def make_working_trees(self):
783
"""Returns the policy for making working trees on new branches."""
932
def _check_ascii_revisionid(self, revision_id, method):
933
"""Private helper for ascii-only repositories."""
934
# weave repositories refuse to store revisionids that are non-ascii.
935
if revision_id is not None:
936
# weaves require ascii revision ids.
937
if isinstance(revision_id, unicode):
939
revision_id.encode('ascii')
940
except UnicodeEncodeError:
941
raise errors.NonAsciiRevisionId(method, self)
944
revision_id.decode('ascii')
945
except UnicodeDecodeError:
946
raise errors.NonAsciiRevisionId(method, self)
950
# remove these delegates a while after bzr 0.15
951
def __make_delegated(name, from_module):
952
def _deprecated_repository_forwarder():
953
symbol_versioning.warn('%s moved to %s in bzr 0.15'
954
% (name, from_module),
957
m = __import__(from_module, globals(), locals(), [name])
959
return getattr(m, name)
960
except AttributeError:
961
raise AttributeError('module %s has no name %s'
963
globals()[name] = _deprecated_repository_forwarder
966
'AllInOneRepository',
967
'WeaveMetaDirRepository',
968
'PreSplitOutRepositoryFormat',
974
__make_delegated(_name, 'bzrlib.repofmt.weaverepo')
978
'RepositoryFormatKnit',
979
'RepositoryFormatKnit1',
981
__make_delegated(_name, 'bzrlib.repofmt.knitrepo')
787
984
def install_revision(repository, rev, revision_tree):
873
1070
return not self.control_files._transport.has('no-working-trees')
876
class KnitRepository(MetaDirRepository):
877
"""Knit format repository."""
879
def _warn_if_deprecated(self):
880
# This class isn't deprecated
883
def _inventory_add_lines(self, inv_vf, revid, parents, lines):
884
inv_vf.add_lines_with_ghosts(revid, parents, lines)
887
def _all_revision_ids(self):
888
"""See Repository.all_revision_ids()."""
889
# Knits get the revision graph from the index of the revision knit, so
890
# it's always possible even if they're on an unlistable transport.
891
return self._revision_store.all_revision_ids(self.get_transaction())
893
def fileid_involved_between_revs(self, from_revid, to_revid):
894
"""Find file_id(s) which are involved in the changes between revisions.
896
This determines the set of revisions which are involved, and then
897
finds all file ids affected by those revisions.
899
vf = self._get_revision_vf()
900
from_set = set(vf.get_ancestry(from_revid))
901
to_set = set(vf.get_ancestry(to_revid))
902
changed = to_set.difference(from_set)
903
return self._fileid_involved_by_set(changed)
905
def fileid_involved(self, last_revid=None):
906
"""Find all file_ids modified in the ancestry of last_revid.
908
:param last_revid: If None, last_revision() will be used.
911
changed = set(self.all_revision_ids())
913
changed = set(self.get_ancestry(last_revid))
916
return self._fileid_involved_by_set(changed)
919
def get_ancestry(self, revision_id):
920
"""Return a list of revision-ids integrated by a revision.
922
This is topologically sorted.
924
if revision_id is None:
926
vf = self._get_revision_vf()
928
return [None] + vf.get_ancestry(revision_id)
929
except errors.RevisionNotPresent:
930
raise errors.NoSuchRevision(self, revision_id)
933
def get_revision(self, revision_id):
934
"""Return the Revision object for a named revision"""
935
return self.get_revision_reconcile(revision_id)
938
def get_revision_graph(self, revision_id=None):
939
"""Return a dictionary containing the revision graph.
941
:param revision_id: The revision_id to get a graph from. If None, then
942
the entire revision graph is returned. This is a deprecated mode of
943
operation and will be removed in the future.
944
:return: a dictionary of revision_id->revision_parents_list.
946
# special case NULL_REVISION
947
if revision_id == _mod_revision.NULL_REVISION:
949
a_weave = self._get_revision_vf()
950
entire_graph = a_weave.get_graph()
951
if revision_id is None:
952
return a_weave.get_graph()
953
elif revision_id not in a_weave:
954
raise errors.NoSuchRevision(self, revision_id)
956
# add what can be reached from revision_id
958
pending = set([revision_id])
959
while len(pending) > 0:
961
result[node] = a_weave.get_parents(node)
962
for revision_id in result[node]:
963
if revision_id not in result:
964
pending.add(revision_id)
968
def get_revision_graph_with_ghosts(self, revision_ids=None):
969
"""Return a graph of the revisions with ghosts marked as applicable.
971
:param revision_ids: an iterable of revisions to graph or None for all.
972
:return: a Graph object with the graph reachable from revision_ids.
974
result = graph.Graph()
975
vf = self._get_revision_vf()
976
versions = set(vf.versions())
978
pending = set(self.all_revision_ids())
981
pending = set(revision_ids)
982
# special case NULL_REVISION
983
if _mod_revision.NULL_REVISION in pending:
984
pending.remove(_mod_revision.NULL_REVISION)
985
required = set(pending)
988
revision_id = pending.pop()
989
if not revision_id in versions:
990
if revision_id in required:
991
raise errors.NoSuchRevision(self, revision_id)
993
result.add_ghost(revision_id)
994
# mark it as done so we don't try for it again.
995
done.add(revision_id)
997
parent_ids = vf.get_parents_with_ghosts(revision_id)
998
for parent_id in parent_ids:
999
# is this queued or done ?
1000
if (parent_id not in pending and
1001
parent_id not in done):
1003
pending.add(parent_id)
1004
result.add_node(revision_id, parent_ids)
1005
done.add(revision_id)
1008
def _get_revision_vf(self):
1009
""":return: a versioned file containing the revisions."""
1010
vf = self._revision_store.get_revision_file(self.get_transaction())
1014
def reconcile(self, other=None, thorough=False):
1015
"""Reconcile this repository."""
1016
from bzrlib.reconcile import KnitReconciler
1017
reconciler = KnitReconciler(self, thorough=thorough)
1018
reconciler.reconcile()
1073
class RepositoryFormatRegistry(registry.Registry):
1074
"""Registry of RepositoryFormats.
1077
def get(self, format_string):
1078
r = registry.Registry.get(self, format_string)
1021
def revision_parents(self, revision_id):
1022
return self._get_revision_vf().get_parents(revision_id)
1025
class KnitRepository2(KnitRepository):
1027
def __init__(self, _format, a_bzrdir, control_files, _revision_store,
1028
control_store, text_store):
1029
KnitRepository.__init__(self, _format, a_bzrdir, control_files,
1030
_revision_store, control_store, text_store)
1031
self._serializer = xml6.serializer_v6
1033
def deserialise_inventory(self, revision_id, xml):
1034
"""Transform the xml into an inventory object.
1036
:param revision_id: The expected revision id of the inventory.
1037
:param xml: A serialised inventory.
1039
result = self._serializer.read_inventory_from_string(xml)
1040
assert result.root.revision is not None
1043
def serialise_inventory(self, inv):
1044
"""Transform the inventory object into XML text.
1046
:param revision_id: The expected revision id of the inventory.
1047
:param xml: A serialised inventory.
1049
assert inv.revision_id is not None
1050
assert inv.root.revision is not None
1051
return KnitRepository.serialise_inventory(self, inv)
1053
def get_commit_builder(self, branch, parents, config, timestamp=None,
1054
timezone=None, committer=None, revprops=None,
1056
"""Obtain a CommitBuilder for this repository.
1058
:param branch: Branch to commit to.
1059
:param parents: Revision ids of the parents of the new revision.
1060
:param config: Configuration to use.
1061
:param timestamp: Optional timestamp recorded for commit.
1062
:param timezone: Optional timezone for timestamp.
1063
:param committer: Optional committer to set for commit.
1064
:param revprops: Optional dictionary of revision properties.
1065
:param revision_id: Optional revision id.
1067
return RootCommitBuilder(self, parents, config, timestamp, timezone,
1068
committer, revprops, revision_id)
1084
format_registry = RepositoryFormatRegistry()
1085
"""Registry of formats, indexed by their identifying format string.
1087
This can contain either format instances themselves, or classes/factories that
1088
can be called to obtain one.
1092
#####################################################################
1093
# Repository Formats
1071
1095
class RepositoryFormat(object):
1072
1096
"""A repository format.
1209
1254
raise NotImplementedError(self.open)
1212
def register_format(klass, format):
1213
klass._formats[format.get_format_string()] = format
1216
def set_default_format(klass, format):
1217
klass._default_format = format
1220
def unregister_format(klass, format):
1221
assert klass._formats[format.get_format_string()] is format
1222
del klass._formats[format.get_format_string()]
1225
class PreSplitOutRepositoryFormat(RepositoryFormat):
1226
"""Base class for the pre split out repository formats."""
1228
rich_root_data = False
1230
def initialize(self, a_bzrdir, shared=False, _internal=False):
1231
"""Create a weave repository.
1233
TODO: when creating split out bzr branch formats, move this to a common
1234
base for Format5, Format6. or something like that.
1237
raise errors.IncompatibleFormat(self, a_bzrdir._format)
1240
# always initialized when the bzrdir is.
1241
return self.open(a_bzrdir, _found=True)
1243
# Create an empty weave
1245
weavefile.write_weave_v5(weave.Weave(), sio)
1246
empty_weave = sio.getvalue()
1248
mutter('creating repository in %s.', a_bzrdir.transport.base)
1249
dirs = ['revision-store', 'weaves']
1250
files = [('inventory.weave', StringIO(empty_weave)),
1253
# FIXME: RBC 20060125 don't peek under the covers
1254
# NB: no need to escape relative paths that are url safe.
1255
control_files = lockable_files.LockableFiles(a_bzrdir.transport,
1256
'branch-lock', lockable_files.TransportLock)
1257
control_files.create_lock()
1258
control_files.lock_write()
1259
control_files._transport.mkdir_multi(dirs,
1260
mode=control_files._dir_mode)
1262
for file, content in files:
1263
control_files.put(file, content)
1265
control_files.unlock()
1266
return self.open(a_bzrdir, _found=True)
1268
def _get_control_store(self, repo_transport, control_files):
1269
"""Return the control store for this repository."""
1270
return self._get_versioned_file_store('',
1275
def _get_text_store(self, transport, control_files):
1276
"""Get a store for file texts for this format."""
1277
raise NotImplementedError(self._get_text_store)
1279
def open(self, a_bzrdir, _found=False):
1280
"""See RepositoryFormat.open()."""
1282
# we are being called directly and must probe.
1283
raise NotImplementedError
1285
repo_transport = a_bzrdir.get_repository_transport(None)
1286
control_files = a_bzrdir._control_files
1287
text_store = self._get_text_store(repo_transport, control_files)
1288
control_store = self._get_control_store(repo_transport, control_files)
1289
_revision_store = self._get_revision_store(repo_transport, control_files)
1290
return AllInOneRepository(_format=self,
1292
_revision_store=_revision_store,
1293
control_store=control_store,
1294
text_store=text_store)
1296
def check_conversion_target(self, target_format):
1300
class RepositoryFormat4(PreSplitOutRepositoryFormat):
1301
"""Bzr repository format 4.
1303
This repository format has:
1305
- TextStores for texts, inventories,revisions.
1307
This format is deprecated: it indexes texts using a text id which is
1308
removed in format 5; initialization and write support for this format
1313
super(RepositoryFormat4, self).__init__()
1314
self._matchingbzrdir = bzrdir.BzrDirFormat4()
1316
def get_format_description(self):
1317
"""See RepositoryFormat.get_format_description()."""
1318
return "Repository format 4"
1320
def initialize(self, url, shared=False, _internal=False):
1321
"""Format 4 branches cannot be created."""
1322
raise errors.UninitializableFormat(self)
1324
def is_supported(self):
1325
"""Format 4 is not supported.
1327
It is not supported because the model changed from 4 to 5 and the
1328
conversion logic is expensive - so doing it on the fly was not
1333
def _get_control_store(self, repo_transport, control_files):
1334
"""Format 4 repositories have no formal control store at this point.
1336
This will cause any control-file-needing apis to fail - this is desired.
1340
def _get_revision_store(self, repo_transport, control_files):
1341
"""See RepositoryFormat._get_revision_store()."""
1342
from bzrlib.xml4 import serializer_v4
1343
return self._get_text_rev_store(repo_transport,
1346
serializer=serializer_v4)
1348
def _get_text_store(self, transport, control_files):
1349
"""See RepositoryFormat._get_text_store()."""
1352
class RepositoryFormat5(PreSplitOutRepositoryFormat):
1353
"""Bzr control format 5.
1355
This repository format has:
1356
- weaves for file texts and inventory
1358
- TextStores for revisions and signatures.
1362
super(RepositoryFormat5, self).__init__()
1363
self._matchingbzrdir = bzrdir.BzrDirFormat5()
1365
def get_format_description(self):
1366
"""See RepositoryFormat.get_format_description()."""
1367
return "Weave repository format 5"
1369
def _get_revision_store(self, repo_transport, control_files):
1370
"""See RepositoryFormat._get_revision_store()."""
1371
"""Return the revision store object for this a_bzrdir."""
1372
return self._get_text_rev_store(repo_transport,
1377
def _get_text_store(self, transport, control_files):
1378
"""See RepositoryFormat._get_text_store()."""
1379
return self._get_versioned_file_store('weaves', transport, control_files, prefixed=False)
1382
class RepositoryFormat6(PreSplitOutRepositoryFormat):
1383
"""Bzr control format 6.
1385
This repository format has:
1386
- weaves for file texts and inventory
1387
- hash subdirectory based stores.
1388
- TextStores for revisions and signatures.
1392
super(RepositoryFormat6, self).__init__()
1393
self._matchingbzrdir = bzrdir.BzrDirFormat6()
1395
def get_format_description(self):
1396
"""See RepositoryFormat.get_format_description()."""
1397
return "Weave repository format 6"
1399
def _get_revision_store(self, repo_transport, control_files):
1400
"""See RepositoryFormat._get_revision_store()."""
1401
return self._get_text_rev_store(repo_transport,
1407
def _get_text_store(self, transport, control_files):
1408
"""See RepositoryFormat._get_text_store()."""
1409
return self._get_versioned_file_store('weaves', transport, control_files)
1412
1257
class MetaDirRepositoryFormat(RepositoryFormat):
1413
1258
"""Common base class for the new repositories using the metadir layout."""
1415
1260
rich_root_data = False
1261
supports_tree_reference = False
1262
_matchingbzrdir = bzrdir.BzrDirMetaFormat1()
1417
1264
def __init__(self):
1418
1265
super(MetaDirRepositoryFormat, self).__init__()
1419
self._matchingbzrdir = bzrdir.BzrDirMetaFormat1()
1421
1267
def _create_control_files(self, a_bzrdir):
1422
1268
"""Create the required files and the initial control_files object."""
1445
1291
control_files.unlock()
1448
class RepositoryFormat7(MetaDirRepositoryFormat):
1449
"""Bzr repository 7.
1451
This repository format has:
1452
- weaves for file texts and inventory
1453
- hash subdirectory based stores.
1454
- TextStores for revisions and signatures.
1455
- a format marker of its own
1456
- an optional 'shared-storage' flag
1457
- an optional 'no-working-trees' flag
1460
def _get_control_store(self, repo_transport, control_files):
1461
"""Return the control store for this repository."""
1462
return self._get_versioned_file_store('',
1467
def get_format_string(self):
1468
"""See RepositoryFormat.get_format_string()."""
1469
return "Bazaar-NG Repository format 7"
1471
def get_format_description(self):
1472
"""See RepositoryFormat.get_format_description()."""
1473
return "Weave repository format 7"
1475
def check_conversion_target(self, target_format):
1478
def _get_revision_store(self, repo_transport, control_files):
1479
"""See RepositoryFormat._get_revision_store()."""
1480
return self._get_text_rev_store(repo_transport,
1487
def _get_text_store(self, transport, control_files):
1488
"""See RepositoryFormat._get_text_store()."""
1489
return self._get_versioned_file_store('weaves',
1493
def initialize(self, a_bzrdir, shared=False):
1494
"""Create a weave repository.
1496
:param shared: If true the repository will be initialized as a shared
1499
# Create an empty weave
1501
weavefile.write_weave_v5(weave.Weave(), sio)
1502
empty_weave = sio.getvalue()
1504
mutter('creating repository in %s.', a_bzrdir.transport.base)
1505
dirs = ['revision-store', 'weaves']
1506
files = [('inventory.weave', StringIO(empty_weave)),
1508
utf8_files = [('format', self.get_format_string())]
1510
self._upload_blank_content(a_bzrdir, dirs, files, utf8_files, shared)
1511
return self.open(a_bzrdir=a_bzrdir, _found=True)
1513
def open(self, a_bzrdir, _found=False, _override_transport=None):
1514
"""See RepositoryFormat.open().
1516
:param _override_transport: INTERNAL USE ONLY. Allows opening the
1517
repository at a slightly different url
1518
than normal. I.e. during 'upgrade'.
1521
format = RepositoryFormat.find_format(a_bzrdir)
1522
assert format.__class__ == self.__class__
1523
if _override_transport is not None:
1524
repo_transport = _override_transport
1526
repo_transport = a_bzrdir.get_repository_transport(None)
1527
control_files = lockable_files.LockableFiles(repo_transport,
1528
'lock', lockdir.LockDir)
1529
text_store = self._get_text_store(repo_transport, control_files)
1530
control_store = self._get_control_store(repo_transport, control_files)
1531
_revision_store = self._get_revision_store(repo_transport, control_files)
1532
return MetaDirRepository(_format=self,
1534
control_files=control_files,
1535
_revision_store=_revision_store,
1536
control_store=control_store,
1537
text_store=text_store)
1540
class RepositoryFormatKnit(MetaDirRepositoryFormat):
1541
"""Bzr repository knit format (generalized).
1543
This repository format has:
1544
- knits for file texts and inventory
1545
- hash subdirectory based stores.
1546
- knits for revisions and signatures
1547
- TextStores for revisions and signatures.
1548
- a format marker of its own
1549
- an optional 'shared-storage' flag
1550
- an optional 'no-working-trees' flag
1554
def _get_control_store(self, repo_transport, control_files):
1555
"""Return the control store for this repository."""
1556
return VersionedFileStore(
1559
file_mode=control_files._file_mode,
1560
versionedfile_class=knit.KnitVersionedFile,
1561
versionedfile_kwargs={'factory':knit.KnitPlainFactory()},
1564
def _get_revision_store(self, repo_transport, control_files):
1565
"""See RepositoryFormat._get_revision_store()."""
1566
from bzrlib.store.revision.knit import KnitRevisionStore
1567
versioned_file_store = VersionedFileStore(
1569
file_mode=control_files._file_mode,
1572
versionedfile_class=knit.KnitVersionedFile,
1573
versionedfile_kwargs={'delta':False,
1574
'factory':knit.KnitPlainFactory(),
1578
return KnitRevisionStore(versioned_file_store)
1580
def _get_text_store(self, transport, control_files):
1581
"""See RepositoryFormat._get_text_store()."""
1582
return self._get_versioned_file_store('knits',
1585
versionedfile_class=knit.KnitVersionedFile,
1586
versionedfile_kwargs={
1587
'create_parent_dir':True,
1588
'delay_create':True,
1589
'dir_mode':control_files._dir_mode,
1593
def initialize(self, a_bzrdir, shared=False):
1594
"""Create a knit format 1 repository.
1596
:param a_bzrdir: bzrdir to contain the new repository; must already
1598
:param shared: If true the repository will be initialized as a shared
1601
mutter('creating repository in %s.', a_bzrdir.transport.base)
1602
dirs = ['revision-store', 'knits']
1604
utf8_files = [('format', self.get_format_string())]
1606
self._upload_blank_content(a_bzrdir, dirs, files, utf8_files, shared)
1607
repo_transport = a_bzrdir.get_repository_transport(None)
1608
control_files = lockable_files.LockableFiles(repo_transport,
1609
'lock', lockdir.LockDir)
1610
control_store = self._get_control_store(repo_transport, control_files)
1611
transaction = transactions.WriteTransaction()
1612
# trigger a write of the inventory store.
1613
control_store.get_weave_or_empty('inventory', transaction)
1614
_revision_store = self._get_revision_store(repo_transport, control_files)
1615
_revision_store.has_revision_id('A', transaction)
1616
_revision_store.get_signature_file(transaction)
1617
return self.open(a_bzrdir=a_bzrdir, _found=True)
1619
def open(self, a_bzrdir, _found=False, _override_transport=None):
1620
"""See RepositoryFormat.open().
1622
:param _override_transport: INTERNAL USE ONLY. Allows opening the
1623
repository at a slightly different url
1624
than normal. I.e. during 'upgrade'.
1627
format = RepositoryFormat.find_format(a_bzrdir)
1628
assert format.__class__ == self.__class__
1629
if _override_transport is not None:
1630
repo_transport = _override_transport
1632
repo_transport = a_bzrdir.get_repository_transport(None)
1633
control_files = lockable_files.LockableFiles(repo_transport,
1634
'lock', lockdir.LockDir)
1635
text_store = self._get_text_store(repo_transport, control_files)
1636
control_store = self._get_control_store(repo_transport, control_files)
1637
_revision_store = self._get_revision_store(repo_transport, control_files)
1638
return KnitRepository(_format=self,
1640
control_files=control_files,
1641
_revision_store=_revision_store,
1642
control_store=control_store,
1643
text_store=text_store)
1646
class RepositoryFormatKnit1(RepositoryFormatKnit):
1647
"""Bzr repository knit format 1.
1649
This repository format has:
1650
- knits for file texts and inventory
1651
- hash subdirectory based stores.
1652
- knits for revisions and signatures
1653
- TextStores for revisions and signatures.
1654
- a format marker of its own
1655
- an optional 'shared-storage' flag
1656
- an optional 'no-working-trees' flag
1659
This format was introduced in bzr 0.8.
1661
def get_format_string(self):
1662
"""See RepositoryFormat.get_format_string()."""
1663
return "Bazaar-NG Knit Repository Format 1"
1665
def get_format_description(self):
1666
"""See RepositoryFormat.get_format_description()."""
1667
return "Knit repository format 1"
1669
def check_conversion_target(self, target_format):
1673
class RepositoryFormatKnit2(RepositoryFormatKnit):
1674
"""Bzr repository knit format 2.
1676
THIS FORMAT IS EXPERIMENTAL
1677
This repository format has:
1678
- knits for file texts and inventory
1679
- hash subdirectory based stores.
1680
- knits for revisions and signatures
1681
- TextStores for revisions and signatures.
1682
- a format marker of its own
1683
- an optional 'shared-storage' flag
1684
- an optional 'no-working-trees' flag
1686
- Support for recording full info about the tree root
1690
rich_root_data = True
1692
def get_format_string(self):
1693
"""See RepositoryFormat.get_format_string()."""
1694
return "Bazaar Knit Repository Format 2\n"
1696
def get_format_description(self):
1697
"""See RepositoryFormat.get_format_description()."""
1698
return "Knit repository format 2"
1700
def check_conversion_target(self, target_format):
1701
if not target_format.rich_root_data:
1702
raise errors.BadConversionTarget(
1703
'Does not support rich root data.', target_format)
1705
def open(self, a_bzrdir, _found=False, _override_transport=None):
1706
"""See RepositoryFormat.open().
1708
:param _override_transport: INTERNAL USE ONLY. Allows opening the
1709
repository at a slightly different url
1710
than normal. I.e. during 'upgrade'.
1713
format = RepositoryFormat.find_format(a_bzrdir)
1714
assert format.__class__ == self.__class__
1715
if _override_transport is not None:
1716
repo_transport = _override_transport
1718
repo_transport = a_bzrdir.get_repository_transport(None)
1719
control_files = lockable_files.LockableFiles(repo_transport, 'lock',
1721
text_store = self._get_text_store(repo_transport, control_files)
1722
control_store = self._get_control_store(repo_transport, control_files)
1723
_revision_store = self._get_revision_store(repo_transport, control_files)
1724
return KnitRepository2(_format=self,
1726
control_files=control_files,
1727
_revision_store=_revision_store,
1728
control_store=control_store,
1729
text_store=text_store)
1733
1294
# formats which have no format string are not discoverable
1734
# and not independently creatable, so are not registered.
1735
RepositoryFormat.register_format(RepositoryFormat7())
1736
_default_format = RepositoryFormatKnit1()
1737
RepositoryFormat.register_format(_default_format)
1738
RepositoryFormat.register_format(RepositoryFormatKnit2())
1739
RepositoryFormat.set_default_format(_default_format)
1740
_legacy_formats = [RepositoryFormat4(),
1741
RepositoryFormat5(),
1742
RepositoryFormat6()]
1295
# and not independently creatable, so are not registered. They're
1296
# all in bzrlib.repofmt.weaverepo now. When an instance of one of these is
1297
# needed, it's constructed directly by the BzrDir. Non-native formats where
1298
# the repository is not separately opened are similar.
1300
format_registry.register_lazy(
1301
'Bazaar-NG Repository format 7',
1302
'bzrlib.repofmt.weaverepo',
1305
# KEEP in sync with bzrdir.format_registry default, which controls the overall
1306
# default control directory format
1308
format_registry.register_lazy(
1309
'Bazaar-NG Knit Repository Format 1',
1310
'bzrlib.repofmt.knitrepo',
1311
'RepositoryFormatKnit1',
1313
format_registry.default_key = 'Bazaar-NG Knit Repository Format 1'
1315
format_registry.register_lazy(
1316
'Bazaar Knit Repository Format 3 (bzr 0.15)\n',
1317
'bzrlib.repofmt.knitrepo',
1318
'RepositoryFormatKnit3',
1745
1322
class InterRepository(InterObject):
1884
1474
@needs_write_lock
1885
def copy_content(self, revision_id=None, basis=None):
1475
def copy_content(self, revision_id=None):
1886
1476
"""See InterRepository.copy_content()."""
1887
1477
# weave specific optimised path:
1888
if basis is not None:
1889
# copy the basis in, then fetch remaining data.
1890
basis.copy_content_into(self.target, revision_id)
1891
# the basis copy_content_into could miss-set this.
1478
# TODO: jam 20070210 Internal, should be an assert, not translate
1479
revision_id = osutils.safe_revision_id(revision_id)
1481
self.target.set_make_working_trees(self.source.make_working_trees())
1482
except NotImplementedError:
1484
# FIXME do not peek!
1485
if self.source.control_files._transport.listable():
1486
pb = ui.ui_factory.nested_progress_bar()
1893
self.target.set_make_working_trees(self.source.make_working_trees())
1894
except NotImplementedError:
1488
self.target.weave_store.copy_all_ids(
1489
self.source.weave_store,
1491
from_transaction=self.source.get_transaction(),
1492
to_transaction=self.target.get_transaction())
1493
pb.update('copying inventory', 0, 1)
1494
self.target.control_weaves.copy_multi(
1495
self.source.control_weaves, ['inventory'],
1496
from_transaction=self.source.get_transaction(),
1497
to_transaction=self.target.get_transaction())
1498
self.target._revision_store.text_store.copy_all_ids(
1499
self.source._revision_store.text_store,
1896
1504
self.target.fetch(self.source, revision_id=revision_id)
1899
self.target.set_make_working_trees(self.source.make_working_trees())
1900
except NotImplementedError:
1902
# FIXME do not peek!
1903
if self.source.control_files._transport.listable():
1904
pb = ui.ui_factory.nested_progress_bar()
1906
self.target.weave_store.copy_all_ids(
1907
self.source.weave_store,
1909
from_transaction=self.source.get_transaction(),
1910
to_transaction=self.target.get_transaction())
1911
pb.update('copying inventory', 0, 1)
1912
self.target.control_weaves.copy_multi(
1913
self.source.control_weaves, ['inventory'],
1914
from_transaction=self.source.get_transaction(),
1915
to_transaction=self.target.get_transaction())
1916
self.target._revision_store.text_store.copy_all_ids(
1917
self.source._revision_store.text_store,
1922
self.target.fetch(self.source, revision_id=revision_id)
1924
1506
@needs_write_lock
1925
1507
def fetch(self, revision_id=None, pb=None):