~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tree.py

[merge] fix \t in commit messages

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):
66
71
    def id2path(self, file_id):
67
72
        return self.inventory.id2path(file_id)
68
73
 
 
74
    def kind(self, file_id):
 
75
        raise NotImplementedError("subclasses must implement kind")
 
76
 
69
77
    def _get_inventory(self):
70
78
        return self._inventory
71
79
    
76
84
                         doc="Inventory of this Tree")
77
85
 
78
86
    def _check_retrieved(self, ie, f):
 
87
        if not __debug__:
 
88
            return  
79
89
        fp = fingerprint_file(f)
80
90
        f.seek(0)
81
91
        
126
136
        self._revision_id = revision_id
127
137
 
128
138
    def get_weave(self, file_id):
129
 
        return self._weave_store.get_weave(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())
 
144
 
 
145
 
 
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)
130
150
        
131
151
 
132
152
    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
 
153
        return ''.join(self.get_file_lines(file_id))
 
154
 
143
155
 
144
156
    def get_file(self, file_id):
145
157
        return StringIO(self.get_file_text(file_id))
152
164
        if ie.kind == "file":
153
165
            return ie.text_sha1
154
166
 
 
167
    def is_executable(self, file_id):
 
168
        ie = self._inventory[file_id]
 
169
        if ie.kind != "file":
 
170
            return None 
 
171
        return self._inventory[file_id].executable
 
172
 
155
173
    def has_filename(self, filename):
156
174
        return bool(self.inventory.path2id(filename))
157
175
 
158
176
    def list_files(self):
159
177
        # The only files returned by this are those from the version
160
178
        for path, entry in self.inventory.iter_entries():
161
 
            yield path, 'V', entry.kind, entry.file_id
 
179
            yield path, 'V', entry.kind, entry.file_id, entry
 
180
 
 
181
    def get_symlink_target(self, file_id):
 
182
        ie = self._inventory[file_id]
 
183
        return ie.symlink_target;
 
184
 
 
185
    def kind(self, file_id):
 
186
        return self._inventory[file_id].kind
162
187
 
163
188
 
164
189
class EmptyTree(Tree):
165
190
    def __init__(self):
166
191
        self._inventory = Inventory()
167
192
 
 
193
    def get_symlink_target(self, file_id):
 
194
        return None
 
195
 
168
196
    def has_filename(self, filename):
169
197
        return False
170
198
 
 
199
    def kind(self, file_id):
 
200
        assert self._inventory[file_id].kind == "root_directory"
 
201
        return "root_directory"
 
202
 
171
203
    def list_files(self):
172
 
        if False:  # just to make it a generator
173
 
            yield None
 
204
        return iter([])
174
205
    
175
206
    def __contains__(self, file_id):
176
207
        return file_id in self._inventory
180
211
        return None
181
212
 
182
213
 
183
 
 
184
 
 
185
214
######################################################################
186
215
# diff
187
216
 
265
294
    """
266
295
    import os
267
296
    os.mkdir(dest)
268
 
    mutter('export version %r' % tree)
 
297
    mutter('export version %r', tree)
269
298
    inv = tree.inventory
270
299
    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))
 
300
        if dp != ".bzrignore":
 
301
            ie.put_on_disk(dest, dp, tree)
 
302
 
280
303
exporters['dir'] = dir_exporter
281
304
 
282
305
try:
321
344
            ball = tarfile.open(dest, 'w:' + compression)
322
345
        except tarfile.CompressionError, e:
323
346
            raise BzrError(str(e))
324
 
        mutter('export version %r' % tree)
 
347
        mutter('export version %r', tree)
325
348
        inv = tree.inventory
326
349
        for dp, ie in inv.iter_entries():
327
 
            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
 
 
347
 
            ball.addfile(item, fileobj)
 
350
            if dp != ".bzrignore":
 
351
                mutter("  export {%s} kind %s to %s" % (ie.file_id, ie.kind, dest))
 
352
                item, fileobj = ie.get_tar_item(root, dp, now, tree)
 
353
                ball.addfile(item, fileobj)
348
354
        ball.close()
 
355
 
349
356
    exporters['tar'] = tar_exporter
350
357
 
351
358
    def tgz_exporter(tree, dest, root):
355
362
    def tbz_exporter(tree, dest, root):
356
363
        tar_exporter(tree, dest, root, compression='bz2')
357
364
    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