21
from cStringIO import StringIO
23
24
from bzrlib.trace import mutter, note
24
from bzrlib.errors import BzrError
25
from bzrlib.errors import BzrError, BzrCheckError
25
26
from bzrlib.inventory import Inventory
26
from bzrlib.osutils import pumpfile, appendpath, fingerprint_file
27
from bzrlib.osutils import appendpath, fingerprint_file
57
58
def has_id(self, file_id):
58
59
return self.inventory.has_id(file_id)
61
def has_or_had_id(self, file_id):
62
if file_id == self.inventory.root.file_id:
64
return self.inventory.has_id(file_id)
60
66
__contains__ = has_id
62
68
def __iter__(self):
92
100
"store is probably damaged/corrupt"])
95
def print_file(self, fileid):
96
"""Print file with id `fileid` to stdout."""
103
def print_file(self, file_id):
104
"""Print file with id `file_id` to stdout."""
98
pumpfile(self.get_file(fileid), sys.stdout)
106
sys.stdout.write(self.get_file_text(file_id))
101
109
def export(self, dest, format='dir', root=None):
119
127
or at least passing a description to the constructor.
122
def __init__(self, store, inv):
130
def __init__(self, weave_store, inv, revision_id):
131
self._weave_store = weave_store
124
132
self._inventory = inv
133
self._revision_id = revision_id
135
def get_weave(self, file_id):
136
# FIXME: RevisionTree should be given a branch
137
# not a store, or the store should know the branch.
138
import bzrlib.transactions as transactions
139
return self._weave_store.get_weave(file_id,
140
transactions.PassThroughTransaction())
143
def get_file_lines(self, file_id):
144
ie = self._inventory[file_id]
145
weave = self.get_weave(file_id)
146
return weave.get(ie.revision)
149
def get_file_text(self, file_id):
150
return ''.join(self.get_file_lines(file_id))
126
153
def get_file(self, file_id):
127
ie = self._inventory[file_id]
128
f = self._store[ie.text_id]
129
mutter(" get fileid{%s} from %r" % (file_id, self))
130
self._check_retrieved(ie, f)
154
return StringIO(self.get_file_text(file_id))
133
156
def get_file_size(self, file_id):
134
157
return self._inventory[file_id].text_size
136
159
def get_file_sha1(self, file_id):
137
160
ie = self._inventory[file_id]
161
if ie.kind == "file":
164
def is_executable(self, file_id):
165
ie = self._inventory[file_id]
166
if ie.kind != "file":
168
return self._inventory[file_id].executable
140
170
def has_filename(self, filename):
141
171
return bool(self.inventory.path2id(filename))
143
173
def list_files(self):
144
174
# The only files returned by this are those from the version
145
175
for path, entry in self.inventory.iter_entries():
146
yield path, 'V', entry.kind, entry.file_id
176
yield path, 'V', entry.kind, entry.file_id, entry
178
def get_symlink_target(self, file_id):
179
ie = self._inventory[file_id]
180
return ie.symlink_target;
182
def kind(self, file_id):
183
return self._inventory[file_id].kind
149
185
class EmptyTree(Tree):
150
186
def __init__(self):
151
187
self._inventory = Inventory()
189
def get_symlink_target(self, file_id):
153
192
def has_filename(self, filename):
156
195
def list_files(self):
157
if False: # just to make it a generator
198
def __contains__(self, file_id):
199
return file_id in self._inventory
201
def get_file_sha1(self, file_id):
202
assert self._inventory[file_id].kind == "root_directory"
162
206
######################################################################
245
289
mutter('export version %r' % tree)
246
290
inv = tree.inventory
247
291
for dp, ie in inv.iter_entries():
249
fullpath = appendpath(dest, dp)
250
if kind == 'directory':
253
pumpfile(tree.get_file(ie.file_id), file(fullpath, 'wb'))
255
raise BzrError("don't know how to export {%s} of kind %r" % (ie.file_id, kind))
256
mutter(" export {%s} kind %s to %s" % (ie.file_id, kind, fullpath))
292
ie.put_on_disk(dest, dp, tree)
257
294
exporters['dir'] = dir_exporter
302
339
inv = tree.inventory
303
340
for dp, ie in inv.iter_entries():
304
341
mutter(" export {%s} kind %s to %s" % (ie.file_id, ie.kind, dest))
305
item = tarfile.TarInfo(os.path.join(root, dp))
306
# TODO: would be cool to actually set it to the timestamp of the
307
# revision it was last changed
309
if ie.kind == 'directory':
310
item.type = tarfile.DIRTYPE
315
elif ie.kind == 'file':
316
item.type = tarfile.REGTYPE
317
fileobj = tree.get_file(ie.file_id)
318
item.size = _find_file_size(fileobj)
321
raise BzrError("don't know how to export {%s} of kind %r" %
322
(ie.file_id, ie.kind))
342
item, fileobj = ie.get_tar_item(root, dp, now, tree)
324
343
ball.addfile(item, fileobj)
326
346
exporters['tar'] = tar_exporter
328
348
def tgz_exporter(tree, dest, root):
332
352
def tbz_exporter(tree, dest, root):
333
353
tar_exporter(tree, dest, root, compression='bz2')
334
354
exporters['tbz2'] = tbz_exporter
337
def _find_file_size(fileobj):
338
offset = fileobj.tell()
341
size = fileobj.tell()
343
# gzip doesn't accept second argument to seek()
347
nread = len(fileobj.read())