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