~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tree.py

  • Committer: Robert Collins
  • Date: 2005-10-11 03:19:29 UTC
  • Revision ID: robertc@robertcollins.net-20051011031929-2d523107133c43be
further tuning of pull, do not do a local merge or fetch at all, if the remote branch is no newer than we are

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
 
29
32
class Tree(object):
30
33
    """Abstract file tree.
31
34
 
55
58
    def has_id(self, file_id):
56
59
        return self.inventory.has_id(file_id)
57
60
 
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
 
 
63
61
    __contains__ = has_id
64
62
 
65
63
    def __iter__(self):
68
66
    def id2path(self, file_id):
69
67
        return self.inventory.id2path(file_id)
70
68
 
71
 
    def kind(self, file_id):
72
 
        raise NotImplementedError("subclasses must implement kind")
73
 
 
74
69
    def _get_inventory(self):
75
70
        return self._inventory
76
71
    
104
99
        """Print file with id `file_id` to stdout."""
105
100
        import sys
106
101
        sys.stdout.write(self.get_file_text(file_id))
107
 
 
108
 
    def lock_read(self):
109
 
        pass
110
 
 
111
 
    def unlock(self):
112
 
        pass
113
 
        
114
 
        
 
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
 
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, branch, inv, revision_id):
126
 
        self._branch = branch
127
 
        self._weave_store = branch.weave_store
 
125
    def __init__(self, weave_store, inv, revision_id):
 
126
        self._weave_store = weave_store
128
127
        self._inventory = inv
129
128
        self._revision_id = revision_id
130
129
 
131
130
    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.
132
133
        import bzrlib.transactions as transactions
133
134
        return self._weave_store.get_weave(file_id,
134
 
                self._branch.get_transaction())
 
135
            transactions.PassThroughTransaction())
135
136
 
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())
140
137
 
141
138
    def get_file_lines(self, file_id):
142
139
        ie = self._inventory[file_id]
143
140
        weave = self.get_weave(file_id)
144
141
        return weave.get(ie.revision)
 
142
        
145
143
 
146
144
    def get_file_text(self, file_id):
147
145
        return ''.join(self.get_file_lines(file_id))
148
146
 
 
147
 
149
148
    def get_file(self, file_id):
150
149
        return StringIO(self.get_file_text(file_id))
151
150
 
158
157
            return ie.text_sha1
159
158
 
160
159
    def is_executable(self, file_id):
161
 
        ie = self._inventory[file_id]
162
 
        if ie.kind != "file":
163
 
            return None 
164
160
        return self._inventory[file_id].executable
165
161
 
166
162
    def has_filename(self, filename):
175
171
        ie = self._inventory[file_id]
176
172
        return ie.symlink_target;
177
173
 
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
 
 
187
174
 
188
175
class EmptyTree(Tree):
189
176
    def __init__(self):
195
182
    def has_filename(self, filename):
196
183
        return False
197
184
 
198
 
    def kind(self, file_id):
199
 
        assert self._inventory[file_id].kind == "root_directory"
200
 
        return "root_directory"
201
 
 
202
185
    def list_files(self):
203
186
        return iter([])
204
187
    
276
259
            
277
260
 
278
261
 
 
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