~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tree.py

  • Committer: Robert Collins
  • Date: 2005-10-18 13:11:57 UTC
  • mfrom: (1185.16.72) (0.2.1)
  • Revision ID: robertc@robertcollins.net-20051018131157-76a9970aa78e927e
Merged Martin.

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
from bzrlib.trace import mutter, note
25
25
from bzrlib.errors import BzrError, BzrCheckError
26
26
from bzrlib.inventory import Inventory
27
 
from bzrlib.osutils import pumpfile, appendpath, fingerprint_file
 
27
from bzrlib.osutils import appendpath, fingerprint_file
28
28
 
29
29
 
30
30
exporters = {}
58
58
    def has_id(self, file_id):
59
59
        return self.inventory.has_id(file_id)
60
60
 
 
61
    def has_or_had_id(self, file_id):
 
62
        if file_id == self.inventory.root.file_id:
 
63
            return True
 
64
        return self.inventory.has_id(file_id)
 
65
 
61
66
    __contains__ = has_id
62
67
 
63
68
    def __iter__(self):
76
81
                         doc="Inventory of this Tree")
77
82
 
78
83
    def _check_retrieved(self, ie, f):
 
84
        if not __debug__:
 
85
            return  
79
86
        fp = fingerprint_file(f)
80
87
        f.seek(0)
81
88
        
126
133
        self._revision_id = revision_id
127
134
 
128
135
    def get_weave(self, file_id):
129
 
        return self._weave_store.get_weave(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())
 
141
 
 
142
 
 
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)
130
147
        
131
148
 
132
149
    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: '
139
 
                                '%d vs %d bytes'
140
 
                                % (self._revision_id, file_id, len(content),
141
 
                                   ie.text_size))
142
 
        return content
 
150
        return ''.join(self.get_file_lines(file_id))
 
151
 
143
152
 
144
153
    def get_file(self, file_id):
145
154
        return StringIO(self.get_file_text(file_id))
152
161
        if ie.kind == "file":
153
162
            return ie.text_sha1
154
163
 
 
164
    def is_executable(self, file_id):
 
165
        ie = self._inventory[file_id]
 
166
        if ie.kind != "file":
 
167
            return None 
 
168
        return self._inventory[file_id].executable
 
169
 
155
170
    def has_filename(self, filename):
156
171
        return bool(self.inventory.path2id(filename))
157
172
 
158
173
    def list_files(self):
159
174
        # The only files returned by this are those from the version
160
175
        for path, entry in self.inventory.iter_entries():
161
 
            yield path, 'V', entry.kind, entry.file_id
162
 
 
 
176
            yield path, 'V', entry.kind, entry.file_id, entry
 
177
 
 
178
    def get_symlink_target(self, file_id):
 
179
        ie = self._inventory[file_id]
 
180
        return ie.symlink_target;
 
181
 
 
182
    def kind(self, file_id):
 
183
        return self._inventory[file_id].kind
163
184
 
164
185
class EmptyTree(Tree):
165
186
    def __init__(self):
166
187
        self._inventory = Inventory()
167
188
 
 
189
    def get_symlink_target(self, file_id):
 
190
        return None
 
191
 
168
192
    def has_filename(self, filename):
169
193
        return False
170
194
 
171
195
    def list_files(self):
172
 
        if False:  # just to make it a generator
173
 
            yield None
 
196
        return iter([])
174
197
    
175
198
    def __contains__(self, file_id):
176
199
        return file_id in self._inventory
180
203
        return None
181
204
 
182
205
 
183
 
 
184
 
 
185
206
######################################################################
186
207
# diff
187
208
 
268
289
    mutter('export version %r' % tree)
269
290
    inv = tree.inventory
270
291
    for dp, ie in inv.iter_entries():
271
 
        kind = ie.kind
272
 
        fullpath = appendpath(dest, dp)
273
 
        if kind == 'directory':
274
 
            os.mkdir(fullpath)
275
 
        elif kind == 'file':
276
 
            pumpfile(tree.get_file(ie.file_id), file(fullpath, 'wb'))
277
 
        else:
278
 
            raise BzrError("don't know how to export {%s} of kind %r" % (ie.file_id, kind))
279
 
        mutter("  export {%s} kind %s to %s" % (ie.file_id, kind, fullpath))
 
292
        ie.put_on_disk(dest, dp, tree)
 
293
 
280
294
exporters['dir'] = dir_exporter
281
295
 
282
296
try:
325
339
        inv = tree.inventory
326
340
        for dp, ie in inv.iter_entries():
327
341
            mutter("  export {%s} kind %s to %s" % (ie.file_id, ie.kind, dest))
328
 
            item = tarfile.TarInfo(os.path.join(root, dp))
329
 
            # TODO: would be cool to actually set it to the timestamp of the
330
 
            # revision it was last changed
331
 
            item.mtime = now
332
 
            if ie.kind == 'directory':
333
 
                item.type = tarfile.DIRTYPE
334
 
                fileobj = None
335
 
                item.name += '/'
336
 
                item.size = 0
337
 
                item.mode = 0755
338
 
            elif ie.kind == 'file':
339
 
                item.type = tarfile.REGTYPE
340
 
                fileobj = tree.get_file(ie.file_id)
341
 
                item.size = _find_file_size(fileobj)
342
 
                item.mode = 0644
343
 
            else:
344
 
                raise BzrError("don't know how to export {%s} of kind %r" %
345
 
                        (ie.file_id, ie.kind))
346
 
 
 
342
            item, fileobj = ie.get_tar_item(root, dp, now, tree)
347
343
            ball.addfile(item, fileobj)
348
344
        ball.close()
 
345
 
349
346
    exporters['tar'] = tar_exporter
350
347
 
351
348
    def tgz_exporter(tree, dest, root):
355
352
    def tbz_exporter(tree, dest, root):
356
353
        tar_exporter(tree, dest, root, compression='bz2')
357
354
    exporters['tbz2'] = tbz_exporter
358
 
 
359
 
 
360
 
def _find_file_size(fileobj):
361
 
    offset = fileobj.tell()
362
 
    try:
363
 
        fileobj.seek(0, 2)
364
 
        size = fileobj.tell()
365
 
    except TypeError:
366
 
        # gzip doesn't accept second argument to seek()
367
 
        fileobj.seek(0)
368
 
        size = 0
369
 
        while True:
370
 
            nread = len(fileobj.read())
371
 
            if nread == 0:
372
 
                break
373
 
            size += nread
374
 
    fileobj.seek(offset)
375
 
    return size