22
22
from unittest import TestSuite
24
from bzrlib import bzrdir, check, delta, gpg, errors, xml5, ui, transactions, osutils
24
import bzrlib.bzrdir as bzrdir
25
25
from bzrlib.decorators import needs_read_lock, needs_write_lock
26
import bzrlib.errors as errors
26
27
from bzrlib.errors import InvalidRevisionId
28
import bzrlib.gpg as gpg
27
29
from bzrlib.graph import Graph
28
30
from bzrlib.inter import InterObject
29
31
from bzrlib.inventory import Inventory
35
37
from bzrlib.revision import NULL_REVISION, Revision
36
38
from bzrlib.store.versioned import VersionedFileStore, WeaveStore
37
39
from bzrlib.store.text import TextStore
38
from bzrlib.symbol_versioning import (deprecated_method,
40
from bzrlib.symbol_versioning import *
41
41
from bzrlib.trace import mutter, note
42
42
from bzrlib.tree import RevisionTree, EmptyTree
43
43
from bzrlib.tsort import topo_sort
44
44
from bzrlib.testament import Testament
45
45
from bzrlib.tree import EmptyTree
46
from bzrlib.delta import compare_trees
46
48
from bzrlib.weave import WeaveFile
49
52
class Repository(object):
70
73
assert inv.revision_id is None or inv.revision_id == revid, \
71
74
"Mismatch between inventory revision" \
72
75
" id and insertion revid (%r, %r)" % (inv.revision_id, revid)
73
inv_text = xml5.serializer_v5.write_inventory_to_string(inv)
74
inv_sha1 = osutils.sha_string(inv_text)
76
inv_text = bzrlib.xml5.serializer_v5.write_inventory_to_string(inv)
77
inv_sha1 = bzrlib.osutils.sha_string(inv_text)
75
78
inv_vf = self.control_weaves.get_weave('inventory',
76
79
self.get_transaction())
77
self._inventory_add_lines(inv_vf, revid, parents, osutils.split_lines(inv_text))
80
self._inventory_add_lines(inv_vf, revid, parents, bzrlib.osutils.split_lines(inv_text))
80
83
def _inventory_add_lines(self, inv_vf, revid, parents, lines):
117
120
"""Return all the possible revisions that we could find."""
118
121
return self.get_inventory_weave().versions()
123
@deprecated_method(zero_nine)
120
124
def all_revision_ids(self):
121
125
"""Returns a list of all the revision ids in the repository.
223
227
For instance, if the repository is at URL/.bzr/repository,
224
228
Repository.open(URL) -> a Repository instance.
226
control = bzrdir.BzrDir.open(base)
230
control = bzrlib.bzrdir.BzrDir.open(base)
227
231
return control.open_repository()
229
233
def copy_content_into(self, destination, revision_id=None, basis=None):
274
278
result = a_bzrdir.create_repository()
275
279
# FIXME RBC 20060209 split out the repository type to avoid this check ?
276
280
elif isinstance(a_bzrdir._format,
277
(bzrdir.BzrDirFormat4,
278
bzrdir.BzrDirFormat5,
279
bzrdir.BzrDirFormat6)):
281
(bzrlib.bzrdir.BzrDirFormat4,
282
bzrlib.bzrdir.BzrDirFormat5,
283
bzrlib.bzrdir.BzrDirFormat6)):
280
284
result = a_bzrdir.open_repository()
282
286
result = self._format.initialize(a_bzrdir, shared=self.is_shared())
331
335
self._check_revision_parents(r, inv)
335
def get_deltas_for_revisions(self, revisions):
336
"""Produce a generator of revision deltas.
338
Note that the input is a sequence of REVISIONS, not revision_ids.
339
Trees will be held in memory until the generator exits.
340
Each delta is relative to the revision's lefthand predecessor.
342
required_trees = set()
343
for revision in revisions:
344
required_trees.add(revision.revision_id)
345
required_trees.update(revision.parent_ids[:1])
346
trees = dict((t.get_revision_id(), t) for
347
t in self.revision_trees(required_trees))
348
for revision in revisions:
349
if not revision.parent_ids:
350
old_tree = EmptyTree()
352
old_tree = trees[revision.parent_ids[0]]
353
yield delta.compare_trees(old_tree, trees[revision.revision_id])
356
338
def get_revision_delta(self, revision_id):
357
339
"""Return the delta for one revision.
359
341
The delta is relative to the left-hand predecessor of the
362
r = self.get_revision(revision_id)
363
return list(self.get_deltas_for_revisions([r]))[0]
344
revision = self.get_revision(revision_id)
345
new_tree = self.revision_tree(revision_id)
346
if not revision.parent_ids:
347
old_tree = EmptyTree()
349
old_tree = self.revision_tree(revision.parent_ids[0])
350
return compare_trees(old_tree, new_tree)
365
352
def _check_revision_parents(self, revision, inventory):
366
353
"""Private to Repository and Fetch.
444
431
:param revision_id: The expected revision id of the inventory.
445
432
:param xml: A serialised inventory.
447
return xml5.serializer_v5.read_inventory_from_string(xml)
434
return bzrlib.xml5.serializer_v5.read_inventory_from_string(xml)
450
437
def get_inventory_xml(self, revision_id):
454
441
iw = self.get_inventory_weave()
455
442
return iw.get_text(revision_id)
456
443
except IndexError:
457
raise errors.HistoryMissing(self, 'inventory', revision_id)
444
raise bzrlib.errors.HistoryMissing(self, 'inventory', revision_id)
460
447
def get_inventory_sha1(self, revision_id):
567
554
return RevisionTree(self, inv, revision_id)
570
def revision_trees(self, revision_ids):
571
"""Return Tree for a revision on this branch.
573
`revision_id` may not be None or 'null:'"""
574
assert None not in revision_ids
575
assert NULL_REVISION not in revision_ids
576
texts = self.get_inventory_weave().get_texts(revision_ids)
577
for text, revision_id in zip(texts, revision_ids):
578
inv = self.deserialise_inventory(revision_id, text)
579
yield RevisionTree(self, inv, revision_id)
582
557
def get_ancestry(self, revision_id):
583
558
"""Return a list of revision-ids integrated by a revision.
668
643
return self._check(revision_ids)
670
645
def _check(self, revision_ids):
671
result = check.Check(self)
646
result = bzrlib.check.Check(self)
945
920
reconciler.reconcile()
946
921
return reconciler
948
def revision_parents(self, revision_id):
949
return self._get_revision_vf().get_parents(revision_id)
923
def revision_parents(self, revid):
924
return self._get_revision_vf().get_parents(rev_id)
952
926
class RepositoryFormat(object):
953
927
"""A repository format.
989
963
except errors.NoSuchFile:
990
964
raise errors.NoRepositoryPresent(a_bzrdir)
992
raise errors.UnknownFormatError(format=format_string)
966
raise errors.UnknownFormatError(format_string)
994
968
def _get_control_store(self, repo_transport, control_files):
995
969
"""Return the control store for this repository."""
1117
1091
# Create an empty weave
1118
1092
sio = StringIO()
1119
write_weave_v5(Weave(), sio)
1093
bzrlib.weavefile.write_weave_v5(Weave(), sio)
1120
1094
empty_weave = sio.getvalue()
1122
1096
mutter('creating repository in %s.', a_bzrdir.transport.base)
1183
1157
def __init__(self):
1184
1158
super(RepositoryFormat4, self).__init__()
1185
self._matchingbzrdir = bzrdir.BzrDirFormat4()
1159
self._matchingbzrdir = bzrlib.bzrdir.BzrDirFormat4()
1187
1161
def get_format_description(self):
1188
1162
"""See RepositoryFormat.get_format_description()."""
1232
1206
def __init__(self):
1233
1207
super(RepositoryFormat5, self).__init__()
1234
self._matchingbzrdir = bzrdir.BzrDirFormat5()
1208
self._matchingbzrdir = bzrlib.bzrdir.BzrDirFormat5()
1236
1210
def get_format_description(self):
1237
1211
"""See RepositoryFormat.get_format_description()."""
1262
1236
def __init__(self):
1263
1237
super(RepositoryFormat6, self).__init__()
1264
self._matchingbzrdir = bzrdir.BzrDirFormat6()
1238
self._matchingbzrdir = bzrlib.bzrdir.BzrDirFormat6()
1266
1240
def get_format_description(self):
1267
1241
"""See RepositoryFormat.get_format_description()."""
1286
1260
def __init__(self):
1287
1261
super(MetaDirRepositoryFormat, self).__init__()
1288
self._matchingbzrdir = bzrdir.BzrDirMetaFormat1()
1262
self._matchingbzrdir = bzrlib.bzrdir.BzrDirMetaFormat1()
1290
1264
def _create_control_files(self, a_bzrdir):
1291
1265
"""Create the required files and the initial control_files object."""
1367
1341
# Create an empty weave
1368
1342
sio = StringIO()
1369
write_weave_v5(Weave(), sio)
1343
bzrlib.weavefile.write_weave_v5(Weave(), sio)
1370
1344
empty_weave = sio.getvalue()
1372
1346
mutter('creating repository in %s.', a_bzrdir.transport.base)
1477
1451
repo_transport = a_bzrdir.get_repository_transport(None)
1478
1452
control_files = LockableFiles(repo_transport, 'lock', LockDir)
1479
1453
control_store = self._get_control_store(repo_transport, control_files)
1480
transaction = transactions.WriteTransaction()
1454
transaction = bzrlib.transactions.WriteTransaction()
1481
1455
# trigger a write of the inventory store.
1482
1456
control_store.get_weave_or_empty('inventory', transaction)
1483
1457
_revision_store = self._get_revision_store(repo_transport, control_files)
2115
2089
# TODO: Rather than invoking sha_strings here, _add_text_to_weave
2116
2090
# should return the SHA1 and size
2117
2091
self._add_text_to_weave(file_id, new_lines, file_parents.keys())
2118
return osutils.sha_strings(new_lines), \
2092
return bzrlib.osutils.sha_strings(new_lines), \
2119
2093
sum(map(len, new_lines))
2121
2095
def modified_link(self, file_id, file_parents, link_target):