17
17
"""Tree classes, representing directory at point in time.
21
from cStringIO import StringIO
21
import os.path, os, fnmatch, time
23
from osutils import pumpfile, filesize, quotefn, sha_file, \
24
joinpath, splitpath, appendpath, isdir, isfile, file_kind, fingerprint_file
26
from stat import S_ISREG, S_ISDIR, ST_MODE, ST_SIZE
28
from bzrlib.inventory import Inventory
29
from bzrlib.trace import mutter, note
30
from bzrlib.errors import BzrError
24
from bzrlib.trace import mutter, note
25
from bzrlib.errors import BzrError, BzrCheckError
26
from bzrlib.inventory import Inventory
27
from bzrlib.osutils import pumpfile, appendpath, fingerprint_file
69
74
def _get_inventory(self):
70
75
return self._inventory
72
def get_file_by_path(self, path):
73
return self.get_file(self._inventory.path2id(path))
75
77
inventory = property(_get_inventory,
76
78
doc="Inventory of this Tree")
93
95
"store is probably damaged/corrupt"])
96
def print_file(self, file_id):
97
"""Print file with id `file_id` to stdout."""
98
def print_file(self, fileid):
99
"""Print file with id `fileid` to stdout."""
99
sys.stdout.write(self.get_file_text(file_id))
102
def export(self, dest, format='dir', root=None):
101
pumpfile(self.get_file(fileid), sys.stdout)
104
def export(self, dest, format='dir'):
103
105
"""Export this tree."""
105
107
exporter = exporters[format]
107
from bzrlib.errors import BzrCommandError
108
109
raise BzrCommandError("export format %r not supported" % format)
109
exporter(self, dest, root)
120
121
or at least passing a description to the constructor.
123
def __init__(self, weave_store, inv, revision_id):
124
self._weave_store = weave_store
124
def __init__(self, store, inv):
125
126
self._inventory = inv
126
self._revision_id = revision_id
128
def get_weave(self, file_id):
129
return self._weave_store.get_weave(file_id)
132
def get_file_text(self, file_id):
133
ie = self._inventory[file_id]
134
weave = self.get_weave(file_id)
135
idx = weave.lookup(ie.text_version)
136
content = weave.get_text(idx)
137
if len(content) != ie.text_size:
138
raise BzrCheckError('mismatched size on revision %s of file %s: '
140
% (self._revision_id, file_id, len(content),
144
128
def get_file(self, file_id):
145
return StringIO(self.get_file_text(file_id))
129
ie = self._inventory[file_id]
130
f = self._store[ie.text_id]
131
mutter(" get fileid{%s} from %r" % (file_id, self))
132
self._check_retrieved(ie, f)
147
135
def get_file_size(self, file_id):
148
136
return self._inventory[file_id].text_size
150
138
def get_file_sha1(self, file_id):
151
139
ie = self._inventory[file_id]
152
if ie.kind == "file":
155
142
def has_filename(self, filename):
156
143
return bool(self.inventory.path2id(filename))
172
159
if False: # just to make it a generator
175
def __contains__(self, file_id):
176
return file_id in self._inventory
178
def get_file_sha1(self, file_id):
179
assert self._inventory[file_id].kind == "root_directory"
185
164
######################################################################
251
230
######################################################################
254
def dir_exporter(tree, dest, root):
233
def dir_exporter(tree, dest):
255
234
"""Export this tree to a new directory.
257
236
`dest` should not exist, and will be created holding the
284
262
except ImportError:
287
def get_root_name(dest):
288
"""Get just the root name for a tarball.
290
>>> get_root_name('mytar.tar')
292
>>> get_root_name('mytar.tar.bz2')
294
>>> get_root_name('tar.tar.tar.tgz')
296
>>> get_root_name('bzr-0.0.5.tar.gz')
298
>>> get_root_name('a/long/path/mytar.tgz')
300
>>> get_root_name('../parent/../dir/other.tbz2')
303
endings = ['.tar', '.tar.gz', '.tgz', '.tar.bz2', '.tbz2']
304
dest = os.path.basename(dest)
306
if dest.endswith(end):
307
return dest[:-len(end)]
309
def tar_exporter(tree, dest, root, compression=None):
265
def tar_exporter(tree, dest, compression=None):
310
266
"""Export this tree to a new tar file.
312
268
`dest` will be created holding the contents of this tree; if it
313
269
already exists, it will be clobbered, like with "tar -c".
315
from time import time
317
272
compression = str(compression or '')
319
root = get_root_name(dest)
321
274
ball = tarfile.open(dest, 'w:' + compression)
322
275
except tarfile.CompressionError, e:
325
278
inv = tree.inventory
326
279
for dp, ie in inv.iter_entries():
327
280
mutter(" export {%s} kind %s to %s" % (ie.file_id, ie.kind, dest))
328
item = tarfile.TarInfo(os.path.join(root, dp))
281
item = tarfile.TarInfo(dp)
329
282
# TODO: would be cool to actually set it to the timestamp of the
330
283
# revision it was last changed
349
302
exporters['tar'] = tar_exporter
351
def tgz_exporter(tree, dest, root):
352
tar_exporter(tree, dest, root, compression='gz')
304
def tgz_exporter(tree, dest):
305
tar_exporter(tree, dest, compression='gz')
353
306
exporters['tgz'] = tgz_exporter
355
def tbz_exporter(tree, dest, root):
356
tar_exporter(tree, dest, root, compression='bz2')
308
def tbz_exporter(tree, dest):
309
tar_exporter(tree, dest, compression='bz2')
357
310
exporters['tbz2'] = tbz_exporter