23
23
from cStringIO import StringIO
25
from warnings import warn
27
from bzrlib import errors
26
28
from bzrlib.weavefile import read_weave, write_weave_v5
27
29
from bzrlib.weave import WeaveFile, Weave
28
30
from bzrlib.store import TransportStore
29
31
from bzrlib.atomicfile import AtomicFile
30
from bzrlib.errors import NoSuchFile, FileExists
31
from bzrlib.symbol_versioning import *
32
from bzrlib.symbol_versioning import (deprecated_method,
32
34
from bzrlib.trace import mutter
112
114
fn = self.filename(file_id)
114
116
return self._transport.put(fn, f, mode=self._file_mode)
117
except errors.NoSuchFile:
116
118
if not self._prefixed:
118
120
self._transport.mkdir(os.path.dirname(fn), mode=self._dir_mode)
119
121
return self._transport.put(fn, f, mode=self._file_mode)
121
def get_weave(self, file_id, transaction):
123
def get_weave(self, file_id, transaction, _filename=None):
124
"""Return the VersionedFile for file_id.
126
:param _filename: filename that would be returned from self.filename for
127
file_id. This is used to reduce duplicate filename calculations when
128
using 'get_weave_or_empty'. FOR INTERNAL USE ONLY.
122
130
weave = transaction.map.find_weave(file_id)
123
131
if weave is not None:
124
132
#mutter("cache hit in %s for %s", self, file_id)
134
if _filename is None:
135
_filename = self.filename(file_id)
126
136
if transaction.writeable():
127
w = self._versionedfile_class(self.filename(file_id), self._transport, self._file_mode,
137
w = self._versionedfile_class(_filename, self._transport, self._file_mode,
128
138
**self._versionedfile_kwargs)
129
139
transaction.map.add_weave(file_id, w)
130
140
transaction.register_dirty(w)
132
w = self._versionedfile_class(self.filename(file_id),
142
w = self._versionedfile_class(_filename,
148
158
w = self.get_weave(file_id, transaction)
149
159
return w.get_lines(rev_id)
151
def _new_weave(self, file_id, transaction):
152
"""Make a new weave for file_id and return it."""
153
weave = self._make_new_versionedfile(file_id, transaction)
154
transaction.map.add_weave(file_id, weave)
155
# has to be dirty - its able to mutate on its own.
156
transaction.register_dirty(weave)
159
def _make_new_versionedfile(self, file_id, transaction):
160
if self.has_id(file_id):
161
def _make_new_versionedfile(self, file_id, transaction,
162
known_missing=False, _filename=None):
163
"""Make a new versioned file.
165
:param _filename: filename that would be returned from self.filename for
166
file_id. This is used to reduce duplicate filename calculations when
167
using 'get_weave_or_empty'. FOR INTERNAL USE ONLY.
169
if not known_missing and self.has_id(file_id):
161
170
self.delete(file_id, transaction)
171
if _filename is None:
172
_filename = self.filename(file_id)
163
weave = self._versionedfile_class(self.filename(file_id), self._transport, self._file_mode, create=True,
174
# we try without making the directory first because thats optimising
175
# for the common case.
176
weave = self._versionedfile_class(_filename, self._transport, self._file_mode, create=True,
164
177
**self._versionedfile_kwargs)
178
except errors.NoSuchFile:
166
179
if not self._prefixed:
167
# unexpected error - NoSuchFile is raised on a missing dir only and that
168
# only occurs when we are prefixed.
180
# unexpected error - NoSuchFile is expected to be raised on a
181
# missing dir only and that only occurs when we are prefixed.
170
183
self._transport.mkdir(self.hash_prefix(file_id), mode=self._dir_mode)
171
weave = self._versionedfile_class(self.filename(file_id), self._transport,
184
weave = self._versionedfile_class(_filename, self._transport,
172
185
self._file_mode, create=True,
173
186
**self._versionedfile_kwargs)
176
189
def get_weave_or_empty(self, file_id, transaction):
177
"""Return a weave, or an empty one if it doesn't exist."""
190
"""Return a weave, or an empty one if it doesn't exist."""
191
# This is typically used from 'commit' and 'fetch/push/pull' where
192
# we scan across many versioned files once. As such the small overhead
193
# of calculating the filename before doing a cache lookup is more than
194
# compensated for by not calculating the filename when making new
196
_filename = self.filename(file_id)
179
return self.get_weave(file_id, transaction)
181
return self._new_weave(file_id, transaction)
198
return self.get_weave(file_id, transaction, _filename=_filename)
199
except errors.NoSuchFile:
200
weave = self._make_new_versionedfile(file_id, transaction,
201
known_missing=True, _filename=_filename)
202
transaction.map.add_weave(file_id, weave)
203
# has to be dirty - its able to mutate on its own.
204
transaction.register_dirty(weave)
183
207
@deprecated_method(zero_eight)
184
208
def put_weave(self, file_id, weave, transaction):