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_file_text(self, file_id):
129
ie = self._inventory[file_id]
130
weave = self._weave_store.get_weave(file_id)
131
idx = weave.lookup(self._revision_id)
132
content = weave.get_text(idx)
133
if len(content) != ie.text_size:
134
raise BzrCheckError('mismatched size on revision %s of file %s: '
136
% (self._revision_id, file_id, len(content),
140
128
def get_file(self, file_id):
141
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)
143
135
def get_file_size(self, file_id):
144
136
return self._inventory[file_id].text_size
146
138
def get_file_sha1(self, file_id):
147
139
ie = self._inventory[file_id]
148
if ie.kind == "file":
151
142
def has_filename(self, filename):
152
143
return bool(self.inventory.path2id(filename))
168
159
if False: # just to make it a generator
171
def __contains__(self, file_id):
172
return file_id in self._inventory
174
def get_file_sha1(self, file_id):
175
assert self._inventory[file_id].kind == "root_directory"
181
164
######################################################################
247
230
######################################################################
250
def dir_exporter(tree, dest, root):
233
def dir_exporter(tree, dest):
251
234
"""Export this tree to a new directory.
253
236
`dest` should not exist, and will be created holding the
280
262
except ImportError:
283
def get_root_name(dest):
284
"""Get just the root name for a tarball.
286
>>> get_root_name('mytar.tar')
288
>>> get_root_name('mytar.tar.bz2')
290
>>> get_root_name('tar.tar.tar.tgz')
292
>>> get_root_name('bzr-0.0.5.tar.gz')
294
>>> get_root_name('a/long/path/mytar.tgz')
296
>>> get_root_name('../parent/../dir/other.tbz2')
299
endings = ['.tar', '.tar.gz', '.tgz', '.tar.bz2', '.tbz2']
300
dest = os.path.basename(dest)
302
if dest.endswith(end):
303
return dest[:-len(end)]
305
def tar_exporter(tree, dest, root, compression=None):
265
def tar_exporter(tree, dest, compression=None):
306
266
"""Export this tree to a new tar file.
308
268
`dest` will be created holding the contents of this tree; if it
309
269
already exists, it will be clobbered, like with "tar -c".
311
from time import time
313
272
compression = str(compression or '')
315
root = get_root_name(dest)
317
274
ball = tarfile.open(dest, 'w:' + compression)
318
275
except tarfile.CompressionError, e:
321
278
inv = tree.inventory
322
279
for dp, ie in inv.iter_entries():
323
280
mutter(" export {%s} kind %s to %s" % (ie.file_id, ie.kind, dest))
324
item = tarfile.TarInfo(os.path.join(root, dp))
281
item = tarfile.TarInfo(dp)
325
282
# TODO: would be cool to actually set it to the timestamp of the
326
283
# revision it was last changed
345
302
exporters['tar'] = tar_exporter
347
def tgz_exporter(tree, dest, root):
348
tar_exporter(tree, dest, root, compression='gz')
304
def tgz_exporter(tree, dest):
305
tar_exporter(tree, dest, compression='gz')
349
306
exporters['tgz'] = tgz_exporter
351
def tbz_exporter(tree, dest, root):
352
tar_exporter(tree, dest, root, compression='bz2')
308
def tbz_exporter(tree, dest):
309
tar_exporter(tree, dest, compression='bz2')
353
310
exporters['tbz2'] = tbz_exporter