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