/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.264.3 by Jelmer Vernooij
Make RevisionTree inventoryless.
20
from dulwich.object_store import tree_lookup_path
21
import stat
22
0.200.617 by Jelmer Vernooij
Add custom InterTree for use between git revision trees.
23
from bzrlib import (
24
    delta,
25
    errors,
26
    revisiontree,
27
    tree,
28
    )
29
30
from bzrlib.plugins.git.mapping import (
0.200.622 by Jelmer Vernooij
Implement InterTree.iter_changes() as well.
31
    mode_is_executable,
0.200.617 by Jelmer Vernooij
Add custom InterTree for use between git revision trees.
32
    mode_kind,
33
    )
34
35
36
class GitRevisionTree(revisiontree.RevisionTree):
0.200.959 by Jelmer Vernooij
Improve docstrings.
37
    """Revision tree implementation based on Git objects."""
0.200.617 by Jelmer Vernooij
Add custom InterTree for use between git revision trees.
38
39
    def __init__(self, repository, revision_id):
40
        self._revision_id = revision_id
41
        self._repository = repository
0.264.3 by Jelmer Vernooij
Make RevisionTree inventoryless.
42
        self.store = repository._git.object_store
0.200.617 by Jelmer Vernooij
Add custom InterTree for use between git revision trees.
43
        assert isinstance(revision_id, str)
0.200.650 by Jelmer Vernooij
Use standard names for lookup functions.
44
        git_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.
45
        try:
0.264.3 by Jelmer Vernooij
Make RevisionTree inventoryless.
46
            commit = self.store[git_id]
0.200.617 by Jelmer Vernooij
Add custom InterTree for use between git revision trees.
47
        except KeyError, r:
48
            raise errors.NoSuchRevision(repository, revision_id)
49
        self.tree = commit.tree
0.264.3 by Jelmer Vernooij
Make RevisionTree inventoryless.
50
        self.fileid_map = self.mapping.get_fileid_map(self.store.__getitem__, self.tree)
51
52
    def id2path(self, file_id):
53
        return self.fileid_map.lookup_path(file_id)
54
55
    def path2id(self, path):
56
        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.
57
58
    def get_revision_id(self):
0.200.959 by Jelmer Vernooij
Improve docstrings.
59
        """See RevisionTree.get_revision_id."""
0.200.617 by Jelmer Vernooij
Add custom InterTree for use between git revision trees.
60
        return self._revision_id
61
62
    def get_file_text(self, file_id, path=None):
0.200.959 by Jelmer Vernooij
Improve docstrings.
63
        """See RevisionTree.get_file_text."""
0.264.3 by Jelmer Vernooij
Make RevisionTree inventoryless.
64
        if path is None:
65
            path = self.id2path(file_id)
66
        (mode, hexsha)= tree_lookup_path(self.store.__getitem__, self.tree, path)
67
        if stat.S_ISREG(mode):
68
            return self.store[hexsha].data
0.200.617 by Jelmer Vernooij
Add custom InterTree for use between git revision trees.
69
        else:
0.200.664 by Jelmer Vernooij
Support submodules during fetch.
70
            return ""
0.200.617 by Jelmer Vernooij
Add custom InterTree for use between git revision trees.
71
72
0.252.43 by Jelmer Vernooij
Some refactoring, support proper file ids in revision deltas.
73
def tree_delta_from_git_changes(changes, mapping,
74
        (old_fileid_map, new_fileid_map), specific_file=None,
75
        require_versioned=False):
0.200.617 by Jelmer Vernooij
Add custom InterTree for use between git revision trees.
76
    """Create a TreeDelta from two git trees.
0.200.959 by Jelmer Vernooij
Improve docstrings.
77
78
    source and target are iterators over tuples with:
0.200.617 by Jelmer Vernooij
Add custom InterTree for use between git revision trees.
79
        (filename, sha, mode)
80
    """
81
    ret = delta.TreeDelta()
82
    for (oldpath, newpath), (oldmode, newmode), (oldsha, newsha) in changes:
0.252.43 by Jelmer Vernooij
Some refactoring, support proper file ids in revision deltas.
83
        if mapping.is_control_file(oldpath):
84
            oldpath = None
85
        if mapping.is_control_file(newpath):
86
            newpath = None
87
        if oldpath is None and newpath is None:
88
            continue
0.200.617 by Jelmer Vernooij
Add custom InterTree for use between git revision trees.
89
        if oldpath is None:
0.252.43 by Jelmer Vernooij
Some refactoring, support proper file ids in revision deltas.
90
            ret.added.append((newpath, new_fileid_map.lookup_file_id(newpath.encode("utf-8")), mode_kind(newmode)))
0.200.617 by Jelmer Vernooij
Add custom InterTree for use between git revision trees.
91
        elif newpath is None:
0.252.43 by Jelmer Vernooij
Some refactoring, support proper file ids in revision deltas.
92
            ret.removed.append((oldpath, old_fileid_map.lookup_file_id(oldpath.encode("utf-8")), mode_kind(oldmode)))
0.200.617 by Jelmer Vernooij
Add custom InterTree for use between git revision trees.
93
        elif oldpath != newpath:
0.252.43 by Jelmer Vernooij
Some refactoring, support proper file ids in revision deltas.
94
            ret.renamed.append((oldpath, newpath, old_fileid_map.lookup_file_id(oldpath.encode("utf-8")), mode_kind(newmode), (oldsha != newsha), (oldmode != newmode)))
0.200.617 by Jelmer Vernooij
Add custom InterTree for use between git revision trees.
95
        elif mode_kind(oldmode) != mode_kind(newmode):
0.252.43 by Jelmer Vernooij
Some refactoring, support proper file ids in revision deltas.
96
            ret.kind_changed.append((newpath, new_fileid_map.lookup_file_id(newpath.encode("utf-8")), mode_kind(oldmode), mode_kind(newmode)))
0.200.617 by Jelmer Vernooij
Add custom InterTree for use between git revision trees.
97
        elif oldsha != newsha or oldmode != newmode:
0.252.43 by Jelmer Vernooij
Some refactoring, support proper file ids in revision deltas.
98
            ret.modified.append((newpath, new_fileid_map.lookup_file_id(newpath.encode("utf-8")), mode_kind(newmode), (oldsha != newsha), (oldmode != newmode)))
0.200.617 by Jelmer Vernooij
Add custom InterTree for use between git revision trees.
99
        else:
0.252.43 by Jelmer Vernooij
Some refactoring, support proper file ids in revision deltas.
100
            ret.unchanged.append((newpath, new_fileid_map.lookup_file_id(newpath.encode("utf-8")), mode_kind(newmode)))
0.200.617 by Jelmer Vernooij
Add custom InterTree for use between git revision trees.
101
    return ret
102
103
0.200.959 by Jelmer Vernooij
Improve docstrings.
104
def changes_from_git_changes(changes, mapping, specific_file=None,
0.200.622 by Jelmer Vernooij
Implement InterTree.iter_changes() as well.
105
                                require_versioned=False):
106
    """Create a iter_changes-like generator from a git stream.
0.200.959 by Jelmer Vernooij
Improve docstrings.
107
108
    source and target are iterators over tuples with:
0.200.622 by Jelmer Vernooij
Implement InterTree.iter_changes() as well.
109
        (filename, sha, mode)
110
    """
111
    for (oldpath, newpath), (oldmode, newmode), (oldsha, newsha) in changes:
112
        path = (oldpath, newpath)
113
        if oldpath is None:
114
            fileid = mapping.generate_file_id(newpath)
115
            oldexe = None
116
            oldkind = None
117
            oldname = None
118
            oldparent = None
119
        else:
120
            oldexe = mode_is_executable(oldmode)
121
            oldkind = mode_kind(oldmode)
122
            try:
123
                (oldparentpath, oldname) = oldpath.rsplit("/", 1)
124
            except ValueError:
125
                oldparent = None
126
                oldname = oldpath
127
            else:
128
                oldparent = mapping.generate_file_id(oldparentpath)
129
            fileid = mapping.generate_file_id(oldpath)
130
        if newpath is None:
131
            newexe = None
132
            newkind = None
133
            newname = None
134
            newparent = None
135
        else:
136
            newexe = mode_is_executable(newmode)
137
            newkind = mode_kind(newmode)
138
            try:
139
                newparentpath, newname = newpath.rsplit("/", 1)
140
            except ValueError:
141
                newparent = None
142
                newname = newpath
143
            else:
144
                newparent = mapping.generate_file_id(newparentpath)
0.200.959 by Jelmer Vernooij
Improve docstrings.
145
        yield (fileid, (oldpath, newpath), (oldsha != newsha),
146
             (oldpath is not None, newpath is not None),
147
             (oldparent, newparent), (oldname, newname),
148
             (oldkind, newkind), (oldexe, newexe))
0.200.622 by Jelmer Vernooij
Implement InterTree.iter_changes() as well.
149
150
0.200.617 by Jelmer Vernooij
Add custom InterTree for use between git revision trees.
151
class InterGitRevisionTrees(tree.InterTree):
152
    """InterTree that works between two git revision trees."""
153
0.200.659 by Jelmer Vernooij
Prevent tests using InterGitRevisionTrees.
154
    _matching_from_tree_format = None
155
    _matching_to_tree_format = None
156
    _test_mutable_trees_to_test_trees = None
157
0.200.617 by Jelmer Vernooij
Add custom InterTree for use between git revision trees.
158
    @classmethod
159
    def is_compatible(cls, source, target):
0.200.959 by Jelmer Vernooij
Improve docstrings.
160
        return (isinstance(source, GitRevisionTree) and
0.200.617 by Jelmer Vernooij
Add custom InterTree for use between git revision trees.
161
                isinstance(target, GitRevisionTree))
162
163
    def compare(self, want_unchanged=False, specific_files=None,
164
                extra_trees=None, require_versioned=False, include_root=False,
165
                want_unversioned=False):
166
        if self.source._repository._git.object_store != self.target._repository._git.object_store:
167
            raise AssertionError
168
        changes = self.source._repository._git.object_store.tree_changes(
169
            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.
170
        source_fileid_map = self.source.mapping.get_fileid_map(
171
            self.source._repository._git.object_store.__getitem__,
172
            self.source.tree)
173
        target_fileid_map = self.target.mapping.get_fileid_map(
174
            self.target._repository._git.object_store.__getitem__,
175
            self.target.tree)
0.200.959 by Jelmer Vernooij
Improve docstrings.
176
        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.
177
            (source_fileid_map, target_fileid_map),
0.200.617 by Jelmer Vernooij
Add custom InterTree for use between git revision trees.
178
            specific_file=specific_files)
179
0.200.622 by Jelmer Vernooij
Implement InterTree.iter_changes() as well.
180
    def iter_changes(self, include_unchanged=False, specific_files=None,
0.200.959 by Jelmer Vernooij
Improve docstrings.
181
        pb=None, extra_trees=[], require_versioned=True,
182
        want_unversioned=False):
0.200.622 by Jelmer Vernooij
Implement InterTree.iter_changes() as well.
183
        if self.source._repository._git.object_store != self.target._repository._git.object_store:
184
            raise AssertionError
185
        changes = self.source._repository._git.object_store.tree_changes(
0.200.959 by Jelmer Vernooij
Improve docstrings.
186
            self.source.tree, self.target.tree,
0.200.622 by Jelmer Vernooij
Implement InterTree.iter_changes() as well.
187
            want_unchanged=include_unchanged)
0.200.959 by Jelmer Vernooij
Improve docstrings.
188
        return changes_from_git_changes(changes, self.target.mapping,
0.200.622 by Jelmer Vernooij
Implement InterTree.iter_changes() as well.
189
            specific_file=specific_files)
190
0.200.617 by Jelmer Vernooij
Add custom InterTree for use between git revision trees.
191
192
tree.InterTree.register_optimiser(InterGitRevisionTrees)