/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.200.617 by Jelmer Vernooij
Add custom InterTree for use between git revision trees.
1
# Copyright (C) 2009 Jelmer Vernooij <jelmer@samba.org>
2
#
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.
7
#
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.
12
#
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
18
"""Git Trees."""
19
0.200.1594 by Jelmer Vernooij
Use absolute_import everywhere.
20
from __future__ import absolute_import
21
0.200.1780 by Jelmer Vernooij
Fix cross-object-store tree comparison.
22
from dulwich.object_store import (
23
    tree_lookup_path,
24
    OverlayObjectStore,
25
    )
0.264.3 by Jelmer Vernooij
Make RevisionTree inventoryless.
26
import stat
0.264.6 by Jelmer Vernooij
Implement custom GitRevisionTree.iter_entries_by_dir, GitRevisionTree.list_files.
27
import posixpath
0.264.3 by Jelmer Vernooij
Make RevisionTree inventoryless.
28
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
29
from ... import (
0.200.617 by Jelmer Vernooij
Add custom InterTree for use between git revision trees.
30
    delta,
31
    errors,
0.264.10 by Jelmer Vernooij
Yield inventory entries.
32
    osutils,
0.200.617 by Jelmer Vernooij
Add custom InterTree for use between git revision trees.
33
    revisiontree,
34
    tree,
35
    )
0.200.1731 by Jelmer Vernooij
Add support for checking untracked changes.
36
from ...revision import NULL_REVISION
0.200.1648 by Jelmer Vernooij
Fix compatibility with newer versions of breezy.
37
from ...bzr import (
38
    inventory,
39
    )
0.200.617 by Jelmer Vernooij
Add custom InterTree for use between git revision trees.
40
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
41
from .mapping import (
0.200.622 by Jelmer Vernooij
Implement InterTree.iter_changes() as well.
42
    mode_is_executable,
0.200.617 by Jelmer Vernooij
Add custom InterTree for use between git revision trees.
43
    mode_kind,
0.200.1731 by Jelmer Vernooij
Add support for checking untracked changes.
44
    GitFileIdMap,
0.287.2 by Jelmer Vernooij
Support empty trees in GitRevisionTree.
45
    default_mapping,
0.200.617 by Jelmer Vernooij
Add custom InterTree for use between git revision trees.
46
    )
47
48
49
class GitRevisionTree(revisiontree.RevisionTree):
0.200.959 by Jelmer Vernooij
Improve docstrings.
50
    """Revision tree implementation based on Git objects."""
0.200.617 by Jelmer Vernooij
Add custom InterTree for use between git revision trees.
51
52
    def __init__(self, repository, revision_id):
53
        self._revision_id = revision_id
54
        self._repository = repository
0.264.3 by Jelmer Vernooij
Make RevisionTree inventoryless.
55
        self.store = repository._git.object_store
0.200.617 by Jelmer Vernooij
Add custom InterTree for use between git revision trees.
56
        assert isinstance(revision_id, str)
0.200.1283 by Jelmer Vernooij
Provide Repository.get_file_graph() and Tree.get_file_revision().
57
        self.commit_id, self.mapping = repository.lookup_bzr_revision_id(revision_id)
0.200.1731 by Jelmer Vernooij
Add support for checking untracked changes.
58
        if revision_id == NULL_REVISION:
59
            self.tree = None
0.287.2 by Jelmer Vernooij
Support empty trees in GitRevisionTree.
60
            self.mapping = default_mapping
61
            self._fileid_map = GitFileIdMap(
0.287.4 by Jelmer Vernooij
Fix GitRevisionTree behaviour for null:
62
                {},
0.287.2 by Jelmer Vernooij
Support empty trees in GitRevisionTree.
63
                default_mapping)
0.200.1731 by Jelmer Vernooij
Add support for checking untracked changes.
64
        else:
65
            try:
66
                commit = self.store[self.commit_id]
67
            except KeyError, r:
68
                raise errors.NoSuchRevision(repository, revision_id)
69
            self.tree = commit.tree
70
            self._fileid_map = self.mapping.get_fileid_map(self.store.__getitem__, self.tree)
0.264.3 by Jelmer Vernooij
Make RevisionTree inventoryless.
71
0.285.1 by Jelmer Vernooij
Swap arguments for tree methods.
72
    def get_file_revision(self, path, file_id=None):
0.200.1283 by Jelmer Vernooij
Provide Repository.get_file_graph() and Tree.get_file_revision().
73
        change_scanner = self._repository._file_change_scanner
0.200.1757 by Jelmer Vernooij
Fix root tests.
74
        (path, commit_id) = change_scanner.find_last_change_revision(path,
75
            self.commit_id)
0.200.1283 by Jelmer Vernooij
Provide Repository.get_file_graph() and Tree.get_file_revision().
76
        return self._repository.lookup_foreign_revision_id(commit_id, self.mapping)
77
0.285.1 by Jelmer Vernooij
Swap arguments for tree methods.
78
    def get_file_mtime(self, path, file_id=None):
79
        revid = self.get_file_revision(path, file_id)
0.200.1283 by Jelmer Vernooij
Provide Repository.get_file_graph() and Tree.get_file_revision().
80
        try:
81
            rev = self._repository.get_revision(revid)
82
        except errors.NoSuchRevision:
83
            raise errors.FileTimestampUnavailable(path)
84
        return rev.timestamp
85
0.264.3 by Jelmer Vernooij
Make RevisionTree inventoryless.
86
    def id2path(self, file_id):
0.200.1712 by Jelmer Vernooij
Add file_id prefix.
87
        try:
88
            return self._fileid_map.lookup_path(file_id)
89
        except ValueError:
0.200.1714 by Jelmer Vernooij
Fix NoSuchId raising.
90
            raise errors.NoSuchId(self, file_id)
0.264.3 by Jelmer Vernooij
Make RevisionTree inventoryless.
91
92
    def path2id(self, path):
0.200.1328 by Jelmer Vernooij
More test fixes.
93
        if self.mapping.is_special_file(path):
94
            return None
95
        return self._fileid_map.lookup_file_id(path.encode('utf-8'))
0.200.617 by Jelmer Vernooij
Add custom InterTree for use between git revision trees.
96
0.200.1569 by Jelmer Vernooij
Implement GitRevisionTree.all_file_ids().
97
    def all_file_ids(self):
98
        return set(self._fileid_map.all_file_ids())
99
0.200.1724 by Jelmer Vernooij
Add GitRevisionTree.all_versioned_paths implementation.
100
    def all_versioned_paths(self):
101
        ret = set()
102
        todo = set([('', self.tree)])
103
        while todo:
104
            (path, tree_id) = todo.pop()
0.287.2 by Jelmer Vernooij
Support empty trees in GitRevisionTree.
105
            if tree_id is None:
106
                continue
0.200.1724 by Jelmer Vernooij
Add GitRevisionTree.all_versioned_paths implementation.
107
            tree = self.store[tree_id]
108
            for name, mode, hexsha in tree.iteritems():
109
                subpath = posixpath.join(path, name)
110
                if stat.S_ISDIR(mode):
111
                    todo.add((subpath, hexsha))
112
                else:
113
                    ret.add(subpath)
114
        return ret
115
0.200.1204 by Jelmer Vernooij
Implement GitRevisionTree.get_root_id().
116
    def get_root_id(self):
117
        return self.path2id("")
118
0.200.1208 by Jelmer Vernooij
Add GitWorkingTree.has_id and GitWorkingTree.has_or_had_id.
119
    def has_or_had_id(self, file_id):
120
        return self.has_id(file_id)
121
122
    def has_id(self, file_id):
123
        try:
124
            path = self.id2path(file_id)
125
        except errors.NoSuchId:
126
            return False
127
        return self.has_filename(path)
128
0.285.1 by Jelmer Vernooij
Swap arguments for tree methods.
129
    def is_executable(self, path, file_id=None):
0.200.1615 by Jelmer Vernooij
Implement GitRevisionTree.is_executable.:
130
        try:
131
            (mode, hexsha) = tree_lookup_path(self.store.__getitem__, self.tree,
132
                path)
133
        except KeyError:
0.285.1 by Jelmer Vernooij
Swap arguments for tree methods.
134
            raise errors.NoSuchId(self, path)
0.200.1615 by Jelmer Vernooij
Implement GitRevisionTree.is_executable.:
135
        if mode is None:
136
            # the tree root is a directory
137
            return False
138
        return mode_is_executable(mode)
139
0.285.1 by Jelmer Vernooij
Swap arguments for tree methods.
140
    def kind(self, path, file_id=None):
0.287.4 by Jelmer Vernooij
Fix GitRevisionTree behaviour for null:
141
        if self.tree is None:
0.287.5 by Jelmer Vernooij
Fix root handling.
142
            raise errors.NoSuchFile(path)
0.200.1283 by Jelmer Vernooij
Provide Repository.get_file_graph() and Tree.get_file_revision().
143
        try:
144
            (mode, hexsha) = tree_lookup_path(self.store.__getitem__, self.tree,
145
                path)
146
        except KeyError:
0.287.5 by Jelmer Vernooij
Fix root handling.
147
            raise errors.NoSuchFile(path)
0.200.1253 by Jelmer Vernooij
Fix Tree.kind(TREE_ROOT).
148
        if mode is None:
149
            # the tree root is a directory
150
            return "directory"
0.200.1241 by Jelmer Vernooij
Implement GitRevisionTree.kind.
151
        return mode_kind(mode)
152
0.200.1197 by Jelmer Vernooij
Implement GitRevisionTree.has_filename.
153
    def has_filename(self, path):
0.287.4 by Jelmer Vernooij
Fix GitRevisionTree behaviour for null:
154
        if self.tree is None:
155
            return False
0.200.1197 by Jelmer Vernooij
Implement GitRevisionTree.has_filename.
156
        try:
157
            tree_lookup_path(self.store.__getitem__, self.tree,
158
                path.encode("utf-8"))
159
        except KeyError:
160
            return False
161
        else:
162
            return True
163
0.264.6 by Jelmer Vernooij
Implement custom GitRevisionTree.iter_entries_by_dir, GitRevisionTree.list_files.
164
    def list_files(self, include_root=False, from_dir=None, recursive=True):
165
        if from_dir is None:
0.200.1197 by Jelmer Vernooij
Implement GitRevisionTree.has_filename.
166
            from_dir = u""
0.287.2 by Jelmer Vernooij
Support empty trees in GitRevisionTree.
167
        if self.tree is None:
168
            return
0.200.1197 by Jelmer Vernooij
Implement GitRevisionTree.has_filename.
169
        (mode, hexsha) = tree_lookup_path(self.store.__getitem__, self.tree,
170
            from_dir.encode("utf-8"))
0.264.9 by Jelmer Vernooij
Implement basic GitWorkingTree.iter_entries_by_dir.
171
        if mode is None: # Root
0.264.10 by Jelmer Vernooij
Yield inventory entries.
172
            root_ie = self._get_dir_ie("", None)
0.264.9 by Jelmer Vernooij
Implement basic GitWorkingTree.iter_entries_by_dir.
173
        else:
0.264.10 by Jelmer Vernooij
Yield inventory entries.
174
            parent_path = posixpath.dirname(from_dir.encode("utf-8"))
0.200.1328 by Jelmer Vernooij
More test fixes.
175
            parent_id = self._fileid_map.lookup_file_id(parent_path)
0.264.10 by Jelmer Vernooij
Yield inventory entries.
176
            if mode_kind(mode) == 'directory':
177
                root_ie = self._get_dir_ie(from_dir.encode("utf-8"), parent_id)
178
            else:
179
                root_ie = self._get_file_ie(from_dir.encode("utf-8"),
180
                    posixpath.basename(from_dir), mode, hexsha)
181
        if from_dir != "" or include_root:
182
            yield (from_dir, "V", root_ie.kind, root_ie.file_id, root_ie)
0.264.6 by Jelmer Vernooij
Implement custom GitRevisionTree.iter_entries_by_dir, GitRevisionTree.list_files.
183
        todo = set()
0.264.10 by Jelmer Vernooij
Yield inventory entries.
184
        if root_ie.kind == 'directory':
185
            todo.add((from_dir.encode("utf-8"), hexsha, root_ie.file_id))
0.264.6 by Jelmer Vernooij
Implement custom GitRevisionTree.iter_entries_by_dir, GitRevisionTree.list_files.
186
        while todo:
0.264.10 by Jelmer Vernooij
Yield inventory entries.
187
            (path, hexsha, parent_id) = todo.pop()
0.264.6 by Jelmer Vernooij
Implement custom GitRevisionTree.iter_entries_by_dir, GitRevisionTree.list_files.
188
            tree = self.store[hexsha]
189
            for name, mode, hexsha in tree.iteritems():
0.200.1328 by Jelmer Vernooij
More test fixes.
190
                if self.mapping.is_special_file(name):
191
                    continue
0.264.6 by Jelmer Vernooij
Implement custom GitRevisionTree.iter_entries_by_dir, GitRevisionTree.list_files.
192
                child_path = posixpath.join(path, name)
0.264.10 by Jelmer Vernooij
Yield inventory entries.
193
                if stat.S_ISDIR(mode):
194
                    ie = self._get_dir_ie(child_path, parent_id)
195
                    if recursive:
196
                        todo.add((child_path, hexsha, ie.file_id))
197
                else:
198
                    ie = self._get_file_ie(child_path, name, mode, hexsha, parent_id)
199
                yield child_path, "V", ie.kind, ie.file_id, ie
200
201
    def _get_file_ie(self, path, name, mode, hexsha, parent_id):
202
        kind = mode_kind(mode)
0.200.1328 by Jelmer Vernooij
More test fixes.
203
        file_id = self._fileid_map.lookup_file_id(path)
0.264.10 by Jelmer Vernooij
Yield inventory entries.
204
        ie = inventory.entry_factory[kind](file_id, name.decode("utf-8"), parent_id)
205
        if kind == 'symlink':
206
            ie.symlink_target = self.store[hexsha].data
0.200.1401 by Jelmer Vernooij
Cope with submodules in working trees.
207
        elif kind == 'tree-reference':
208
            ie.reference_revision = self.mapping.revision_id_foreign_to_bzr(hexsha)
0.264.10 by Jelmer Vernooij
Yield inventory entries.
209
        else:
210
            data = self.store[hexsha].data
211
            ie.text_sha1 = osutils.sha_string(data)
212
            ie.text_size = len(data)
213
            ie.executable = mode_is_executable(mode)
214
        return ie
215
216
    def _get_dir_ie(self, path, parent_id):
0.200.1328 by Jelmer Vernooij
More test fixes.
217
        file_id = self._fileid_map.lookup_file_id(path)
0.287.6 by Jelmer Vernooij
Fix some more tests.
218
        ie = inventory.InventoryDirectory(file_id,
0.264.10 by Jelmer Vernooij
Yield inventory entries.
219
            posixpath.basename(path).decode("utf-8"), parent_id)
0.287.6 by Jelmer Vernooij
Fix some more tests.
220
        ie.revision = self.get_file_revision(path)
221
        return ie
0.264.6 by Jelmer Vernooij
Implement custom GitRevisionTree.iter_entries_by_dir, GitRevisionTree.list_files.
222
0.200.1744 by Jelmer Vernooij
Implement GitRevisionTree.iter_children.
223
    def iter_children(self, file_id):
224
        path = self._fileid_map.lookup_path(file_id)
225
        mode, tree_sha = tree_lookup_path(self.store.__getitem__, self.tree, path)
226
        if stat.S_ISDIR(mode):
227
            for name, mode, hexsha  in self.store[tree_sha].iteritems():
228
                yield self._fileid_map.lookup_file_id(posixpath.join(path, name))
229
0.264.6 by Jelmer Vernooij
Implement custom GitRevisionTree.iter_entries_by_dir, GitRevisionTree.list_files.
230
    def iter_entries_by_dir(self, specific_file_ids=None, yield_parents=False):
0.287.4 by Jelmer Vernooij
Fix GitRevisionTree behaviour for null:
231
        if self.tree is None:
232
            return
0.200.1285 by Jelmer Vernooij
Support specific_file_ids argument to Tree.iter_entries_by_dir.
233
        # FIXME: Support yield parents
0.264.6 by Jelmer Vernooij
Implement custom GitRevisionTree.iter_entries_by_dir, GitRevisionTree.list_files.
234
        if specific_file_ids is not None:
0.200.1285 by Jelmer Vernooij
Support specific_file_ids argument to Tree.iter_entries_by_dir.
235
            specific_paths = [self.id2path(file_id) for file_id in specific_file_ids]
236
            if specific_paths in ([u""], []):
237
                specific_paths = None
238
            else:
239
                specific_paths = set(specific_paths)
240
        else:
241
            specific_paths = None
0.264.10 by Jelmer Vernooij
Yield inventory entries.
242
        todo = set([("", self.tree, None)])
0.264.6 by Jelmer Vernooij
Implement custom GitRevisionTree.iter_entries_by_dir, GitRevisionTree.list_files.
243
        while todo:
0.264.10 by Jelmer Vernooij
Yield inventory entries.
244
            path, tree_sha, parent_id = todo.pop()
245
            ie = self._get_dir_ie(path, parent_id)
0.200.1285 by Jelmer Vernooij
Support specific_file_ids argument to Tree.iter_entries_by_dir.
246
            if specific_paths is None or path in specific_paths:
0.200.1715 by Jelmer Vernooij
Fix some more tests.
247
                yield path.decode("utf-8"), ie
0.264.6 by Jelmer Vernooij
Implement custom GitRevisionTree.iter_entries_by_dir, GitRevisionTree.list_files.
248
            tree = self.store[tree_sha]
249
            for name, mode, hexsha  in tree.iteritems():
0.200.1328 by Jelmer Vernooij
More test fixes.
250
                if self.mapping.is_special_file(name):
251
                    continue
0.264.6 by Jelmer Vernooij
Implement custom GitRevisionTree.iter_entries_by_dir, GitRevisionTree.list_files.
252
                child_path = posixpath.join(path, name)
253
                if stat.S_ISDIR(mode):
0.200.1285 by Jelmer Vernooij
Support specific_file_ids argument to Tree.iter_entries_by_dir.
254
                    if (specific_paths is None or
255
                        any(filter(lambda p: p.startswith(child_path), specific_paths))):
256
                        todo.add((child_path, hexsha, ie.file_id))
257
                elif specific_paths is None or child_path in specific_paths:
0.200.1715 by Jelmer Vernooij
Fix some more tests.
258
                    yield (child_path.decode("utf-8"),
0.200.1307 by Jelmer Vernooij
Formatting fixes, specify path to a couple more functions.
259
                            self._get_file_ie(child_path, name, mode, hexsha,
0.200.1285 by Jelmer Vernooij
Support specific_file_ids argument to Tree.iter_entries_by_dir.
260
                           ie.file_id))
0.264.6 by Jelmer Vernooij
Implement custom GitRevisionTree.iter_entries_by_dir, GitRevisionTree.list_files.
261
0.200.617 by Jelmer Vernooij
Add custom InterTree for use between git revision trees.
262
    def get_revision_id(self):
0.200.959 by Jelmer Vernooij
Improve docstrings.
263
        """See RevisionTree.get_revision_id."""
0.200.617 by Jelmer Vernooij
Add custom InterTree for use between git revision trees.
264
        return self._revision_id
265
0.285.1 by Jelmer Vernooij
Swap arguments for tree methods.
266
    def get_file_sha1(self, path, file_id=None, stat_value=None):
0.287.6 by Jelmer Vernooij
Fix some more tests.
267
        if self.tree is None:
268
            raise errors.NoSuchFile(path)
0.285.1 by Jelmer Vernooij
Swap arguments for tree methods.
269
        return osutils.sha_string(self.get_file_text(path, file_id))
0.200.1255 by Jelmer Vernooij
Implement GitRevisionTree.get_file_sha1.
270
0.285.1 by Jelmer Vernooij
Swap arguments for tree methods.
271
    def get_file_verifier(self, path, file_id=None, stat_value=None):
0.200.1302 by Jelmer Vernooij
Significantly improve performance of WorkingTree.extras().
272
        (mode, hexsha) = tree_lookup_path(self.store.__getitem__, self.tree,
273
            path)
274
        return ("GIT", hexsha)
275
0.285.1 by Jelmer Vernooij
Swap arguments for tree methods.
276
    def get_file_text(self, path, file_id=None):
0.200.959 by Jelmer Vernooij
Improve docstrings.
277
        """See RevisionTree.get_file_text."""
0.287.5 by Jelmer Vernooij
Fix root handling.
278
        if self.tree is None:
279
            raise errors.NoSuchFile(path)
0.200.1302 by Jelmer Vernooij
Significantly improve performance of WorkingTree.extras().
280
        (mode, hexsha) = tree_lookup_path(self.store.__getitem__, self.tree, path)
0.264.3 by Jelmer Vernooij
Make RevisionTree inventoryless.
281
        if stat.S_ISREG(mode):
282
            return self.store[hexsha].data
0.200.617 by Jelmer Vernooij
Add custom InterTree for use between git revision trees.
283
        else:
0.200.664 by Jelmer Vernooij
Support submodules during fetch.
284
            return ""
0.200.617 by Jelmer Vernooij
Add custom InterTree for use between git revision trees.
285
0.285.1 by Jelmer Vernooij
Swap arguments for tree methods.
286
    def get_symlink_target(self, path, file_id=None):
0.200.1466 by Jelmer Vernooij
Implement GitRevisionTree.get_symlink_target.
287
        """See RevisionTree.get_symlink_target."""
0.200.1701 by Jelmer Vernooij
Fix a few tests.
288
        (mode, hexsha) = tree_lookup_path(self.store.__getitem__, self.tree, path.encode('utf-8'))
0.200.1466 by Jelmer Vernooij
Implement GitRevisionTree.get_symlink_target.
289
        if stat.S_ISLNK(mode):
0.200.1701 by Jelmer Vernooij
Fix a few tests.
290
            return self.store[hexsha].data.decode('utf-8')
0.200.1466 by Jelmer Vernooij
Implement GitRevisionTree.get_symlink_target.
291
        else:
292
            return None
293
0.264.10 by Jelmer Vernooij
Yield inventory entries.
294
    def _comparison_data(self, entry, path):
295
        if entry is None:
296
            return None, False, None
297
        return entry.kind, entry.executable, None
298
0.200.1568 by Jelmer Vernooij
Implement GitRevisionTree.path_content_summary.
299
    def path_content_summary(self, path):
300
        """See Tree.path_content_summary."""
301
        try:
302
            (mode, hexsha) = tree_lookup_path(self.store.__getitem__, self.tree, path)
303
        except KeyError:
304
            return ('missing', None, None, None)
305
        kind = mode_kind(mode)
306
        if kind == 'file':
307
            executable = mode_is_executable(mode)
308
            contents = self.store[hexsha].data
309
            return (kind, len(contents), executable, osutils.sha_string(contents))
310
        elif kind == 'symlink':
311
            return (kind, None, None, self.store[hexsha].data)
312
        else:
313
            return (kind, None, None, None)
314
0.200.617 by Jelmer Vernooij
Add custom InterTree for use between git revision trees.
315
0.252.43 by Jelmer Vernooij
Some refactoring, support proper file ids in revision deltas.
316
def tree_delta_from_git_changes(changes, mapping,
0.200.1743 by Jelmer Vernooij
Fix some revision delta filtering.
317
        (old_fileid_map, new_fileid_map), specific_files=None,
0.287.5 by Jelmer Vernooij
Fix root handling.
318
        require_versioned=False, include_root=False):
0.200.617 by Jelmer Vernooij
Add custom InterTree for use between git revision trees.
319
    """Create a TreeDelta from two git trees.
0.200.959 by Jelmer Vernooij
Improve docstrings.
320
321
    source and target are iterators over tuples with:
0.200.617 by Jelmer Vernooij
Add custom InterTree for use between git revision trees.
322
        (filename, sha, mode)
323
    """
324
    ret = delta.TreeDelta()
325
    for (oldpath, newpath), (oldmode, newmode), (oldsha, newsha) in changes:
0.287.5 by Jelmer Vernooij
Fix root handling.
326
        if newpath == u'' and not include_root:
327
            continue
0.200.1743 by Jelmer Vernooij
Fix some revision delta filtering.
328
        if not (specific_files is None or
0.287.5 by Jelmer Vernooij
Fix root handling.
329
                (oldpath is not None and osutils.is_inside_or_parent_of_any(specific_files, oldpath)) or
330
                (newpath is not None and osutils.is_inside_or_parent_of_any(specific_files, newpath))):
0.200.1743 by Jelmer Vernooij
Fix some revision delta filtering.
331
            continue
0.200.1752 by Jelmer Vernooij
Don't traverse nested trees in WorkingTree.smart_add.
332
        if mapping.is_special_file(oldpath):
0.252.43 by Jelmer Vernooij
Some refactoring, support proper file ids in revision deltas.
333
            oldpath = None
0.200.1752 by Jelmer Vernooij
Don't traverse nested trees in WorkingTree.smart_add.
334
        if mapping.is_special_file(newpath):
0.252.43 by Jelmer Vernooij
Some refactoring, support proper file ids in revision deltas.
335
            newpath = None
336
        if oldpath is None and newpath is None:
337
            continue
0.200.617 by Jelmer Vernooij
Add custom InterTree for use between git revision trees.
338
        if oldpath is None:
0.200.1613 by Jelmer Vernooij
Handle encoding better in working tree iter changes.
339
            file_id = new_fileid_map.lookup_file_id(newpath)
340
            ret.added.append((newpath.decode('utf-8'), file_id, mode_kind(newmode)))
0.200.617 by Jelmer Vernooij
Add custom InterTree for use between git revision trees.
341
        elif newpath is None:
0.200.1613 by Jelmer Vernooij
Handle encoding better in working tree iter changes.
342
            file_id = old_fileid_map.lookup_file_id(oldpath)
343
            ret.removed.append((oldpath.decode('utf-8'), file_id, mode_kind(oldmode)))
0.200.617 by Jelmer Vernooij
Add custom InterTree for use between git revision trees.
344
        elif oldpath != newpath:
0.200.1613 by Jelmer Vernooij
Handle encoding better in working tree iter changes.
345
            file_id = old_fileid_map.lookup_file_id(oldpath)
0.287.3 by Jelmer Vernooij
Some improvements to changes iterator.
346
            ret.renamed.append(
347
                (oldpath.decode('utf-8'), newpath.decode('utf-8'), file_id,
348
                mode_kind(newmode), (oldsha != newsha),
349
                (oldmode != newmode)))
0.200.617 by Jelmer Vernooij
Add custom InterTree for use between git revision trees.
350
        elif mode_kind(oldmode) != mode_kind(newmode):
0.200.1613 by Jelmer Vernooij
Handle encoding better in working tree iter changes.
351
            file_id = new_fileid_map.lookup_file_id(newpath)
0.287.3 by Jelmer Vernooij
Some improvements to changes iterator.
352
            ret.kind_changed.append(
353
                (newpath.decode('utf-8'), file_id, mode_kind(oldmode),
354
                mode_kind(newmode)))
0.200.617 by Jelmer Vernooij
Add custom InterTree for use between git revision trees.
355
        elif oldsha != newsha or oldmode != newmode:
0.287.3 by Jelmer Vernooij
Some improvements to changes iterator.
356
            if stat.S_ISDIR(oldmode) and stat.S_ISDIR(newmode):
357
                continue
0.200.1613 by Jelmer Vernooij
Handle encoding better in working tree iter changes.
358
            file_id = new_fileid_map.lookup_file_id(newpath)
0.287.3 by Jelmer Vernooij
Some improvements to changes iterator.
359
            ret.modified.append(
360
                (newpath.decode('utf-8'), file_id, mode_kind(newmode),
361
                (oldsha != newsha), (oldmode != newmode)))
0.200.617 by Jelmer Vernooij
Add custom InterTree for use between git revision trees.
362
        else:
0.200.1613 by Jelmer Vernooij
Handle encoding better in working tree iter changes.
363
            file_id = new_fileid_map.lookup_file_id(newpath)
364
            ret.unchanged.append((newpath.decode('utf-8'), file_id, mode_kind(newmode)))
0.200.617 by Jelmer Vernooij
Add custom InterTree for use between git revision trees.
365
    return ret
366
367
0.200.1743 by Jelmer Vernooij
Fix some revision delta filtering.
368
def changes_from_git_changes(changes, mapping, specific_files=None,
0.200.622 by Jelmer Vernooij
Implement InterTree.iter_changes() as well.
369
                                require_versioned=False):
370
    """Create a iter_changes-like generator from a git stream.
0.200.959 by Jelmer Vernooij
Improve docstrings.
371
372
    source and target are iterators over tuples with:
0.200.622 by Jelmer Vernooij
Implement InterTree.iter_changes() as well.
373
        (filename, sha, mode)
374
    """
375
    for (oldpath, newpath), (oldmode, newmode), (oldsha, newsha) in changes:
0.200.1743 by Jelmer Vernooij
Fix some revision delta filtering.
376
        if not (specific_files is None or
0.287.5 by Jelmer Vernooij
Fix root handling.
377
                (oldpath is not None and osutils.is_inside_or_parent_of_any(specific_files, oldpath)) or
378
                (newpath is not None and osutils.is_inside_or_parent_of_any(specific_files, newpath))):
0.200.1743 by Jelmer Vernooij
Fix some revision delta filtering.
379
            continue
0.200.622 by Jelmer Vernooij
Implement InterTree.iter_changes() as well.
380
        path = (oldpath, newpath)
0.287.3 by Jelmer Vernooij
Some improvements to changes iterator.
381
        if oldpath is not None and mapping.is_special_file(oldpath):
382
            continue
383
        if newpath is not None and mapping.is_special_file(newpath):
0.200.1328 by Jelmer Vernooij
More test fixes.
384
            continue
0.200.622 by Jelmer Vernooij
Implement InterTree.iter_changes() as well.
385
        if oldpath is None:
386
            fileid = mapping.generate_file_id(newpath)
387
            oldexe = None
388
            oldkind = None
389
            oldname = None
390
            oldparent = None
391
        else:
0.200.1345 by Jelmer Vernooij
paths should be unicode when yielded by iter_changes.
392
            oldpath = oldpath.decode("utf-8")
0.200.1576 by Jelmer Vernooij
Merge a bunch of fixes from store-roundtrip-info.
393
            assert oldmode is not None
0.200.622 by Jelmer Vernooij
Implement InterTree.iter_changes() as well.
394
            oldexe = mode_is_executable(oldmode)
395
            oldkind = mode_kind(oldmode)
0.316.1 by Jelmer Vernooij
Fix iter_changes behaviour for trees in the tree root.
396
            if oldpath == u'':
0.200.622 by Jelmer Vernooij
Implement InterTree.iter_changes() as well.
397
                oldparent = None
0.316.1 by Jelmer Vernooij
Fix iter_changes behaviour for trees in the tree root.
398
                oldname = ''
0.200.622 by Jelmer Vernooij
Implement InterTree.iter_changes() as well.
399
            else:
0.316.1 by Jelmer Vernooij
Fix iter_changes behaviour for trees in the tree root.
400
                (oldparentpath, oldname) = osutils.split(oldpath)
0.200.622 by Jelmer Vernooij
Implement InterTree.iter_changes() as well.
401
                oldparent = mapping.generate_file_id(oldparentpath)
402
            fileid = mapping.generate_file_id(oldpath)
403
        if newpath is None:
404
            newexe = None
405
            newkind = None
406
            newname = None
407
            newparent = None
408
        else:
0.200.1345 by Jelmer Vernooij
paths should be unicode when yielded by iter_changes.
409
            newpath = newpath.decode("utf-8")
0.200.1576 by Jelmer Vernooij
Merge a bunch of fixes from store-roundtrip-info.
410
            if newmode is not None:
411
                newexe = mode_is_executable(newmode)
412
                newkind = mode_kind(newmode)
413
            else:
414
                newexe = False
415
                newkind = None
0.316.1 by Jelmer Vernooij
Fix iter_changes behaviour for trees in the tree root.
416
            if newpath == u'':
0.200.622 by Jelmer Vernooij
Implement InterTree.iter_changes() as well.
417
                newparent = None
0.316.1 by Jelmer Vernooij
Fix iter_changes behaviour for trees in the tree root.
418
                newname = u''
0.200.622 by Jelmer Vernooij
Implement InterTree.iter_changes() as well.
419
            else:
0.316.1 by Jelmer Vernooij
Fix iter_changes behaviour for trees in the tree root.
420
                newparentpath, newname = osutils.split(newpath)
0.200.622 by Jelmer Vernooij
Implement InterTree.iter_changes() as well.
421
                newparent = mapping.generate_file_id(newparentpath)
0.200.959 by Jelmer Vernooij
Improve docstrings.
422
        yield (fileid, (oldpath, newpath), (oldsha != newsha),
423
             (oldpath is not None, newpath is not None),
424
             (oldparent, newparent), (oldname, newname),
425
             (oldkind, newkind), (oldexe, newexe))
0.200.622 by Jelmer Vernooij
Implement InterTree.iter_changes() as well.
426
427
0.287.3 by Jelmer Vernooij
Some improvements to changes iterator.
428
class InterGitTrees(tree.InterTree):
429
    """InterTree that works between two git trees."""
0.200.617 by Jelmer Vernooij
Add custom InterTree for use between git revision trees.
430
0.200.659 by Jelmer Vernooij
Prevent tests using InterGitRevisionTrees.
431
    _matching_from_tree_format = None
432
    _matching_to_tree_format = None
433
    _test_mutable_trees_to_test_trees = None
434
0.200.617 by Jelmer Vernooij
Add custom InterTree for use between git revision trees.
435
    @classmethod
436
    def is_compatible(cls, source, target):
0.200.959 by Jelmer Vernooij
Improve docstrings.
437
        return (isinstance(source, GitRevisionTree) and
0.200.617 by Jelmer Vernooij
Add custom InterTree for use between git revision trees.
438
                isinstance(target, GitRevisionTree))
439
440
    def compare(self, want_unchanged=False, specific_files=None,
441
                extra_trees=None, require_versioned=False, include_root=False,
442
                want_unversioned=False):
0.287.3 by Jelmer Vernooij
Some improvements to changes iterator.
443
        changes = self._iter_git_changes(want_unchanged=want_unchanged)
0.200.1731 by Jelmer Vernooij
Add support for checking untracked changes.
444
        source_fileid_map = self.source._fileid_map
445
        target_fileid_map = self.target._fileid_map
0.200.959 by Jelmer Vernooij
Improve docstrings.
446
        return tree_delta_from_git_changes(changes, self.target.mapping,
0.252.43 by Jelmer Vernooij
Some refactoring, support proper file ids in revision deltas.
447
            (source_fileid_map, target_fileid_map),
0.287.5 by Jelmer Vernooij
Fix root handling.
448
            specific_files=specific_files, include_root=include_root)
0.200.617 by Jelmer Vernooij
Add custom InterTree for use between git revision trees.
449
0.200.622 by Jelmer Vernooij
Implement InterTree.iter_changes() as well.
450
    def iter_changes(self, include_unchanged=False, specific_files=None,
0.287.3 by Jelmer Vernooij
Some improvements to changes iterator.
451
                     pb=None, extra_trees=[], require_versioned=True,
452
                     want_unversioned=False):
453
        changes = self._iter_git_changes(want_unchanged=include_unchanged)
0.200.959 by Jelmer Vernooij
Improve docstrings.
454
        return changes_from_git_changes(changes, self.target.mapping,
0.200.1743 by Jelmer Vernooij
Fix some revision delta filtering.
455
            specific_files=specific_files)
0.200.622 by Jelmer Vernooij
Implement InterTree.iter_changes() as well.
456
0.287.3 by Jelmer Vernooij
Some improvements to changes iterator.
457
    def _iter_git_changes(self, want_unchanged=False):
458
        raise NotImplementedError(self._iter_git_changes)
459
460
461
class InterGitRevisionTrees(InterGitTrees):
462
    """InterTree that works between two git revision trees."""
463
464
    _matching_from_tree_format = None
465
    _matching_to_tree_format = None
466
    _test_mutable_trees_to_test_trees = None
467
468
    @classmethod
469
    def is_compatible(cls, source, target):
470
        return (isinstance(source, GitRevisionTree) and
471
                isinstance(target, GitRevisionTree))
472
473
    def _iter_git_changes(self, want_unchanged=False):
474
        if self.source._repository._git.object_store != self.target._repository._git.object_store:
0.200.1780 by Jelmer Vernooij
Fix cross-object-store tree comparison.
475
            store = OverlayObjectStore([self.source._repository._git.object_store,
476
                                        self.target._repository._git.object_store])
477
        else:
478
            store = self.source._repository._git.object_store
0.287.3 by Jelmer Vernooij
Some improvements to changes iterator.
479
        return self.source._repository._git.object_store.tree_changes(
480
            self.source.tree, self.target.tree, want_unchanged=want_unchanged,
481
            include_trees=True)
482
0.200.617 by Jelmer Vernooij
Add custom InterTree for use between git revision trees.
483
484
tree.InterTree.register_optimiser(InterGitRevisionTrees)