~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tree.py

  • Committer: Andrew Bennetts
  • Date: 2008-07-28 06:53:44 UTC
  • mfrom: (3581 +trunk)
  • mto: This revision was merged to the branch mainline in revision 3583.
  • Revision ID: andrew.bennetts@canonical.com-20080728065344-ocndjoycs903q6fz
Merge bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
 
24
24
import bzrlib
25
25
from bzrlib import (
 
26
    conflicts as _mod_conflicts,
26
27
    delta,
27
28
    osutils,
28
29
    revision as _mod_revision,
29
 
    conflicts as _mod_conflicts,
 
30
    rules,
30
31
    symbol_versioning,
31
32
    )
32
33
from bzrlib.decorators import needs_read_lock
176
177
    def iter_entries_by_dir(self, specific_file_ids=None):
177
178
        """Walk the tree in 'by_dir' order.
178
179
 
179
 
        This will yield each entry in the tree as a (path, entry) tuple. The
180
 
        order that they are yielded is: the contents of a directory are 
181
 
        preceeded by the parent of a directory, and all the contents of a 
182
 
        directory are grouped together.
 
180
        This will yield each entry in the tree as a (path, entry) tuple.
 
181
        The order that they are yielded is:
 
182
 
 
183
        Directories are walked in a depth-first lexicographical order,
 
184
        however, whenever a directory is reached, all of its direct child
 
185
        nodes are yielded in  lexicographical order before yielding the
 
186
        grandchildren.
 
187
 
 
188
        For example, in the tree::
 
189
 
 
190
           a/
 
191
             b/
 
192
               c
 
193
             d/
 
194
               e
 
195
           f/
 
196
             g
 
197
 
 
198
        The yield order (ignoring root) would be::
 
199
          a, f, a/b, a/d, a/b/c, a/d/e, f/g
183
200
        """
184
201
        return self.inventory.iter_entries_by_dir(
185
202
            specific_file_ids=specific_file_ids)
357
374
        return vf.plan_lca_merge(last_revision_a, last_revision_b,
358
375
                                 last_revision_base)
359
376
 
 
377
    def _iter_parent_trees(self):
 
378
        """Iterate through parent trees, defaulting to Tree.revision_tree."""
 
379
        for revision_id in self.get_parent_ids():
 
380
            try:
 
381
                yield self.revision_tree(revision_id)
 
382
            except errors.NoSuchRevisionInTree:
 
383
                yield self.repository.revision_tree(revision_id)
 
384
 
 
385
    @staticmethod
 
386
    def _file_revision(revision_tree, file_id):
 
387
        """Determine the revision associated with a file in a given tree."""
 
388
        revision_tree.lock_read()
 
389
        try:
 
390
            return revision_tree.inventory[file_id].revision
 
391
        finally:
 
392
            revision_tree.unlock()
 
393
 
360
394
    def _get_file_revision(self, file_id, vf, tree_revision):
361
395
        """Ensure that file_id, tree_revision is in vf to plan the merge."""
362
 
        def file_revision(revision_tree):
363
 
            revision_tree.lock_read()
364
 
            try:
365
 
                return revision_tree.inventory[file_id].revision
366
 
            finally:
367
 
                revision_tree.unlock()
368
 
 
369
 
        def iter_parent_trees():
370
 
            for revision_id in self.get_parent_ids():
371
 
                try:
372
 
                    yield self.revision_tree(revision_id)
373
 
                except:
374
 
                    yield self.repository.revision_tree(revision_id)
375
396
 
376
397
        if getattr(self, '_repository', None) is None:
377
398
            last_revision = tree_revision
378
 
            parent_keys = [(file_id, file_revision(t)) for t in
379
 
                iter_parent_trees()]
 
399
            parent_keys = [(file_id, self._file_revision(t, file_id)) for t in
 
400
                self._iter_parent_trees()]
380
401
            vf.add_lines((file_id, last_revision), parent_keys,
381
402
                         self.get_file(file_id).readlines())
382
403
            repo = self.branch.repository
383
404
            base_vf = repo.texts
384
405
        else:
385
 
            last_revision = file_revision(self)
 
406
            last_revision = self._file_revision(self, file_id)
386
407
            base_vf = self._repository.texts
387
408
        if base_vf not in vf.fallback_versionedfiles:
388
409
            vf.fallback_versionedfiles.append(base_vf)
512
533
        """
513
534
        raise NotImplementedError(self.walkdirs)
514
535
 
 
536
    def iter_search_rules(self, path_names, pref_names=None,
 
537
        _default_searcher=rules._per_user_searcher):
 
538
        """Find the preferences for filenames in a tree.
 
539
 
 
540
        :param path_names: an iterable of paths to find attributes for.
 
541
          Paths are given relative to the root of the tree.
 
542
        :param pref_names: the list of preferences to lookup - None for all
 
543
        :param _default_searcher: private parameter to assist testing - don't use
 
544
        :return: an iterator of tuple sequences, one per path-name.
 
545
          See _RulesSearcher.get_items for details on the tuple sequence.
 
546
        """
 
547
        searcher = self._get_rules_searcher(_default_searcher)
 
548
        if searcher is not None:
 
549
            if pref_names is not None:
 
550
                for path in path_names:
 
551
                    yield searcher.get_selected_items(path, pref_names)
 
552
            else:
 
553
                for path in path_names:
 
554
                    yield searcher.get_items(path)
 
555
 
 
556
    @needs_read_lock
 
557
    def _get_rules_searcher(self, default_searcher):
 
558
        """Get the RulesSearcher for this tree given the default one."""
 
559
        searcher = default_searcher
 
560
        file_id = self.path2id(rules.RULES_TREE_FILENAME)
 
561
        if file_id is not None:
 
562
            ini_file = self.get_file(file_id)
 
563
            searcher = rules._StackedRulesSearcher(
 
564
                [rules._IniBasedRulesSearcher(ini_file), default_searcher])
 
565
        return searcher
 
566
 
515
567
 
516
568
class EmptyTree(Tree):
517
569