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