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