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