93
def add_inventory(self, revision_id, inv, parents):
94
"""Add the inventory inv to the repository as revision_id.
92
def add_inventory(self, revid, inv, parents):
93
"""Add the inventory inv to the repository as revid.
96
:param parents: The revision ids of the parents that revision_id
95
:param parents: The revision ids of the parents that revid
97
96
is known to have and are in the repository already.
99
98
returns the sha1 of the serialized inventory.
101
revision_id = osutils.safe_revision_id(revision_id)
102
_mod_revision.check_not_reserved_id(revision_id)
103
assert inv.revision_id is None or inv.revision_id == revision_id, \
100
_mod_revision.check_not_reserved_id(revid)
101
assert inv.revision_id is None or inv.revision_id == revid, \
104
102
"Mismatch between inventory revision" \
105
" id and insertion revid (%r, %r)" % (inv.revision_id, revision_id)
103
" id and insertion revid (%r, %r)" % (inv.revision_id, revid)
106
104
assert inv.root is not None
107
105
inv_text = self.serialise_inventory(inv)
108
106
inv_sha1 = osutils.sha_string(inv_text)
109
107
inv_vf = self.control_weaves.get_weave('inventory',
110
108
self.get_transaction())
111
self._inventory_add_lines(inv_vf, revision_id, parents,
112
osutils.split_lines(inv_text))
109
self._inventory_add_lines(inv_vf, revid, parents, osutils.split_lines(inv_text))
115
def _inventory_add_lines(self, inv_vf, revision_id, parents, lines):
112
def _inventory_add_lines(self, inv_vf, revid, parents, lines):
116
113
final_parents = []
117
114
for parent in parents:
118
115
if parent in inv_vf:
119
116
final_parents.append(parent)
121
inv_vf.add_lines(revision_id, final_parents, lines)
118
inv_vf.add_lines(revid, final_parents, lines)
123
120
@needs_write_lock
124
def add_revision(self, revision_id, rev, inv=None, config=None):
125
"""Add rev to the revision store as revision_id.
121
def add_revision(self, rev_id, rev, inv=None, config=None):
122
"""Add rev to the revision store as rev_id.
127
:param revision_id: the revision id to use.
124
:param rev_id: the revision id to use.
128
125
:param rev: The revision object.
129
126
:param inv: The inventory for the revision. if None, it will be looked
130
127
up in the inventory storer
132
129
If supplied its signature_needed method will be used
133
130
to determine if a signature should be made.
135
revision_id = osutils.safe_revision_id(revision_id)
136
# TODO: jam 20070210 Shouldn't we check rev.revision_id and
138
_mod_revision.check_not_reserved_id(revision_id)
132
_mod_revision.check_not_reserved_id(rev_id)
139
133
if config is not None and config.signature_needed():
141
inv = self.get_inventory(revision_id)
135
inv = self.get_inventory(rev_id)
142
136
plaintext = Testament(rev, inv).as_short_text()
143
137
self.store_revision_signature(
144
gpg.GPGStrategy(config), plaintext, revision_id)
145
if not revision_id in self.get_inventory_weave():
138
gpg.GPGStrategy(config), plaintext, rev_id)
139
if not rev_id in self.get_inventory_weave():
147
raise errors.WeaveRevisionNotPresent(revision_id,
141
raise errors.WeaveRevisionNotPresent(rev_id,
148
142
self.get_inventory_weave())
150
144
# yes, this is not suitable for adding with ghosts.
151
self.add_inventory(revision_id, inv, rev.parent_ids)
145
self.add_inventory(rev_id, inv, rev.parent_ids)
152
146
self._revision_store.add_revision(rev, self.get_transaction())
176
170
if self._revision_store.text_store.listable():
177
171
return self._revision_store.all_revision_ids(self.get_transaction())
178
172
result = self._all_possible_ids()
179
# TODO: jam 20070210 Ensure that _all_possible_ids returns non-unicode
180
# ids. (It should, since _revision_store's API should change to
181
# return utf8 revision_ids)
182
173
return self._eliminate_revisions_not_present(result)
184
175
def break_lock(self):
303
291
:param revprops: Optional dictionary of revision properties.
304
292
:param revision_id: Optional revision id.
306
revision_id = osutils.safe_revision_id(revision_id)
307
294
return _CommitBuilder(self, parents, config, timestamp, timezone,
308
295
committer, revprops, revision_id)
350
336
if not revision_id or not isinstance(revision_id, basestring):
351
337
raise errors.InvalidRevisionId(revision_id=revision_id,
353
return self.get_revisions([revision_id])[0]
339
return self._revision_store.get_revisions([revision_id],
340
self.get_transaction())[0]
356
342
def get_revisions(self, revision_ids):
357
revision_ids = [osutils.safe_revision_id(r) for r in revision_ids]
358
revs = self._revision_store.get_revisions(revision_ids,
343
return self._revision_store.get_revisions(revision_ids,
359
344
self.get_transaction())
361
assert not isinstance(rev.revision_id, unicode)
362
for parent_id in rev.parent_ids:
363
assert not isinstance(parent_id, unicode)
367
347
def get_revision_xml(self, revision_id):
368
# TODO: jam 20070210 This shouldn't be necessary since get_revision
369
# would have already do it.
370
# TODO: jam 20070210 Just use _serializer.write_revision_to_string()
371
revision_id = osutils.safe_revision_id(revision_id)
372
rev = self.get_revision(revision_id)
348
rev = self.get_revision(revision_id)
373
349
rev_tmp = StringIO()
374
350
# the current serializer..
375
351
self._revision_store._serializer.write_revision(rev, rev_tmp)
531
503
def get_inventory(self, revision_id):
532
504
"""Get Inventory object by hash."""
533
# TODO: jam 20070210 Technically we don't need to sanitize, since all
534
# called functions must sanitize.
535
revision_id = osutils.safe_revision_id(revision_id)
536
505
return self.deserialise_inventory(
537
506
revision_id, self.get_inventory_xml(revision_id))
554
522
def get_inventory_xml(self, revision_id):
555
523
"""Get inventory XML as a file object."""
556
revision_id = osutils.safe_revision_id(revision_id)
558
assert isinstance(revision_id, str), type(revision_id)
525
assert isinstance(revision_id, basestring), type(revision_id)
559
526
iw = self.get_inventory_weave()
560
527
return iw.get_text(revision_id)
561
528
except IndexError:
739
700
def get_transaction(self):
740
701
return self.control_files.get_transaction()
742
def revision_parents(self, revision_id):
743
revision_id = osutils.safe_revision_id(revision_id)
744
return self.get_inventory_weave().parent_names(revision_id)
703
def revision_parents(self, revid):
704
return self.get_inventory_weave().parent_names(revid)
746
706
@needs_write_lock
747
707
def set_make_working_trees(self, new_value):
762
722
@needs_write_lock
763
723
def sign_revision(self, revision_id, gpg_strategy):
764
revision_id = osutils.safe_revision_id(revision_id)
765
724
plaintext = Testament.from_revision(self, revision_id).as_short_text()
766
725
self.store_revision_signature(gpg_strategy, plaintext, revision_id)
769
728
def has_signature_for_revision_id(self, revision_id):
770
729
"""Query for a revision signature for revision_id in the repository."""
771
revision_id = osutils.safe_revision_id(revision_id)
772
730
return self._revision_store.has_signature(revision_id,
773
731
self.get_transaction())
776
734
def get_signature_text(self, revision_id):
777
735
"""Return the text for a signature."""
778
revision_id = osutils.safe_revision_id(revision_id)
779
736
return self._revision_store.get_signature_text(revision_id,
780
737
self.get_transaction())
1012
963
This determines the set of revisions which are involved, and then
1013
964
finds all file ids affected by those revisions.
1015
# TODO: jam 20070210 Is this function even used?
1016
from_revid = osutils.safe_revision_id(from_revid)
1017
to_revid = osutils.safe_revision_id(to_revid)
1018
966
vf = self._get_revision_vf()
1019
967
from_set = set(vf.get_ancestry(from_revid))
1020
968
to_set = set(vf.get_ancestry(to_revid))
1188
1131
:param revprops: Optional dictionary of revision properties.
1189
1132
:param revision_id: Optional revision id.
1191
revision_id = osutils.safe_revision_id(revision_id)
1192
1134
return RootCommitBuilder(self, parents, config, timestamp, timezone,
1193
1135
committer, revprops, revision_id)
1196
class RepositoryFormatRegistry(registry.Registry):
1197
"""Registry of RepositoryFormats.
1201
format_registry = RepositoryFormatRegistry()
1202
"""Registry of formats, indexed by their identifying format string."""
1205
1138
class RepositoryFormat(object):
1206
1139
"""A repository format.
1226
1159
parameterisation.
1162
_default_format = None
1163
"""The default format used for new repositories."""
1166
"""The known formats."""
1229
1168
def __str__(self):
1230
1169
return "<%s>" % self.__class__.__name__
1233
1172
def find_format(klass, a_bzrdir):
1234
"""Return the format for the repository object in a_bzrdir.
1236
This is used by bzr native formats that have a "format" file in
1237
the repository. Other methods may be used by different types of
1173
"""Return the format for the repository object in a_bzrdir."""
1241
1175
transport = a_bzrdir.get_repository_transport(None)
1242
1176
format_string = transport.get("format").read()
1243
return format_registry.get(format_string)
1177
return klass._formats[format_string]
1244
1178
except errors.NoSuchFile:
1245
1179
raise errors.NoRepositoryPresent(a_bzrdir)
1246
1180
except KeyError:
1247
1181
raise errors.UnknownFormatError(format=format_string)
1250
@deprecated_method(symbol_versioning.zero_fourteen)
1251
def set_default_format(klass, format):
1252
klass._set_default_format(format)
1255
def _set_default_format(klass, format):
1256
"""Set the default format for new Repository creation.
1258
The format must already be registered.
1260
format_registry.default_key = format.get_format_string()
1263
def register_format(klass, format):
1264
format_registry.register(format.get_format_string(), format)
1267
def unregister_format(klass, format):
1268
format_registry.remove(format.get_format_string())
1183
def _get_control_store(self, repo_transport, control_files):
1184
"""Return the control store for this repository."""
1185
raise NotImplementedError(self._get_control_store)
1271
1188
def get_default_format(klass):
1272
1189
"""Return the current default format."""
1273
return format_registry.get(format_registry.default_key)
1275
def _get_control_store(self, repo_transport, control_files):
1276
"""Return the control store for this repository."""
1277
raise NotImplementedError(self._get_control_store)
1190
return klass._default_format
1279
1192
def get_format_string(self):
1280
1193
"""Return the ASCII format string that identifies this format.
1363
1276
raise NotImplementedError(self.open)
1279
def register_format(klass, format):
1280
klass._formats[format.get_format_string()] = format
1283
@deprecated_method(symbol_versioning.zero_fourteen)
1284
def set_default_format(klass, format):
1285
klass._set_default_format(format)
1288
def _set_default_format(klass, format):
1289
klass._default_format = format
1292
def unregister_format(klass, format):
1293
assert klass._formats[format.get_format_string()] is format
1294
del klass._formats[format.get_format_string()]
1366
1297
class PreSplitOutRepositoryFormat(RepositoryFormat):
1367
1298
"""Base class for the pre split out repository formats."""
1876
1807
# formats which have no format string are not discoverable
1877
1808
# and not independently creatable, so are not registered.
1878
1809
RepositoryFormat.register_format(RepositoryFormat7())
1879
# KEEP in sync with bzrdir.format_registry default, which controls the overall
1880
# default control directory format
1810
# KEEP in sync with bzrdir.format_registry default
1881
1811
_default_format = RepositoryFormatKnit1()
1882
1812
RepositoryFormat.register_format(_default_format)
1883
1813
RepositoryFormat.register_format(RepositoryFormatKnit2())
1932
1862
# generic, possibly worst case, slow code path.
1933
1863
target_ids = set(self.target.all_revision_ids())
1934
1864
if revision_id is not None:
1935
# TODO: jam 20070210 InterRepository is internal enough that it
1936
# should assume revision_ids are already utf-8
1937
revision_id = osutils.safe_revision_id(revision_id)
1938
1865
source_ids = self.source.get_ancestry(revision_id)
1939
1866
assert source_ids[0] is None
1940
1867
source_ids.pop(0)
1982
1909
self.target.set_make_working_trees(self.source.make_working_trees())
1983
1910
except NotImplementedError:
1985
# TODO: jam 20070210 This is fairly internal, so we should probably
1986
# just assert that revision_id is not unicode.
1987
revision_id = osutils.safe_revision_id(revision_id)
1988
1912
# grab the basis available data
1989
1913
if basis is not None:
1990
1914
self.target.fetch(basis, revision_id=revision_id)
2001
1925
mutter("Using fetch logic to copy between %s(%s) and %s(%s)",
2002
1926
self.source, self.source._format, self.target,
2003
1927
self.target._format)
2004
# TODO: jam 20070210 This should be an assert, not a translate
2005
revision_id = osutils.safe_revision_id(revision_id)
2006
1928
f = GenericRepoFetcher(to_repository=self.target,
2007
1929
from_repository=self.source,
2008
1930
last_revision=revision_id,
2038
1960
def copy_content(self, revision_id=None, basis=None):
2039
1961
"""See InterRepository.copy_content()."""
2040
1962
# weave specific optimised path:
2041
# TODO: jam 20070210 Internal, should be an assert, not translate
2042
revision_id = osutils.safe_revision_id(revision_id)
2043
1963
if basis is not None:
2044
1964
# copy the basis in, then fetch remaining data.
2045
1965
basis.copy_content_into(self.target, revision_id)
2082
2002
from bzrlib.fetch import GenericRepoFetcher
2083
2003
mutter("Using fetch logic to copy between %s(%s) and %s(%s)",
2084
2004
self.source, self.source._format, self.target, self.target._format)
2085
# TODO: jam 20070210 This should be an assert, not a translate
2086
revision_id = osutils.safe_revision_id(revision_id)
2087
2005
f = GenericRepoFetcher(to_repository=self.target,
2088
2006
from_repository=self.source,
2089
2007
last_revision=revision_id,
2158
2076
from bzrlib.fetch import KnitRepoFetcher
2159
2077
mutter("Using fetch logic to copy between %s(%s) and %s(%s)",
2160
2078
self.source, self.source._format, self.target, self.target._format)
2161
# TODO: jam 20070210 This should be an assert, not a translate
2162
revision_id = osutils.safe_revision_id(revision_id)
2163
2079
f = KnitRepoFetcher(to_repository=self.target,
2164
2080
from_repository=self.source,
2165
2081
last_revision=revision_id,
2216
2132
def fetch(self, revision_id=None, pb=None):
2217
2133
"""See InterRepository.fetch()."""
2218
2134
from bzrlib.fetch import Model1toKnit2Fetcher
2219
# TODO: jam 20070210 This should be an assert, not a translate
2220
revision_id = osutils.safe_revision_id(revision_id)
2221
2135
f = Model1toKnit2Fetcher(to_repository=self.target,
2222
2136
from_repository=self.source,
2223
2137
last_revision=revision_id,
2271
2183
mutter("Using fetch logic to copy between %s(%s) and %s(%s)",
2272
2184
self.source, self.source._format, self.target,
2273
2185
self.target._format)
2274
# TODO: jam 20070210 This should be an assert, not a translate
2275
revision_id = osutils.safe_revision_id(revision_id)
2276
2186
f = Knit1to2Fetcher(to_repository=self.target,
2277
2187
from_repository=self.source,
2278
2188
last_revision=revision_id,