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