/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
70 by mbp at sourcefrog
Prepare for smart recursive add.
1
# Copyright (C) 2005 Canonical Ltd
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
2
#
1 by mbp at sourcefrog
import from baz patch-364
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
7
#
1 by mbp at sourcefrog
import from baz patch-364
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
12
#
1 by mbp at sourcefrog
import from baz patch-364
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
17
"""Tree classes, representing directory at point in time.
18
"""
19
849 by Martin Pool
- Put files inside an exported tarball into a top-level directory rather than
20
import os
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
21
from collections import deque
1196 by Martin Pool
- [WIP] retrieve historical texts from weaves
22
from cStringIO import StringIO
800 by Martin Pool
Merge John's import-speedup branch:
23
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
24
import bzrlib
2079.1.1 by John Arbash Meinel
Create a deprecated bzrlib.tree.RevisionTree() in favor of bzrlib.revisiontree.RevisionTree()
25
from bzrlib import (
26
    delta,
2012.1.8 by Aaron Bentley
Merge from bzr.dev
27
    osutils,
2079.1.1 by John Arbash Meinel
Create a deprecated bzrlib.tree.RevisionTree() in favor of bzrlib.revisiontree.RevisionTree()
28
    symbol_versioning,
29
    )
1852.11.1 by Robert Collins
Deprecate compare_trees and move its body to InterTree.changes_from.
30
from bzrlib.decorators import needs_read_lock
1196 by Martin Pool
- [WIP] retrieve historical texts from weaves
31
from bzrlib.errors import BzrError, BzrCheckError
1551.7.14 by Aaron Bentley
Use specified_file_ids instead of is_inside_any in compare_trees
32
from bzrlib import errors
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
33
from bzrlib.inventory import Inventory, InventoryFile
1852.8.2 by Robert Collins
Add InterTree class to represent InterTree operations.
34
from bzrlib.inter import InterObject
1732.1.1 by John Arbash Meinel
deprecating appendpath, it does exactly what pathjoin does
35
from bzrlib.osutils import fingerprint_file
1773.2.1 by Robert Collins
Teach all trees about unknowns, conflicts and get_parent_ids.
36
import bzrlib.revision
37
from bzrlib.trace import mutter, note
1 by mbp at sourcefrog
import from baz patch-364
38
1852.5.1 by Robert Collins
Deprecate EmptyTree in favour of using Repository.revision_tree.
39
558 by Martin Pool
- All top-level classes inherit from object
40
class Tree(object):
1 by mbp at sourcefrog
import from baz patch-364
41
    """Abstract file tree.
42
43
    There are several subclasses:
44
    
45
    * `WorkingTree` exists as files on disk editable by the user.
46
47
    * `RevisionTree` is a tree as recorded at some point in the past.
48
49
    Trees contain an `Inventory` object, and also know how to retrieve
50
    file texts mentioned in the inventory, either from a working
51
    directory or from a store.
52
53
    It is possible for trees to contain files that are not described
54
    in their inventory or vice versa; for this use `filenames()`.
55
56
    Trees can be compared, etc, regardless of whether they are working
57
    trees or versioned trees.
58
    """
59
    
1852.9.6 by Robert Collins
Merge the change from Tree.compare to Tree.changes_from.
60
    def changes_from(self, other, want_unchanged=False, specific_files=None,
2255.7.90 by Robert Collins
Add unversioned path reporting to TreeDelta.
61
        extra_trees=None, require_versioned=False, include_root=False,
62
        want_unversioned=False):
1852.8.8 by Robert Collins
change Tree.compare to Tree.changes_from - its better for the common case.
63
        """Return a TreeDelta of the changes from other to this tree.
1852.9.3 by Robert Collins
Convert the test_delta tests to intertree_implementation and workingtree_implementation tests as appropriate.
64
65
        :param other: A tree to compare with.
66
        :param specific_files: An optional list of file paths to restrict the
67
            comparison to. When mapping filenames to ids, all matches in all
68
            trees (including optional extra_trees) are used, and all children of
69
            matched directories are included.
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
70
        :param want_unchanged: An optional boolean requesting the inclusion of
71
            unchanged entries in the result.
72
        :param extra_trees: An optional list of additional trees to use when
73
            mapping the contents of specific_files (paths) to file_ids.
1852.9.5 by Robert Collins
Add tests for require_versioned to the InterTree.compare() test suite.
74
        :param require_versioned: An optional boolean (defaults to False). When
75
            supplied and True all the 'specific_files' must be versioned, or
76
            a PathsNotVersionedError will be thrown.
2255.7.90 by Robert Collins
Add unversioned path reporting to TreeDelta.
77
        :param want_unversioned: Scan for unversioned paths.
1852.9.3 by Robert Collins
Convert the test_delta tests to intertree_implementation and workingtree_implementation tests as appropriate.
78
1852.8.4 by Robert Collins
Hook InterTree into Tree.
79
        The comparison will be performed by an InterTree object looked up on 
80
        self and other.
81
        """
1852.8.8 by Robert Collins
change Tree.compare to Tree.changes_from - its better for the common case.
82
        # Martin observes that Tree.changes_from returns a TreeDelta and this
83
        # may confuse people, because the class name of the returned object is
84
        # a synonym of the object referenced in the method name.
1852.9.6 by Robert Collins
Merge the change from Tree.compare to Tree.changes_from.
85
        return InterTree.get(other, self).compare(
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
86
            want_unchanged=want_unchanged,
87
            specific_files=specific_files,
1852.9.5 by Robert Collins
Add tests for require_versioned to the InterTree.compare() test suite.
88
            extra_trees=extra_trees,
89
            require_versioned=require_versioned,
2255.7.90 by Robert Collins
Add unversioned path reporting to TreeDelta.
90
            include_root=include_root,
91
            want_unversioned=want_unversioned,
1852.9.5 by Robert Collins
Add tests for require_versioned to the InterTree.compare() test suite.
92
            )
2012.1.1 by Aaron Bentley
Implement change iterator
93
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
94
    def _iter_changes(self, from_tree, include_unchanged=False,
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
95
                     specific_files=None, pb=None, extra_trees=None,
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
96
                     require_versioned=True, want_unversioned=False):
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
97
        intertree = InterTree.get(from_tree, self)
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
98
        return intertree._iter_changes(include_unchanged, specific_files, pb,
2255.7.90 by Robert Collins
Add unversioned path reporting to TreeDelta.
99
            extra_trees, require_versioned, want_unversioned=want_unversioned)
1852.8.4 by Robert Collins
Hook InterTree into Tree.
100
    
1773.2.1 by Robert Collins
Teach all trees about unknowns, conflicts and get_parent_ids.
101
    def conflicts(self):
102
        """Get a list of the conflicts in the tree.
103
104
        Each conflict is an instance of bzrlib.conflicts.Conflict.
105
        """
106
        return []
107
2255.7.91 by Robert Collins
Move unknown detection in long status into the delta creation, saving a tree-scan.
108
    def extras(self):
109
        """For trees that can have unversioned files, return all such paths."""
110
        return []
111
1773.2.1 by Robert Collins
Teach all trees about unknowns, conflicts and get_parent_ids.
112
    def get_parent_ids(self):
113
        """Get the parent ids for this tree. 
114
115
        :return: a list of parent ids. [] is returned to indicate
116
        a tree with no parents.
117
        :raises: BzrError if the parents are not known.
118
        """
119
        raise NotImplementedError(self.get_parent_ids)
120
    
1 by mbp at sourcefrog
import from baz patch-364
121
    def has_filename(self, filename):
122
        """True if the tree has given filename."""
123
        raise NotImplementedError()
124
1185.12.39 by abentley
Propogated has_or_had_id to Tree
125
    def has_id(self, file_id):
2294.1.10 by John Arbash Meinel
Switch all apis over to utf8 file ids. All tests pass
126
        file_id = osutils.safe_file_id(file_id)
1185.12.39 by abentley
Propogated has_or_had_id to Tree
127
        return self.inventory.has_id(file_id)
128
1852.6.9 by Robert Collins
Add more test trees to the tree-implementations tests.
129
    __contains__ = has_id
130
1185.12.39 by abentley
Propogated has_or_had_id to Tree
131
    def has_or_had_id(self, file_id):
2294.1.10 by John Arbash Meinel
Switch all apis over to utf8 file ids. All tests pass
132
        file_id = osutils.safe_file_id(file_id)
1185.12.39 by abentley
Propogated has_or_had_id to Tree
133
        if file_id == self.inventory.root.file_id:
1185.12.38 by abentley
semi-broke merge
134
            return True
1 by mbp at sourcefrog
import from baz patch-364
135
        return self.inventory.has_id(file_id)
136
462 by Martin Pool
- New form 'file_id in tree' to check if the file is present
137
    def __iter__(self):
138
        return iter(self.inventory)
139
1 by mbp at sourcefrog
import from baz patch-364
140
    def id2path(self, file_id):
2294.1.10 by John Arbash Meinel
Switch all apis over to utf8 file ids. All tests pass
141
        file_id = osutils.safe_file_id(file_id)
1 by mbp at sourcefrog
import from baz patch-364
142
        return self.inventory.id2path(file_id)
143
1986.1.2 by Robert Collins
Various changes to allow non-workingtree specific tests to run entirely
144
    def is_control_filename(self, filename):
145
        """True if filename is the name of a control file in this tree.
146
        
147
        :param filename: A filename within the tree. This is a relative path
148
        from the root of this tree.
149
150
        This is true IF and ONLY IF the filename is part of the meta data
151
        that bzr controls in this tree. I.E. a random .bzr directory placed
152
        on disk will not be a control file for this tree.
153
        """
154
        return self.bzrdir.is_control_filename(filename)
155
2255.2.15 by Robert Collins
Dirstate - truncate state file fixing bug in saving a smaller file, get more tree_implementation tests passing.
156
    @needs_read_lock
1551.9.29 by Aaron Bentley
Optimize Tree._iter_changes with specific file_ids
157
    def iter_entries_by_dir(self, specific_file_ids=None):
1852.6.9 by Robert Collins
Add more test trees to the tree-implementations tests.
158
        """Walk the tree in 'by_dir' order.
159
160
        This will yield each entry in the tree as a (path, entry) tuple. The
161
        order that they are yielded is: the contents of a directory are 
162
        preceeded by the parent of a directory, and all the contents of a 
163
        directory are grouped together.
164
        """
1551.9.29 by Aaron Bentley
Optimize Tree._iter_changes with specific file_ids
165
        return self.inventory.iter_entries_by_dir(
166
            specific_file_ids=specific_file_ids)
1852.6.9 by Robert Collins
Add more test trees to the tree-implementations tests.
167
2100.3.27 by Aaron Bentley
Enable nested commits
168
    def iter_reference_entries(self):
169
        for path, entry in self.iter_entries_by_dir():
170
            if entry.kind == 'tree-reference':
171
                yield path, entry
172
1465 by Robert Collins
Bugfix the new pull --clobber to not generate spurious conflicts.
173
    def kind(self, file_id):
2255.2.159 by Martin Pool
reference-trees in dirstate pass all tests.
174
        raise NotImplementedError("Tree subclass %s must implement kind"
175
            % self.__class__.__name__)
1465 by Robert Collins
Bugfix the new pull --clobber to not generate spurious conflicts.
176
2100.3.20 by Aaron Bentley
Implement tree comparison for tree references
177
    def get_reference_revision(self, entry, path=None):
2255.2.158 by Martin Pool
Most of the integration of dirstate and subtree
178
        raise NotImplementedError("Tree subclass %s must implement "
179
                                  "get_reference_revision"
180
            % self.__class__.__name__)
2100.3.20 by Aaron Bentley
Implement tree comparison for tree references
181
2012.1.7 by Aaron Bentley
Get tree._iter_changed down to ~ 1 stat per file
182
    def _comparison_data(self, entry, path):
2012.1.15 by Aaron Bentley
Minor tweaks
183
        """Return a tuple of kind, executable, stat_value for a file.
184
185
        entry may be None if there is no inventory entry for the file, but
186
        path must always be supplied.
187
188
        kind is None if there is no file present (even if an inventory id is
189
        present).  executable is False for non-file entries.
190
        """
2012.1.7 by Aaron Bentley
Get tree._iter_changed down to ~ 1 stat per file
191
        raise NotImplementedError(self._comparison_data)
192
2255.2.10 by Robert Collins
Now all tests matching dirstate pass - added generation of inventories for parent trees.
193
    def _file_size(self, entry, stat_value):
2012.1.7 by Aaron Bentley
Get tree._iter_changed down to ~ 1 stat per file
194
        raise NotImplementedError(self._file_size)
195
1 by mbp at sourcefrog
import from baz patch-364
196
    def _get_inventory(self):
197
        return self._inventory
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
198
    
1986.1.2 by Robert Collins
Various changes to allow non-workingtree specific tests to run entirely
199
    def get_file(self, file_id):
200
        """Return a file object for the file file_id in the tree."""
201
        raise NotImplementedError(self.get_file)
2255.7.36 by John Arbash Meinel
All trees should implement get_file_mtime()
202
203
    def get_file_mtime(self, file_id, path=None):
204
        """Return the modification time for a file.
205
206
        :param file_id: The handle for this file.
207
        :param path: The path that this file can be found at.
208
            These must point to the same object.
209
        """
210
        raise NotImplementedError(self.get_file_mtime)
211
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
212
    def get_file_by_path(self, path):
213
        return self.get_file(self._inventory.path2id(path))
1 by mbp at sourcefrog
import from baz patch-364
214
2255.2.134 by John Arbash Meinel
Add a tree-test for get_symlink_target
215
    def get_symlink_target(self, file_id):
216
        """Get the target for a given file_id.
217
218
        It is assumed that the caller already knows that file_id is referencing
219
        a symlink.
220
        :param file_id: Handle for the symlink entry.
221
        :return: The path the symlink points to.
222
        """
223
        raise NotImplementedError(self.get_symlink_target)
224
1551.9.16 by Aaron Bentley
Implement Tree.annotate_iter for RevisionTree and WorkingTree
225
    def annotate_iter(self, file_id):
1551.9.18 by Aaron Bentley
Updates from review comments
226
        """Return an iterator of revision_id, line tuples
227
1551.9.16 by Aaron Bentley
Implement Tree.annotate_iter for RevisionTree and WorkingTree
228
        For working trees (and mutable trees in general), the special
229
        revision_id 'current:' will be used for lines that are new in this
230
        tree, e.g. uncommitted changes.
231
        :param file_id: The file to produce an annotated version from
232
        """
233
        raise NotImplementedError(self.annotate_iter)
234
1 by mbp at sourcefrog
import from baz patch-364
235
    inventory = property(_get_inventory,
236
                         doc="Inventory of this Tree")
237
238
    def _check_retrieved(self, ie, f):
1364 by Martin Pool
- remove extra verification of files retrieved from tree
239
        if not __debug__:
240
            return  
130 by mbp at sourcefrog
- fixup checks on retrieved files to cope with compression,
241
        fp = fingerprint_file(f)
242
        f.seek(0)
243
        
1963.2.6 by Robey Pointer
pychecker is on crack; go back to using 'is None'.
244
        if ie.text_size is not None:
131 by mbp at sourcefrog
check size and sha1 of files retrieved from the tree
245
            if ie.text_size != fp['size']:
694 by Martin Pool
- weed out all remaining calls to bailout() and remove the function
246
                raise BzrError("mismatched size for file %r in %r" % (ie.file_id, self._store),
1 by mbp at sourcefrog
import from baz patch-364
247
                        ["inventory expects %d bytes" % ie.text_size,
130 by mbp at sourcefrog
- fixup checks on retrieved files to cope with compression,
248
                         "file is actually %d bytes" % fp['size'],
1 by mbp at sourcefrog
import from baz patch-364
249
                         "store is probably damaged/corrupt"])
250
130 by mbp at sourcefrog
- fixup checks on retrieved files to cope with compression,
251
        if ie.text_sha1 != fp['sha1']:
694 by Martin Pool
- weed out all remaining calls to bailout() and remove the function
252
            raise BzrError("wrong SHA-1 for file %r in %r" % (ie.file_id, self._store),
1 by mbp at sourcefrog
import from baz patch-364
253
                    ["inventory expects %s" % ie.text_sha1,
130 by mbp at sourcefrog
- fixup checks on retrieved files to cope with compression,
254
                     "file is actually %s" % fp['sha1'],
1 by mbp at sourcefrog
import from baz patch-364
255
                     "store is probably damaged/corrupt"])
256
1986.1.2 by Robert Collins
Various changes to allow non-workingtree specific tests to run entirely
257
    def path2id(self, path):
258
        """Return the id for path in this tree."""
259
        return self._inventory.path2id(path)
1 by mbp at sourcefrog
import from baz patch-364
260
2255.2.101 by Robert Collins
Finish making Tree.ids2paths support the file_ids_across_trees api.
261
    def paths2ids(self, paths, trees=[], require_versioned=True):
2255.2.100 by Robert Collins
Create a paths2ids api to replace find_ids_across_trees, with tests.
262
        """Return all the ids that can be reached by walking from paths.
263
        
264
        Each path is looked up in each this tree and any extras provided in
265
        trees, and this is repeated recursively: the children in an extra tree
266
        of a directory that has been renamed under a provided path in this tree
267
        are all returned, even if none exist until a provided path in this
268
        tree, and vice versa.
2255.2.101 by Robert Collins
Finish making Tree.ids2paths support the file_ids_across_trees api.
269
270
        :param paths: An iterable of paths to start converting to ids from.
2255.2.104 by Robert Collins
Add WorkingTree4.paths2ids which is inventory-usage free if the trees being examined are in the dirstate.
271
            Alternatively, if paths is None, no ids should be calculated and None
272
            will be returned. This is offered to make calling the api unconditional
273
            for code that *might* take a list of files.
2255.2.101 by Robert Collins
Finish making Tree.ids2paths support the file_ids_across_trees api.
274
        :param trees: Additional trees to consider.
275
        :param require_versioned: If False, do not raise NotVersionedError if
276
            an element of paths is not versioned in this tree and all of trees.
2255.2.100 by Robert Collins
Create a paths2ids api to replace find_ids_across_trees, with tests.
277
        """
2255.2.105 by Robert Collins
Unfuck InterTree.compare which I broke with the paths2ids implementation.
278
        return find_ids_across_trees(paths, [self] + list(trees), require_versioned)
2255.2.100 by Robert Collins
Create a paths2ids api to replace find_ids_across_trees, with tests.
279
1196 by Martin Pool
- [WIP] retrieve historical texts from weaves
280
    def print_file(self, file_id):
281
        """Print file with id `file_id` to stdout."""
2294.1.10 by John Arbash Meinel
Switch all apis over to utf8 file ids. All tests pass
282
        file_id = osutils.safe_file_id(file_id)
176 by mbp at sourcefrog
New cat command contributed by janmar.
283
        import sys
1196 by Martin Pool
- [WIP] retrieve historical texts from weaves
284
        sys.stdout.write(self.get_file_text(file_id))
1543.1.1 by Denys Duchier
lock operations for trees - use them for diff
285
286
    def lock_read(self):
287
        pass
288
1908.11.1 by Robert Collins
Add a new method ``Tree.revision_tree`` which allows access to cached
289
    def revision_tree(self, revision_id):
290
        """Obtain a revision tree for the revision revision_id.
291
292
        The intention of this method is to allow access to possibly cached
293
        tree data. Implementors of this method should raise NoSuchRevision if
294
        the tree is not locally available, even if they could obtain the 
295
        tree via a repository or some other means. Callers are responsible 
296
        for finding the ultimate source for a revision tree.
297
298
        :param revision_id: The revision_id of the requested tree.
299
        :return: A Tree.
300
        :raises: NoSuchRevision if the tree cannot be obtained.
301
        """
302
        raise errors.NoSuchRevisionInTree(self, revision_id)
303
1773.2.1 by Robert Collins
Teach all trees about unknowns, conflicts and get_parent_ids.
304
    def unknowns(self):
305
        """What files are present in this tree and unknown.
306
        
307
        :return: an iterator over the unknown files.
308
        """
309
        return iter([])
310
1543.1.1 by Denys Duchier
lock operations for trees - use them for diff
311
    def unlock(self):
312
        pass
1658.1.9 by Martin Pool
Give an error for bzr diff on an nonexistent file (Malone #3619)
313
314
    def filter_unversioned_files(self, paths):
2255.7.62 by Robert Collins
Update the Tree.filter_unversioned_files docstring to reflect what the existing implementations actually do, and change the WorkingTree4 implementation to match a newly created test for it.
315
        """Filter out paths that are versioned.
1658.1.9 by Martin Pool
Give an error for bzr diff on an nonexistent file (Malone #3619)
316
317
        :return: set of paths.
318
        """
1658.1.10 by Martin Pool
diff on unversiond files should give an error (Malone #3619)
319
        # NB: we specifically *don't* call self.has_filename, because for
320
        # WorkingTrees that can indicate files that exist on disk but that 
321
        # are not versioned.
322
        pred = self.inventory.has_filename
323
        return set((p for p in paths if not pred(p)))
1852.7.1 by Robert Collins
Move RevisionTree out of tree.py.
324
1852.15.3 by Robert Collins
Add a first-cut Tree.walkdirs method.
325
    def walkdirs(self, prefix=""):
326
        """Walk the contents of this tree from path down.
327
328
        This yields all the data about the contents of a directory at a time.
329
        After each directory has been yielded, if the caller has mutated the
330
        list to exclude some directories, they are then not descended into.
331
        
332
        The data yielded is of the form:
1852.15.7 by Robert Collins
Start testing behaviour of unknowns in WorkingTree.walkdirs.
333
        ((directory-relpath, directory-path-from-root, directory-fileid),
1852.15.3 by Robert Collins
Add a first-cut Tree.walkdirs method.
334
        [(relpath, basename, kind, lstat, path_from_tree_root, file_id, 
1852.15.7 by Robert Collins
Start testing behaviour of unknowns in WorkingTree.walkdirs.
335
          versioned_kind), ...]),
336
         - directory-relpath is the containing dirs relpath from prefix
337
         - directory-path-from-root is the containing dirs path from /
338
         - directory-fileid is the id of the directory if it is versioned.
1852.15.3 by Robert Collins
Add a first-cut Tree.walkdirs method.
339
         - relpath is the relative path within the subtree being walked.
340
         - basename is the basename
341
         - kind is the kind of the file now. If unknonwn then the file is not
342
           present within the tree - but it may be recorded as versioned. See
343
           versioned_kind.
344
         - lstat is the stat data *if* the file was statted.
345
         - path_from_tree_root is the path from the root of the tree.
346
         - file_id is the file_id is the entry is versioned.
347
         - versioned_kind is the kind of the file as last recorded in the 
348
           versioning system. If 'unknown' the file is not versioned.
349
        One of 'kind' and 'versioned_kind' must not be 'unknown'.
350
351
        :param prefix: Start walking from prefix within the tree rather than
352
        at the root. This allows one to walk a subtree but get paths that are
353
        relative to a tree rooted higher up.
354
        :return: an iterator over the directory data.
355
        """
356
        raise NotImplementedError(self.walkdirs)
357
1852.7.1 by Robert Collins
Move RevisionTree out of tree.py.
358
1 by mbp at sourcefrog
import from baz patch-364
359
class EmptyTree(Tree):
1773.2.1 by Robert Collins
Teach all trees about unknowns, conflicts and get_parent_ids.
360
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
361
    def __init__(self):
1731.1.33 by Aaron Bentley
Revert no-special-root changes
362
        self._inventory = Inventory(root_id=None)
2079.1.1 by John Arbash Meinel
Create a deprecated bzrlib.tree.RevisionTree() in favor of bzrlib.revisiontree.RevisionTree()
363
        symbol_versioning.warn('EmptyTree is deprecated as of bzr 0.9 please'
364
                               ' use repository.revision_tree instead.',
365
                               DeprecationWarning, stacklevel=2)
1 by mbp at sourcefrog
import from baz patch-364
366
1773.2.1 by Robert Collins
Teach all trees about unknowns, conflicts and get_parent_ids.
367
    def get_parent_ids(self):
368
        return []
369
1092.2.6 by Robert Collins
symlink support updated to work
370
    def get_symlink_target(self, file_id):
371
        return None
372
1 by mbp at sourcefrog
import from baz patch-364
373
    def has_filename(self, filename):
374
        return False
375
1907.1.4 by Aaron Bentley
Restore RootEntry, but mark it deprecated, restore EmptyTree.kind
376
    def kind(self, file_id):
2294.1.10 by John Arbash Meinel
Switch all apis over to utf8 file ids. All tests pass
377
        file_id = osutils.safe_file_id(file_id)
1907.1.4 by Aaron Bentley
Restore RootEntry, but mark it deprecated, restore EmptyTree.kind
378
        assert self._inventory[file_id].kind == "directory"
379
        return "directory"
380
1731.1.56 by Aaron Bentley
Fix EmptyTree's default include_root
381
    def list_files(self, include_root=False):
1732.1.14 by John Arbash Meinel
Some speedups by not calling pathjoin()
382
        return iter([])
1 by mbp at sourcefrog
import from baz patch-364
383
    
974.1.12 by aaron.bentley at utoronto
Switched from text-id to hashcache for merge optimization
384
    def __contains__(self, file_id):
2294.1.10 by John Arbash Meinel
Switch all apis over to utf8 file ids. All tests pass
385
        file_id = osutils.safe_file_id(file_id)
1711.9.11 by John Arbash Meinel
change return foo in bar to return (foo in bar)
386
        return (file_id in self._inventory)
974.1.12 by aaron.bentley at utoronto
Switched from text-id to hashcache for merge optimization
387
2012.1.7 by Aaron Bentley
Get tree._iter_changed down to ~ 1 stat per file
388
    def get_file_sha1(self, file_id, path=None, stat_value=None):
974.1.14 by aaron.bentley at utoronto
Fixed bugs in merge optimization
389
        return None
390
391
1 by mbp at sourcefrog
import from baz patch-364
392
######################################################################
393
# diff
394
395
# TODO: Merge these two functions into a single one that can operate
396
# on either a whole tree or a set of files.
397
398
# TODO: Return the diff in order by filename, not by category or in
399
# random order.  Can probably be done by lock-stepping through the
400
# filenames from both trees.
401
402
403
def file_status(filename, old_tree, new_tree):
404
    """Return single-letter status, old and new names for a file.
405
406
    The complexity here is in deciding how to represent renames;
407
    many complex cases are possible.
408
    """
409
    old_inv = old_tree.inventory
410
    new_inv = new_tree.inventory
411
    new_id = new_inv.path2id(filename)
412
    old_id = old_inv.path2id(filename)
413
414
    if not new_id and not old_id:
415
        # easy: doesn't exist in either; not versioned at all
416
        if new_tree.is_ignored(filename):
417
            return 'I', None, None
418
        else:
419
            return '?', None, None
420
    elif new_id:
421
        # There is now a file of this name, great.
422
        pass
423
    else:
424
        # There is no longer a file of this name, but we can describe
425
        # what happened to the file that used to have
426
        # this name.  There are two possibilities: either it was
427
        # deleted entirely, or renamed.
428
        assert old_id
429
        if new_inv.has_id(old_id):
430
            return 'X', old_inv.id2path(old_id), new_inv.id2path(old_id)
431
        else:
432
            return 'D', old_inv.id2path(old_id), None
433
434
    # if the file_id is new in this revision, it is added
435
    if new_id and not old_inv.has_id(new_id):
436
        return 'A'
437
438
    # if there used to be a file of this name, but that ID has now
439
    # disappeared, it is deleted
440
    if old_id and not new_inv.has_id(old_id):
441
        return 'D'
442
443
    return 'wtf?'
444
445
    
446
164 by mbp at sourcefrog
new 'renames' command
447
def find_renames(old_inv, new_inv):
448
    for file_id in old_inv:
449
        if file_id not in new_inv:
450
            continue
451
        old_name = old_inv.id2path(file_id)
452
        new_name = new_inv.id2path(file_id)
453
        if old_name != new_name:
454
            yield (old_name, new_name)
455
            
678 by Martin Pool
- export to tarballs
456
1551.7.22 by Aaron Bentley
Changes from review
457
def find_ids_across_trees(filenames, trees, require_versioned=True):
458
    """Find the ids corresponding to specified filenames.
459
    
460
    All matches in all trees will be used, and all children of matched
461
    directories will be used.
462
1551.10.7 by Aaron Bentley
Use new-style output for status
463
    :param filenames: The filenames to find file_ids for (if None, returns
464
        None)
1551.7.22 by Aaron Bentley
Changes from review
465
    :param trees: The trees to find file_ids within
466
    :param require_versioned: if true, all specified filenames must occur in
467
    at least one tree.
468
    :return: a set of file ids for the specified filenames and their children.
469
    """
470
    if not filenames:
471
        return None
2255.2.82 by Robert Collins
various notes about find_ids_across_trees
472
    specified_path_ids = _find_ids_across_trees(filenames, trees,
473
        require_versioned)
474
    return _find_children_across_trees(specified_path_ids, trees)
475
476
477
def _find_ids_across_trees(filenames, trees, require_versioned):
1551.7.22 by Aaron Bentley
Changes from review
478
    """Find the ids corresponding to specified filenames.
479
    
2255.2.82 by Robert Collins
various notes about find_ids_across_trees
480
    All matches in all trees will be used, but subdirectories are not scanned.
1551.7.22 by Aaron Bentley
Changes from review
481
1551.7.14 by Aaron Bentley
Use specified_file_ids instead of is_inside_any in compare_trees
482
    :param filenames: The filenames to find file_ids for
483
    :param trees: The trees to find file_ids within
1551.7.16 by Aaron Bentley
Fix docs
484
    :param require_versioned: if true, all specified filenames must occur in
2255.2.82 by Robert Collins
various notes about find_ids_across_trees
485
        at least one tree.
486
    :return: a set of (path, file ids) for the specified filenames
1551.7.14 by Aaron Bentley
Use specified_file_ids instead of is_inside_any in compare_trees
487
    """
1551.7.17 by Aaron Bentley
Switch to PathsNotVersioned, accept extra_trees
488
    not_versioned = []
1551.7.18 by Aaron Bentley
Indentation and documentation fixes
489
    interesting_ids = set()
490
    for tree_path in filenames:
491
        not_found = True
492
        for tree in trees:
2255.2.82 by Robert Collins
various notes about find_ids_across_trees
493
            file_id = tree.path2id(tree_path)
1551.7.18 by Aaron Bentley
Indentation and documentation fixes
494
            if file_id is not None:
495
                interesting_ids.add(file_id)
496
                not_found = False
497
        if not_found:
498
            not_versioned.append(tree_path)
1551.7.22 by Aaron Bentley
Changes from review
499
    if len(not_versioned) > 0 and require_versioned:
500
        raise errors.PathsNotVersionedError(not_versioned)
501
    return interesting_ids
502
503
504
def _find_children_across_trees(specified_ids, trees):
505
    """Return a set including specified ids and their children
1551.7.18 by Aaron Bentley
Indentation and documentation fixes
506
    
1551.7.22 by Aaron Bentley
Changes from review
507
    All matches in all trees will be used.
508
509
    :param trees: The trees to find file_ids within
510
    :return: a set containing all specified ids and their children 
511
    """
512
    interesting_ids = set(specified_ids)
1551.7.18 by Aaron Bentley
Indentation and documentation fixes
513
    pending = interesting_ids
514
    # now handle children of interesting ids
515
    # we loop so that we handle all children of each id in both trees
516
    while len(pending) > 0:
517
        new_pending = set()
518
        for file_id in pending:
1551.7.14 by Aaron Bentley
Use specified_file_ids instead of is_inside_any in compare_trees
519
            for tree in trees:
2255.2.82 by Robert Collins
various notes about find_ids_across_trees
520
                if not tree.has_id(file_id):
1551.7.18 by Aaron Bentley
Indentation and documentation fixes
521
                    continue
522
                entry = tree.inventory[file_id]
523
                for child in getattr(entry, 'children', {}).itervalues():
524
                    if child.file_id not in interesting_ids:
525
                        new_pending.add(child.file_id)
526
        interesting_ids.update(new_pending)
527
        pending = new_pending
1551.7.14 by Aaron Bentley
Use specified_file_ids instead of is_inside_any in compare_trees
528
    return interesting_ids
1852.8.2 by Robert Collins
Add InterTree class to represent InterTree operations.
529
530
531
class InterTree(InterObject):
532
    """This class represents operations taking place between two Trees.
533
534
    Its instances have methods like 'compare' and contain references to the
535
    source and target trees these operations are to be carried out on.
536
537
    clients of bzrlib should not need to use InterTree directly, rather they
538
    should use the convenience methods on Tree such as 'Tree.compare()' which
539
    will pass through to InterTree as appropriate.
540
    """
541
1910.2.15 by Aaron Bentley
Back out inter.get changes, make optimizers an ordered list
542
    _optimisers = []
1852.8.2 by Robert Collins
Add InterTree class to represent InterTree operations.
543
1852.11.1 by Robert Collins
Deprecate compare_trees and move its body to InterTree.changes_from.
544
    @needs_read_lock
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
545
    def compare(self, want_unchanged=False, specific_files=None,
2255.7.90 by Robert Collins
Add unversioned path reporting to TreeDelta.
546
        extra_trees=None, require_versioned=False, include_root=False,
547
        want_unversioned=False):
1852.9.3 by Robert Collins
Convert the test_delta tests to intertree_implementation and workingtree_implementation tests as appropriate.
548
        """Return the changes from source to target.
1852.8.3 by Robert Collins
Implement an InterTreeTestProvider and a trivial test_compare test case.
549
550
        :return: A TreeDelta.
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
551
        :param specific_files: An optional list of file paths to restrict the
552
            comparison to. When mapping filenames to ids, all matches in all
553
            trees (including optional extra_trees) are used, and all children of
554
            matched directories are included.
555
        :param want_unchanged: An optional boolean requesting the inclusion of
556
            unchanged entries in the result.
557
        :param extra_trees: An optional list of additional trees to use when
558
            mapping the contents of specific_files (paths) to file_ids.
1852.9.5 by Robert Collins
Add tests for require_versioned to the InterTree.compare() test suite.
559
        :param require_versioned: An optional boolean (defaults to False). When
560
            supplied and True all the 'specific_files' must be versioned, or
561
            a PathsNotVersionedError will be thrown.
2255.7.90 by Robert Collins
Add unversioned path reporting to TreeDelta.
562
        :param want_unversioned: Scan for unversioned paths.
1852.8.3 by Robert Collins
Implement an InterTreeTestProvider and a trivial test_compare test case.
563
        """
2255.2.82 by Robert Collins
various notes about find_ids_across_trees
564
        # NB: show_status depends on being able to pass in non-versioned files
565
        # and report them as unknown
2255.2.105 by Robert Collins
Unfuck InterTree.compare which I broke with the paths2ids implementation.
566
        trees = (self.source,)
1852.11.1 by Robert Collins
Deprecate compare_trees and move its body to InterTree.changes_from.
567
        if extra_trees is not None:
568
            trees = trees + tuple(extra_trees)
2255.2.102 by Robert Collins
Use Tree.path2ids in status operations.
569
        # target is usually the newer tree:
2255.2.105 by Robert Collins
Unfuck InterTree.compare which I broke with the paths2ids implementation.
570
        specific_file_ids = self.target.paths2ids(specific_files, trees,
2255.2.102 by Robert Collins
Use Tree.path2ids in status operations.
571
            require_versioned=require_versioned)
1852.11.1 by Robert Collins
Deprecate compare_trees and move its body to InterTree.changes_from.
572
        if specific_files and not specific_file_ids:
573
            # All files are unversioned, so just return an empty delta
574
            # _compare_trees would think we want a complete delta
2255.7.90 by Robert Collins
Add unversioned path reporting to TreeDelta.
575
            result = delta.TreeDelta()
2255.7.91 by Robert Collins
Move unknown detection in long status into the delta creation, saving a tree-scan.
576
            fake_entry = InventoryFile('unused', 'unused', 'unused')
577
            result.unversioned = [(path, None,
578
                self.target._comparison_data(fake_entry, path)[0]) for path in
579
                specific_files]
2255.7.90 by Robert Collins
Add unversioned path reporting to TreeDelta.
580
            return result
1852.11.1 by Robert Collins
Deprecate compare_trees and move its body to InterTree.changes_from.
581
        return delta._compare_trees(self.source, self.target, want_unchanged,
2255.7.90 by Robert Collins
Add unversioned path reporting to TreeDelta.
582
            specific_files, include_root, extra_trees=extra_trees,
583
            want_unversioned=want_unversioned)
2012.1.1 by Aaron Bentley
Implement change iterator
584
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
585
    def _iter_changes(self, include_unchanged=False,
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
586
                      specific_files=None, pb=None, extra_trees=[],
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
587
                      require_versioned=True, want_unversioned=False):
2012.1.1 by Aaron Bentley
Implement change iterator
588
        """Generate an iterator of changes between trees.
589
590
        A tuple is returned:
591
        (file_id, path, changed_content, versioned, parent, name, kind,
592
         executable)
593
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
594
        Path is relative to the target tree.  changed_content is True if the
595
        file's content has changed.  This includes changes to its kind, and to
2012.1.3 by Aaron Bentley
Always generate tuples (because kind is always used, even when not different)
596
        a symlink's target.
2012.1.1 by Aaron Bentley
Implement change iterator
597
2012.1.15 by Aaron Bentley
Minor tweaks
598
        versioned, parent, name, kind, executable are tuples of (from, to).
599
        If a file is missing in a tree, its kind is None.
2012.1.1 by Aaron Bentley
Implement change iterator
600
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
601
        Iteration is done in parent-to-child order, relative to the target
602
        tree.
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
603
604
        There is no guarantee that all paths are in sorted order: the
605
        requirement to expand the search due to renames may result in children
606
        that should be found early being found late in the search, after
607
        lexically later results have been returned.
608
        :param require_versioned: Raise errors.PathsNotVersionedError if a
609
            path in the specific_files list is not versioned in one of
610
            source, target or extra_trees.
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
611
        :param want_unversioned: Should unversioned files be returned in the
612
            output. An unversioned file is defined as one with (False, False)
613
            for the versioned pair.
2012.1.1 by Aaron Bentley
Implement change iterator
614
        """
2255.2.158 by Martin Pool
Most of the integration of dirstate and subtree
615
        # this must return a sequence rather than a list so that it can hold a
616
        # read-lock for the whole time.
617
        #
618
        # TODO: this really only needs to lock the trees not the branches, so
619
        # could do with lock_tree_read() -- mbp 20070227
620
        result = []
2255.2.170 by Martin Pool
merge dirstate
621
        ## self.source.lock_read()
622
        ## self.target.lock_read()
623
        ## try:
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
624
        lookup_trees = [self.source]
625
        if extra_trees:
626
             lookup_trees.extend(extra_trees)
627
        specific_file_ids = self.target.paths2ids(specific_files,
628
            lookup_trees, require_versioned=require_versioned)
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
629
        if want_unversioned:
630
            all_unversioned = sorted([(p.split('/'), p) for p in self.target.extras()
631
                if not specific_files or
632
                    osutils.is_inside_any(specific_files, p)])
633
            all_unversioned = deque(all_unversioned)
634
        else:
635
            all_unversioned = deque()
2012.1.1 by Aaron Bentley
Implement change iterator
636
        to_paths = {}
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
637
        from_entries_by_dir = list(self.source.inventory.iter_entries_by_dir(
1551.9.29 by Aaron Bentley
Optimize Tree._iter_changes with specific file_ids
638
            specific_file_ids=specific_file_ids))
2012.1.16 by Aaron Bentley
Support progress bars in iter_changes
639
        from_data = dict((e.file_id, (p, e)) for p, e in from_entries_by_dir)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
640
        to_entries_by_dir = list(self.target.inventory.iter_entries_by_dir(
1551.9.31 by Aaron Bentley
Handle to_paths correctly when parent of file is not in specified_ids
641
            specific_file_ids=specific_file_ids))
1551.9.29 by Aaron Bentley
Optimize Tree._iter_changes with specific file_ids
642
        num_entries = len(from_entries_by_dir) + len(to_entries_by_dir)
2012.1.16 by Aaron Bentley
Support progress bars in iter_changes
643
        entry_count = 0
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
644
        # the unversioned path lookup only occurs on real trees - where there 
645
        # can be extras. So the fake_entry is solely used to look up
646
        # executable it values when execute is not supported.
647
        fake_entry = InventoryFile('unused', 'unused', 'unused')
2012.1.16 by Aaron Bentley
Support progress bars in iter_changes
648
        for to_path, to_entry in to_entries_by_dir:
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
649
            while all_unversioned and all_unversioned[0][0] < to_path.split('/'):
650
                unversioned_path = all_unversioned.popleft()
2255.2.158 by Martin Pool
Most of the integration of dirstate and subtree
651
                to_kind, to_executable, to_stat = \
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
652
                    self.target._comparison_data(fake_entry, unversioned_path[1])
653
                yield (None, unversioned_path[1], True, (False, False),
654
                    (None, None),
655
                    (None, unversioned_path[0][-1]),
656
                    (None, to_kind),
657
                    (None, to_executable))
2012.1.1 by Aaron Bentley
Implement change iterator
658
            file_id = to_entry.file_id
2012.1.7 by Aaron Bentley
Get tree._iter_changed down to ~ 1 stat per file
659
            to_paths[file_id] = to_path
2012.1.16 by Aaron Bentley
Support progress bars in iter_changes
660
            entry_count += 1
2012.1.1 by Aaron Bentley
Implement change iterator
661
            changed_content = False
2012.1.7 by Aaron Bentley
Get tree._iter_changed down to ~ 1 stat per file
662
            from_path, from_entry = from_data.get(file_id, (None, None))
663
            from_versioned = (from_entry is not None)
664
            if from_entry is not None:
665
                from_versioned = True
666
                from_name = from_entry.name
2012.1.1 by Aaron Bentley
Implement change iterator
667
                from_parent = from_entry.parent_id
2012.1.7 by Aaron Bentley
Get tree._iter_changed down to ~ 1 stat per file
668
                from_kind, from_executable, from_stat = \
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
669
                    self.source._comparison_data(from_entry, from_path)
1551.9.29 by Aaron Bentley
Optimize Tree._iter_changes with specific file_ids
670
                entry_count += 1
2012.1.1 by Aaron Bentley
Implement change iterator
671
            else:
2012.1.7 by Aaron Bentley
Get tree._iter_changed down to ~ 1 stat per file
672
                from_versioned = False
2012.1.1 by Aaron Bentley
Implement change iterator
673
                from_kind = None
674
                from_parent = None
675
                from_name = None
676
                from_executable = None
2012.1.7 by Aaron Bentley
Get tree._iter_changed down to ~ 1 stat per file
677
            versioned = (from_versioned, True)
678
            to_kind, to_executable, to_stat = \
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
679
                self.target._comparison_data(to_entry, to_path)
2012.1.3 by Aaron Bentley
Always generate tuples (because kind is always used, even when not different)
680
            kind = (from_kind, to_kind)
681
            if kind[0] != kind[1]:
2012.1.1 by Aaron Bentley
Implement change iterator
682
                changed_content = True
2012.1.2 by Aaron Bentley
reimplement compare_trees
683
            elif from_kind == 'file':
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
684
                from_size = self.source._file_size(from_entry, from_stat)
685
                to_size = self.target._file_size(to_entry, to_stat)
2012.1.7 by Aaron Bentley
Get tree._iter_changed down to ~ 1 stat per file
686
                if from_size != to_size:
687
                    changed_content = True
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
688
                elif (self.source.get_file_sha1(file_id, from_path, from_stat) !=
689
                    self.target.get_file_sha1(file_id, to_path, to_stat)):
2012.1.2 by Aaron Bentley
reimplement compare_trees
690
                    changed_content = True
691
            elif from_kind == 'symlink':
2255.7.2 by Robert Collins
Add a (currently) disabled test for unversioned paths in the target tree with _iter_changes.
692
                if (self.source.get_symlink_target(file_id) !=
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
693
                    self.target.get_symlink_target(file_id)):
2012.1.2 by Aaron Bentley
reimplement compare_trees
694
                    changed_content = True
2255.2.158 by Martin Pool
Most of the integration of dirstate and subtree
695
                elif from_kind == 'tree-reference':
696
                    if (self.source.get_reference_revision(from_entry, from_path)
697
                        != self.target.get_reference_revision(to_entry, to_path)):
698
                        changed_content = True 
2012.1.3 by Aaron Bentley
Always generate tuples (because kind is always used, even when not different)
699
            parent = (from_parent, to_entry.parent_id)
700
            name = (from_name, to_entry.name)
701
            executable = (from_executable, to_executable)
2012.1.16 by Aaron Bentley
Support progress bars in iter_changes
702
            if pb is not None:
703
                pb.update('comparing files', entry_count, num_entries)
2255.7.2 by Robert Collins
Add a (currently) disabled test for unversioned paths in the target tree with _iter_changes.
704
            if (changed_content is not False or versioned[0] != versioned[1]
2012.1.3 by Aaron Bentley
Always generate tuples (because kind is always used, even when not different)
705
                or parent[0] != parent[1] or name[0] != name[1] or 
706
                executable[0] != executable[1] or include_unchanged):
2012.1.7 by Aaron Bentley
Get tree._iter_changed down to ~ 1 stat per file
707
                yield (file_id, to_path, changed_content, versioned, parent,
2012.1.1 by Aaron Bentley
Implement change iterator
708
                       name, kind, executable)
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
709
        while all_unversioned:
710
            # yield any trailing unversioned paths
711
            unversioned_path = all_unversioned.popleft()
712
            to_kind, to_executable, to_stat = \
713
                self.target._comparison_data(fake_entry, unversioned_path[1])
714
            yield (None, unversioned_path[1], True, (False, False),
715
                (None, None),
716
                (None, unversioned_path[0][-1]),
717
                (None, to_kind),
718
                (None, to_executable))
2012.1.1 by Aaron Bentley
Implement change iterator
719
1551.9.31 by Aaron Bentley
Handle to_paths correctly when parent of file is not in specified_ids
720
        def get_to_path(from_entry):
721
            if from_entry.parent_id is None:
722
                to_path = ''
723
            else:
724
                if from_entry.parent_id not in to_paths:
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
725
                    get_to_path(self.source.inventory[from_entry.parent_id])
1551.9.31 by Aaron Bentley
Handle to_paths correctly when parent of file is not in specified_ids
726
                to_path = osutils.pathjoin(to_paths[from_entry.parent_id],
727
                                           from_entry.name)
728
            to_paths[from_entry.file_id] = to_path
729
            return to_path
730
2012.1.7 by Aaron Bentley
Get tree._iter_changed down to ~ 1 stat per file
731
        for path, from_entry in from_entries_by_dir:
2012.1.1 by Aaron Bentley
Implement change iterator
732
            file_id = from_entry.file_id
733
            if file_id in to_paths:
734
                continue
1551.9.31 by Aaron Bentley
Handle to_paths correctly when parent of file is not in specified_ids
735
            to_path = get_to_path(from_entry)
2012.1.16 by Aaron Bentley
Support progress bars in iter_changes
736
            entry_count += 1
737
            if pb is not None:
738
                pb.update('comparing files', entry_count, num_entries)
2012.1.1 by Aaron Bentley
Implement change iterator
739
            versioned = (True, False)
740
            parent = (from_entry.parent_id, None)
741
            name = (from_entry.name, None)
2012.1.7 by Aaron Bentley
Get tree._iter_changed down to ~ 1 stat per file
742
            from_kind, from_executable, stat_value = \
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
743
                self.source._comparison_data(from_entry, path)
2012.1.7 by Aaron Bentley
Get tree._iter_changed down to ~ 1 stat per file
744
            kind = (from_kind, None)
2012.1.2 by Aaron Bentley
reimplement compare_trees
745
            executable = (from_executable, None)
2012.1.1 by Aaron Bentley
Implement change iterator
746
            changed_content = True
747
            # the parent's path is necessarily known at this point.
748
            yield(file_id, to_path, changed_content, versioned, parent,
749
                  name, kind, executable)
2255.2.158 by Martin Pool
Most of the integration of dirstate and subtree
750
2012.1.8 by Aaron Bentley
Merge from bzr.dev
751
2079.1.1 by John Arbash Meinel
Create a deprecated bzrlib.tree.RevisionTree() in favor of bzrlib.revisiontree.RevisionTree()
752
# This was deprecated before 0.12, but did not have an official warning
753
@symbol_versioning.deprecated_function(symbol_versioning.zero_twelve)
754
def RevisionTree(*args, **kwargs):
755
    """RevisionTree has moved to bzrlib.revisiontree.RevisionTree()
756
757
    Accessing it as bzrlib.tree.RevisionTree has been deprecated as of
758
    bzr 0.12.
759
    """
760
    from bzrlib.revisiontree import RevisionTree as _RevisionTree
761
    return _RevisionTree(*args, **kwargs)
762
 
763