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