~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tree.py

  • Committer: Michael Ellerman
  • Date: 2006-02-28 14:45:51 UTC
  • mto: (1558.1.18 Aaron's integration)
  • mto: This revision was merged to the branch mainline in revision 1586.
  • Revision ID: michael@ellerman.id.au-20060228144551-3d9941ecde4a0b0a
Update contrib/pwk for -p1 diffs from bzr

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
from cStringIO import StringIO
22
22
 
23
23
import bzrlib
 
24
from bzrlib.trace import mutter, note
24
25
from bzrlib.errors import BzrError, BzrCheckError
25
 
from bzrlib import errors
26
26
from bzrlib.inventory import Inventory
27
 
from bzrlib.osutils import fingerprint_file
28
 
import bzrlib.revision
29
 
from bzrlib.trace import mutter, note
 
27
from bzrlib.osutils import appendpath, fingerprint_file
30
28
 
31
29
class Tree(object):
32
30
    """Abstract file tree.
50
48
    trees or versioned trees.
51
49
    """
52
50
    
53
 
    def conflicts(self):
54
 
        """Get a list of the conflicts in the tree.
55
 
 
56
 
        Each conflict is an instance of bzrlib.conflicts.Conflict.
57
 
        """
58
 
        return []
59
 
 
60
 
    def get_parent_ids(self):
61
 
        """Get the parent ids for this tree. 
62
 
 
63
 
        :return: a list of parent ids. [] is returned to indicate
64
 
        a tree with no parents.
65
 
        :raises: BzrError if the parents are not known.
66
 
        """
67
 
        raise NotImplementedError(self.get_parent_ids)
68
 
    
69
51
    def has_filename(self, filename):
70
52
        """True if the tree has given filename."""
71
53
        raise NotImplementedError()
126
108
    def lock_read(self):
127
109
        pass
128
110
 
129
 
    def unknowns(self):
130
 
        """What files are present in this tree and unknown.
131
 
        
132
 
        :return: an iterator over the unknown files.
133
 
        """
134
 
        return iter([])
135
 
 
136
111
    def unlock(self):
137
112
        pass
138
 
 
139
 
    def filter_unversioned_files(self, paths):
140
 
        """Filter out paths that are not versioned.
141
 
 
142
 
        :return: set of paths.
143
 
        """
144
 
        # NB: we specifically *don't* call self.has_filename, because for
145
 
        # WorkingTrees that can indicate files that exist on disk but that 
146
 
        # are not versioned.
147
 
        pred = self.inventory.has_filename
148
 
        return set((p for p in paths if not pred(p)))
149
113
        
150
114
        
151
115
class RevisionTree(Tree):
159
123
    """
160
124
    
161
125
    def __init__(self, branch, inv, revision_id):
162
 
        # for compatability the 'branch' parameter has not been renamed to 
163
 
        # repository at this point. However, we should change RevisionTree's
164
 
        # construction to always be via Repository and not via direct 
165
 
        # construction - this will mean that we can change the constructor
166
 
        # with much less chance of breaking client code.
167
 
        self._repository = branch
 
126
        self._branch = branch
168
127
        self._weave_store = branch.weave_store
169
128
        self._inventory = inv
170
129
        self._revision_id = revision_id
171
130
 
172
 
    def get_parent_ids(self):
173
 
        """See Tree.get_parent_ids.
174
 
 
175
 
        A RevisionTree's parents match the revision graph.
176
 
        """
177
 
        parent_ids = self._repository.get_revision(self._revision_id).parent_ids
178
 
        return parent_ids
179
 
        
180
 
    def get_revision_id(self):
181
 
        """Return the revision id associated with this tree."""
182
 
        return self._revision_id
183
 
 
184
131
    def get_weave(self, file_id):
 
132
        import bzrlib.transactions as transactions
185
133
        return self._weave_store.get_weave(file_id,
186
 
                self._repository.get_transaction())
 
134
                self._branch.get_transaction())
 
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())
187
140
 
188
141
    def get_file_lines(self, file_id):
189
142
        ie = self._inventory[file_id]
190
143
        weave = self.get_weave(file_id)
191
 
        return weave.get_lines(ie.revision)
 
144
        return weave.get(ie.revision)
192
145
 
193
146
    def get_file_text(self, file_id):
194
147
        return ''.join(self.get_file_lines(file_id))
199
152
    def get_file_size(self, file_id):
200
153
        return self._inventory[file_id].text_size
201
154
 
202
 
    def get_file_sha1(self, file_id, path=None):
 
155
    def get_file_sha1(self, file_id):
203
156
        ie = self._inventory[file_id]
204
157
        if ie.kind == "file":
205
158
            return ie.text_sha1
206
 
        return None
207
 
 
208
 
    def get_file_mtime(self, file_id, path=None):
209
 
        ie = self._inventory[file_id]
210
 
        revision = self._repository.get_revision(ie.revision)
211
 
        return revision.timestamp
212
 
 
213
 
    def is_executable(self, file_id, path=None):
 
159
 
 
160
    def is_executable(self, file_id):
214
161
        ie = self._inventory[file_id]
215
162
        if ie.kind != "file":
216
163
            return None 
232
179
        return self._inventory[file_id].kind
233
180
 
234
181
    def lock_read(self):
235
 
        self._repository.lock_read()
 
182
        self._branch.lock_read()
236
183
 
237
184
    def unlock(self):
238
 
        self._repository.unlock()
 
185
        self._branch.unlock()
239
186
 
240
187
 
241
188
class EmptyTree(Tree):
242
 
 
243
189
    def __init__(self):
244
190
        self._inventory = Inventory()
245
191
 
246
 
    def get_parent_ids(self):
247
 
        """See Tree.get_parent_ids.
248
 
 
249
 
        An EmptyTree always has NULL_REVISION as the only parent.
250
 
        """
251
 
        return []
252
 
 
253
192
    def get_symlink_target(self, file_id):
254
193
        return None
255
194
 
266
205
    def __contains__(self, file_id):
267
206
        return file_id in self._inventory
268
207
 
269
 
    def get_file_sha1(self, file_id, path=None):
 
208
    def get_file_sha1(self, file_id):
270
209
        assert self._inventory[file_id].kind == "root_directory"
271
210
        return None
272
211
 
336
275
            yield (old_name, new_name)
337
276
            
338
277
 
339
 
def find_ids_across_trees(filenames, trees, require_versioned=True):
340
 
    """Find the ids corresponding to specified filenames.
341
 
    
342
 
    All matches in all trees will be used, and all children of matched
343
 
    directories will be used.
344
 
 
345
 
    :param filenames: The filenames to find file_ids for
346
 
    :param trees: The trees to find file_ids within
347
 
    :param require_versioned: if true, all specified filenames must occur in
348
 
    at least one tree.
349
 
    :return: a set of file ids for the specified filenames and their children.
350
 
    """
351
 
    if not filenames:
352
 
        return None
353
 
    specified_ids = _find_filename_ids_across_trees(filenames, trees, 
354
 
                                                    require_versioned)
355
 
    return _find_children_across_trees(specified_ids, trees)
356
 
 
357
 
 
358
 
def _find_filename_ids_across_trees(filenames, trees, require_versioned):
359
 
    """Find the ids corresponding to specified filenames.
360
 
    
361
 
    All matches in all trees will be used.
362
 
 
363
 
    :param filenames: The filenames to find file_ids for
364
 
    :param trees: The trees to find file_ids within
365
 
    :param require_versioned: if true, all specified filenames must occur in
366
 
    at least one tree.
367
 
    :return: a set of file ids for the specified filenames
368
 
    """
369
 
    not_versioned = []
370
 
    interesting_ids = set()
371
 
    for tree_path in filenames:
372
 
        not_found = True
373
 
        for tree in trees:
374
 
            file_id = tree.inventory.path2id(tree_path)
375
 
            if file_id is not None:
376
 
                interesting_ids.add(file_id)
377
 
                not_found = False
378
 
        if not_found:
379
 
            not_versioned.append(tree_path)
380
 
    if len(not_versioned) > 0 and require_versioned:
381
 
        raise errors.PathsNotVersionedError(not_versioned)
382
 
    return interesting_ids
383
 
 
384
 
 
385
 
def _find_children_across_trees(specified_ids, trees):
386
 
    """Return a set including specified ids and their children
387
 
    
388
 
    All matches in all trees will be used.
389
 
 
390
 
    :param trees: The trees to find file_ids within
391
 
    :return: a set containing all specified ids and their children 
392
 
    """
393
 
    interesting_ids = set(specified_ids)
394
 
    pending = interesting_ids
395
 
    # now handle children of interesting ids
396
 
    # we loop so that we handle all children of each id in both trees
397
 
    while len(pending) > 0:
398
 
        new_pending = set()
399
 
        for file_id in pending:
400
 
            for tree in trees:
401
 
                if file_id not in tree:
402
 
                    continue
403
 
                entry = tree.inventory[file_id]
404
 
                for child in getattr(entry, 'children', {}).itervalues():
405
 
                    if child.file_id not in interesting_ids:
406
 
                        new_pending.add(child.file_id)
407
 
        interesting_ids.update(new_pending)
408
 
        pending = new_pending
409
 
    return interesting_ids
 
278