21
from cStringIO import StringIO
24
23
from bzrlib.trace import mutter, note
25
from bzrlib.errors import BzrError, BzrCheckError
24
from bzrlib.errors import BzrError
26
25
from bzrlib.inventory import Inventory
27
from bzrlib.osutils import appendpath, fingerprint_file
26
from bzrlib.osutils import pumpfile, appendpath, fingerprint_file
58
57
def has_id(self, file_id):
59
58
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)
66
60
__contains__ = has_id
68
62
def __iter__(self):
71
65
def id2path(self, file_id):
72
66
return self.inventory.id2path(file_id)
74
def kind(self, file_id):
75
raise NotImplementedError("subclasses must implement kind")
77
68
def _get_inventory(self):
78
69
return self._inventory
103
92
"store is probably damaged/corrupt"])
106
def print_file(self, file_id):
107
"""Print file with id `file_id` to stdout."""
95
def print_file(self, fileid):
96
"""Print file with id `fileid` to stdout."""
109
sys.stdout.write(self.get_file_text(file_id))
98
pumpfile(self.get_file(fileid), sys.stdout)
112
101
def export(self, dest, format='dir', root=None):
130
119
or at least passing a description to the constructor.
133
def __init__(self, weave_store, inv, revision_id):
134
self._weave_store = weave_store
122
def __init__(self, store, inv):
135
124
self._inventory = inv
136
self._revision_id = revision_id
138
def get_weave(self, file_id):
139
# FIXME: RevisionTree should be given a branch
140
# not a store, or the store should know the branch.
141
import bzrlib.transactions as transactions
142
return self._weave_store.get_weave(file_id,
143
transactions.PassThroughTransaction())
146
def get_file_lines(self, file_id):
147
ie = self._inventory[file_id]
148
weave = self.get_weave(file_id)
149
return weave.get(ie.revision)
152
def get_file_text(self, file_id):
153
return ''.join(self.get_file_lines(file_id))
156
126
def get_file(self, file_id):
157
return StringIO(self.get_file_text(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)
159
133
def get_file_size(self, file_id):
160
134
return self._inventory[file_id].text_size
164
138
if ie.kind == "file":
165
139
return ie.text_sha1
167
def is_executable(self, file_id):
168
ie = self._inventory[file_id]
169
if ie.kind != "file":
171
return self._inventory[file_id].executable
173
141
def has_filename(self, filename):
174
142
return bool(self.inventory.path2id(filename))
176
144
def list_files(self):
177
145
# The only files returned by this are those from the version
178
146
for path, entry in self.inventory.iter_entries():
179
yield path, 'V', entry.kind, entry.file_id, entry
181
def get_symlink_target(self, file_id):
182
ie = self._inventory[file_id]
183
return ie.symlink_target;
185
def kind(self, file_id):
186
return self._inventory[file_id].kind
147
yield path, 'V', entry.kind, entry.file_id
189
150
class EmptyTree(Tree):
190
151
def __init__(self):
191
152
self._inventory = Inventory()
193
def get_symlink_target(self, file_id):
196
154
def has_filename(self, filename):
199
def kind(self, file_id):
200
assert self._inventory[file_id].kind == "root_directory"
201
return "root_directory"
203
157
def list_files(self):
158
if False: # just to make it a generator
206
161
def __contains__(self, file_id):
207
162
return file_id in self._inventory
297
254
mutter('export version %r' % tree)
298
255
inv = tree.inventory
299
256
for dp, ie in inv.iter_entries():
300
ie.put_on_disk(dest, dp, tree)
258
fullpath = appendpath(dest, dp)
259
if kind == 'directory':
262
pumpfile(tree.get_file(ie.file_id), file(fullpath, 'wb'))
264
raise BzrError("don't know how to export {%s} of kind %r" % (ie.file_id, kind))
265
mutter(" export {%s} kind %s to %s" % (ie.file_id, kind, fullpath))
302
266
exporters['dir'] = dir_exporter
347
311
inv = tree.inventory
348
312
for dp, ie in inv.iter_entries():
349
313
mutter(" export {%s} kind %s to %s" % (ie.file_id, ie.kind, dest))
350
item, fileobj = ie.get_tar_item(root, dp, now, tree)
314
item = tarfile.TarInfo(os.path.join(root, dp))
315
# TODO: would be cool to actually set it to the timestamp of the
316
# revision it was last changed
318
if ie.kind == 'directory':
319
item.type = tarfile.DIRTYPE
324
elif ie.kind == 'file':
325
item.type = tarfile.REGTYPE
326
fileobj = tree.get_file(ie.file_id)
327
item.size = _find_file_size(fileobj)
330
raise BzrError("don't know how to export {%s} of kind %r" %
331
(ie.file_id, ie.kind))
351
333
ball.addfile(item, fileobj)
354
335
exporters['tar'] = tar_exporter
356
337
def tgz_exporter(tree, dest, root):
360
341
def tbz_exporter(tree, dest, root):
361
342
tar_exporter(tree, dest, root, compression='bz2')
362
343
exporters['tbz2'] = tbz_exporter
346
def _find_file_size(fileobj):
347
offset = fileobj.tell()
350
size = fileobj.tell()
352
# gzip doesn't accept second argument to seek()
356
nread = len(fileobj.read())