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