17
17
"""Tree classes, representing directory at point in time.
20
from osutils import pumpfile, appendpath, fingerprint_file
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
26
from bzrlib.inventory import Inventory
27
from bzrlib.osutils import appendpath, fingerprint_file
67
69
def _get_inventory(self):
68
70
return self._inventory
72
def get_file_by_path(self, path):
73
return self.get_file(self._inventory.path2id(path))
70
75
inventory = property(_get_inventory,
71
76
doc="Inventory of this Tree")
73
78
def _check_retrieved(self, ie, f):
74
81
fp = fingerprint_file(f)
88
95
"store is probably damaged/corrupt"])
91
def print_file(self, fileid):
92
"""Print file with id `fileid` to stdout."""
98
def print_file(self, file_id):
99
"""Print file with id `file_id` to stdout."""
94
pumpfile(self.get_file(fileid), sys.stdout)
101
sys.stdout.write(self.get_file_text(file_id))
97
104
def export(self, dest, format='dir', root=None):
115
122
or at least passing a description to the constructor.
118
def __init__(self, store, inv):
125
def __init__(self, weave_store, inv, revision_id):
126
self._weave_store = weave_store
120
127
self._inventory = inv
128
self._revision_id = revision_id
130
def get_weave(self, file_id):
131
# FIXME: RevisionTree should be given a branch
132
# not a store, or the store should know the branch.
133
import bzrlib.transactions as transactions
134
return self._weave_store.get_weave(file_id,
135
transactions.PassThroughTransaction())
138
def get_file_lines(self, file_id):
139
ie = self._inventory[file_id]
140
weave = self.get_weave(file_id)
141
return weave.get(ie.revision)
144
def get_file_text(self, file_id):
145
return ''.join(self.get_file_lines(file_id))
122
148
def get_file(self, file_id):
123
ie = self._inventory[file_id]
124
f = self._store[ie.text_id]
125
mutter(" get fileid{%s} from %r" % (file_id, self))
126
self._check_retrieved(ie, f)
149
return StringIO(self.get_file_text(file_id))
129
151
def get_file_size(self, file_id):
130
152
return self._inventory[file_id].text_size
132
154
def get_file_sha1(self, file_id):
133
155
ie = self._inventory[file_id]
156
if ie.kind == "file":
159
def is_executable(self, file_id):
160
return self._inventory[file_id].executable
136
162
def has_filename(self, filename):
137
163
return bool(self.inventory.path2id(filename))
139
165
def list_files(self):
140
166
# The only files returned by this are those from the version
141
167
for path, entry in self.inventory.iter_entries():
142
yield path, 'V', entry.kind, entry.file_id
168
yield path, 'V', entry.kind, entry.file_id, entry
170
def get_symlink_target(self, file_id):
171
ie = self._inventory[file_id]
172
return ie.symlink_target;
145
175
class EmptyTree(Tree):
146
def __init__(self, root_id):
147
from bzrlib.inventory import Inventory
148
self._inventory = Inventory(root_id)
177
self._inventory = Inventory()
179
def get_symlink_target(self, file_id):
150
182
def has_filename(self, filename):
153
185
def list_files(self):
154
if False: # just to make it a generator
188
def __contains__(self, file_id):
189
return file_id in self._inventory
191
def get_file_sha1(self, file_id):
192
assert self._inventory[file_id].kind == "root_directory"
159
196
######################################################################
242
279
mutter('export version %r' % tree)
243
280
inv = tree.inventory
244
281
for dp, ie in inv.iter_entries():
246
fullpath = appendpath(dest, dp)
247
if kind == 'directory':
250
pumpfile(tree.get_file(ie.file_id), file(fullpath, 'wb'))
252
raise BzrError("don't know how to export {%s} of kind %r" % (ie.file_id, kind))
253
mutter(" export {%s} kind %s to %s" % (ie.file_id, kind, fullpath))
282
ie.put_on_disk(dest, dp, tree)
254
284
exporters['dir'] = dir_exporter
299
329
inv = tree.inventory
300
330
for dp, ie in inv.iter_entries():
301
331
mutter(" export {%s} kind %s to %s" % (ie.file_id, ie.kind, dest))
302
item = tarfile.TarInfo(os.path.join(root, dp))
303
# TODO: would be cool to actually set it to the timestamp of the
304
# revision it was last changed
306
if ie.kind == 'directory':
307
item.type = tarfile.DIRTYPE
312
elif ie.kind == 'file':
313
item.type = tarfile.REGTYPE
314
fileobj = tree.get_file(ie.file_id)
315
item.size = _find_file_size(fileobj)
318
raise BzrError("don't know how to export {%s} of kind %r" %
319
(ie.file_id, ie.kind))
332
item, fileobj = ie.get_tar_item(root, dp, now, tree)
321
333
ball.addfile(item, fileobj)
323
336
exporters['tar'] = tar_exporter
325
338
def tgz_exporter(tree, dest, root):
329
342
def tbz_exporter(tree, dest, root):
330
343
tar_exporter(tree, dest, root, compression='bz2')
331
344
exporters['tbz2'] = tbz_exporter
334
def _find_file_size(fileobj):
335
offset = fileobj.tell()
338
size = fileobj.tell()
340
# gzip doesn't accept second argument to seek()
344
nread = len(fileobj.read())