~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tree.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2006-02-18 02:33:47 UTC
  • mfrom: (1534.1.24 integration)
  • Revision ID: pqm@pqm.ubuntu.com-20060218023347-0952c65f668bfd68
Merge Robert Collins integration.

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
from bzrlib.inventory import Inventory
27
27
from bzrlib.osutils import appendpath, fingerprint_file
28
28
 
29
 
 
30
 
exporters = {}
31
 
 
32
29
class Tree(object):
33
30
    """Abstract file tree.
34
31
 
58
55
    def has_id(self, file_id):
59
56
        return self.inventory.has_id(file_id)
60
57
 
 
58
    def has_or_had_id(self, file_id):
 
59
        if file_id == self.inventory.root.file_id:
 
60
            return True
 
61
        return self.inventory.has_id(file_id)
 
62
 
61
63
    __contains__ = has_id
62
64
 
63
65
    def __iter__(self):
66
68
    def id2path(self, file_id):
67
69
        return self.inventory.id2path(file_id)
68
70
 
 
71
    def kind(self, file_id):
 
72
        raise NotImplementedError("subclasses must implement kind")
 
73
 
69
74
    def _get_inventory(self):
70
75
        return self._inventory
71
76
    
99
104
        """Print file with id `file_id` to stdout."""
100
105
        import sys
101
106
        sys.stdout.write(self.get_file_text(file_id))
102
 
        
103
 
        
104
 
    def export(self, dest, format='dir', root=None):
105
 
        """Export this tree."""
106
 
        try:
107
 
            exporter = exporters[format]
108
 
        except KeyError:
109
 
            from bzrlib.errors import BzrCommandError
110
 
            raise BzrCommandError("export format %r not supported" % format)
111
 
        exporter(self, dest, root)
112
 
 
113
 
 
114
 
 
 
107
 
 
108
    def lock_read(self):
 
109
        pass
 
110
 
 
111
    def unlock(self):
 
112
        pass
 
113
        
 
114
        
115
115
class RevisionTree(Tree):
116
116
    """Tree viewing a previous revision.
117
117
 
122
122
           or at least passing a description to the constructor.
123
123
    """
124
124
    
125
 
    def __init__(self, weave_store, inv, revision_id):
126
 
        self._weave_store = weave_store
 
125
    def __init__(self, branch, inv, revision_id):
 
126
        self._branch = branch
 
127
        self._weave_store = branch.weave_store
127
128
        self._inventory = inv
128
129
        self._revision_id = revision_id
129
130
 
130
131
    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
132
        import bzrlib.transactions as transactions
134
133
        return self._weave_store.get_weave(file_id,
135
 
            transactions.PassThroughTransaction())
 
134
                self._branch.get_transaction())
136
135
 
 
136
    def get_weave_prelude(self, file_id):
 
137
        import bzrlib.transactions as transactions
 
138
        return self._weave_store.get_weave_prelude(file_id,
 
139
                self._branch.get_transaction())
137
140
 
138
141
    def get_file_lines(self, file_id):
139
142
        ie = self._inventory[file_id]
140
143
        weave = self.get_weave(file_id)
141
144
        return weave.get(ie.revision)
142
 
        
143
145
 
144
146
    def get_file_text(self, file_id):
145
147
        return ''.join(self.get_file_lines(file_id))
146
148
 
147
 
 
148
149
    def get_file(self, file_id):
149
150
        return StringIO(self.get_file_text(file_id))
150
151
 
157
158
            return ie.text_sha1
158
159
 
159
160
    def is_executable(self, file_id):
 
161
        ie = self._inventory[file_id]
 
162
        if ie.kind != "file":
 
163
            return None 
160
164
        return self._inventory[file_id].executable
161
165
 
162
166
    def has_filename(self, filename):
171
175
        ie = self._inventory[file_id]
172
176
        return ie.symlink_target;
173
177
 
 
178
    def kind(self, file_id):
 
179
        return self._inventory[file_id].kind
 
180
 
 
181
    def lock_read(self):
 
182
        self._branch.lock_read()
 
183
 
 
184
    def unlock(self):
 
185
        self._branch.unlock()
 
186
 
174
187
 
175
188
class EmptyTree(Tree):
176
189
    def __init__(self):
182
195
    def has_filename(self, filename):
183
196
        return False
184
197
 
 
198
    def kind(self, file_id):
 
199
        assert self._inventory[file_id].kind == "root_directory"
 
200
        return "root_directory"
 
201
 
185
202
    def list_files(self):
186
203
        return iter([])
187
204
    
259
276
            
260
277
 
261
278
 
262
 
######################################################################
263
 
# export
264
 
 
265
 
def dir_exporter(tree, dest, root):
266
 
    """Export this tree to a new directory.
267
 
 
268
 
    `dest` should not exist, and will be created holding the
269
 
    contents of this tree.
270
 
 
271
 
    TODO: To handle subdirectories we need to create the
272
 
           directories first.
273
 
 
274
 
    :note: If the export fails, the destination directory will be
275
 
           left in a half-assed state.
276
 
    """
277
 
    import os
278
 
    os.mkdir(dest)
279
 
    mutter('export version %r' % tree)
280
 
    inv = tree.inventory
281
 
    for dp, ie in inv.iter_entries():
282
 
        ie.put_on_disk(dest, dp, tree)
283
 
 
284
 
exporters['dir'] = dir_exporter
285
 
 
286
 
try:
287
 
    import tarfile
288
 
except ImportError:
289
 
    pass
290
 
else:
291
 
    def get_root_name(dest):
292
 
        """Get just the root name for a tarball.
293
 
 
294
 
        >>> get_root_name('mytar.tar')
295
 
        'mytar'
296
 
        >>> get_root_name('mytar.tar.bz2')
297
 
        'mytar'
298
 
        >>> get_root_name('tar.tar.tar.tgz')
299
 
        'tar.tar.tar'
300
 
        >>> get_root_name('bzr-0.0.5.tar.gz')
301
 
        'bzr-0.0.5'
302
 
        >>> get_root_name('a/long/path/mytar.tgz')
303
 
        'mytar'
304
 
        >>> get_root_name('../parent/../dir/other.tbz2')
305
 
        'other'
306
 
        """
307
 
        endings = ['.tar', '.tar.gz', '.tgz', '.tar.bz2', '.tbz2']
308
 
        dest = os.path.basename(dest)
309
 
        for end in endings:
310
 
            if dest.endswith(end):
311
 
                return dest[:-len(end)]
312
 
 
313
 
    def tar_exporter(tree, dest, root, compression=None):
314
 
        """Export this tree to a new tar file.
315
 
 
316
 
        `dest` will be created holding the contents of this tree; if it
317
 
        already exists, it will be clobbered, like with "tar -c".
318
 
        """
319
 
        from time import time
320
 
        now = time()
321
 
        compression = str(compression or '')
322
 
        if root is None:
323
 
            root = get_root_name(dest)
324
 
        try:
325
 
            ball = tarfile.open(dest, 'w:' + compression)
326
 
        except tarfile.CompressionError, e:
327
 
            raise BzrError(str(e))
328
 
        mutter('export version %r' % tree)
329
 
        inv = tree.inventory
330
 
        for dp, ie in inv.iter_entries():
331
 
            mutter("  export {%s} kind %s to %s" % (ie.file_id, ie.kind, dest))
332
 
            item, fileobj = ie.get_tar_item(root, dp, now, tree)
333
 
            ball.addfile(item, fileobj)
334
 
        ball.close()
335
 
 
336
 
    exporters['tar'] = tar_exporter
337
 
 
338
 
    def tgz_exporter(tree, dest, root):
339
 
        tar_exporter(tree, dest, root, compression='gz')
340
 
    exporters['tgz'] = tgz_exporter
341
 
 
342
 
    def tbz_exporter(tree, dest, root):
343
 
        tar_exporter(tree, dest, root, compression='bz2')
344
 
    exporters['tbz2'] = tbz_exporter