/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.200.135 by Jelmer Vernooij
Add stub for fetching data.
1
# Copyright (C) 2008 Canonical Ltd
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
0.200.158 by Jelmer Vernooij
fetch works \o/
17
from bzrlib import osutils, ui, urlutils
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
18
from bzrlib.errors import InvalidRevisionId
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
19
from bzrlib.inventory import Inventory
0.200.135 by Jelmer Vernooij
Add stub for fetching data.
20
from bzrlib.repository import InterRepository
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
21
from bzrlib.trace import info
0.200.158 by Jelmer Vernooij
fetch works \o/
22
from bzrlib.tsort import topo_sort
0.200.135 by Jelmer Vernooij
Add stub for fetching data.
23
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
24
from bzrlib.plugins.git import git
0.200.141 by Jelmer Vernooij
Separate out local and remote fetching.
25
from bzrlib.plugins.git.repository import LocalGitRepository, GitRepository, GitFormat
26
from bzrlib.plugins.git.remote import RemoteGitRepository
0.216.4 by Jelmer Vernooij
Add basic pack fetch infrastructure.
27
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
28
from dulwich.objects import Commit
29
0.216.4 by Jelmer Vernooij
Add basic pack fetch infrastructure.
30
from cStringIO import StringIO
31
32
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
33
class BzrFetchGraphWalker(object):
0.216.4 by Jelmer Vernooij
Add basic pack fetch infrastructure.
34
35
    def __init__(self, repository, mapping):
36
        self.repository = repository
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
37
        self.mapping = mapping
38
        self.done = set()
39
        self.heads = set(repository.all_revision_ids())
0.216.4 by Jelmer Vernooij
Add basic pack fetch infrastructure.
40
        self.parents = {}
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
41
42
    def ack(self, sha):
43
        revid = self.mapping.revision_id_foreign_to_bzr(sha)
44
        self.remove(revid)
45
46
    def remove(self, revid):
47
        self.done.add(revid)
48
        if ref in self.heads:
49
            self.heads.remove(revid)
50
        if revid in self.parents:
51
            for p in self.parents[revid]:
52
                self.remove(p)
0.216.4 by Jelmer Vernooij
Add basic pack fetch infrastructure.
53
54
    def next(self):
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
55
        while self.heads:
56
            ret = self.heads.pop()
57
            ps = self.repository.get_parent_map([ret])[ret]
0.216.4 by Jelmer Vernooij
Add basic pack fetch infrastructure.
58
            self.parents[ret] = ps
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
59
            self.heads.update([p for p in ps if not p in self.done])
60
            try:
61
                self.done.add(ret)
62
                return self.mapping.revision_id_bzr_to_foreign(ret)
63
            except InvalidRevisionId:
64
                pass
0.216.4 by Jelmer Vernooij
Add basic pack fetch infrastructure.
65
        return None
66
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
67
0.200.159 by Jelmer Vernooij
Fix branch tests.
68
def import_git_blob(repo, mapping, path, blob, inv, parent_invs, executable):
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
69
    """Import a git blob object into a bzr repository.
70
71
    :param repo: bzr repository
72
    :param path: Path in the tree
73
    :param blob: A git blob
74
    """
75
    file_id = mapping.generate_file_id(path)
0.200.158 by Jelmer Vernooij
fetch works \o/
76
    text_revision = inv.revision_id
77
    repo.texts.add_lines((file_id, text_revision),
78
        [(file_id, p[file_id].revision) for p in parent_invs if file_id in p],
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
79
        osutils.split_lines(blob.data))
0.200.157 by Jelmer Vernooij
Fix some bit of fetching.
80
    ie = inv.add_path(path, "file", file_id)
0.200.158 by Jelmer Vernooij
fetch works \o/
81
    ie.revision = text_revision
82
    ie.text_size = len(blob.data)
83
    ie.text_sha1 = osutils.sha_string(blob.data)
0.200.159 by Jelmer Vernooij
Fix branch tests.
84
    ie.executable = executable
0.200.158 by Jelmer Vernooij
fetch works \o/
85
86
87
def import_git_tree(repo, mapping, path, tree, inv, parent_invs, lookup_object):
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
88
    """Import a git tree object into a bzr repository.
89
90
    :param repo: A Bzr repository object
91
    :param path: Path in the tree
92
    :param tree: A git tree object
93
    :param inv: Inventory object
94
    """
95
    file_id = mapping.generate_file_id(path)
0.200.158 by Jelmer Vernooij
fetch works \o/
96
    text_revision = inv.revision_id
97
    repo.texts.add_lines((file_id, text_revision),
98
        [(file_id, p[file_id].revision) for p in parent_invs if file_id in p],
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
99
        [])
0.200.158 by Jelmer Vernooij
fetch works \o/
100
    ie = inv.add_path(path, "directory", file_id)
101
    ie.revision = text_revision
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
102
    for mode, name, hexsha in tree.entries():
103
        entry_kind = (mode & 0700000) / 0100000
104
        basename = name.decode("utf-8")
105
        if path == "":
106
            child_path = name
107
        else:
108
            child_path = urlutils.join(path, name)
109
        if entry_kind == 0:
0.200.157 by Jelmer Vernooij
Fix some bit of fetching.
110
            tree = lookup_object(hexsha)
0.200.158 by Jelmer Vernooij
fetch works \o/
111
            import_git_tree(repo, mapping, child_path, tree, inv, parent_invs, lookup_object)
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
112
        elif entry_kind == 1:
0.200.157 by Jelmer Vernooij
Fix some bit of fetching.
113
            blob = lookup_object(hexsha)
0.200.159 by Jelmer Vernooij
Fix branch tests.
114
            fs_mode = mode & 0777
115
            import_git_blob(repo, mapping, child_path, blob, inv, parent_invs, bool(fs_mode & 0111))
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
116
        else:
117
            raise AssertionError("Unknown blob kind, perms=%r." % (mode,))
118
119
0.200.158 by Jelmer Vernooij
fetch works \o/
120
def import_git_objects(repo, mapping, object_iter, pb=None):
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
121
    """Import a set of git objects into a bzr repository.
122
123
    :param repo: Bazaar repository
124
    :param mapping: Mapping to use
125
    :param object_iter: Iterator over Git objects.
126
    """
127
    # TODO: a more (memory-)efficient implementation of this
128
    objects = {}
0.200.158 by Jelmer Vernooij
fetch works \o/
129
    for i, o in enumerate(object_iter):
130
        if pb is not None:
131
            pb.update("fetching objects", i) 
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
132
        objects[o.id] = o
0.200.158 by Jelmer Vernooij
fetch works \o/
133
    graph = []
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
134
    root_trees = {}
0.200.158 by Jelmer Vernooij
fetch works \o/
135
    revisions = {}
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
136
    # Find and convert commit objects
0.200.157 by Jelmer Vernooij
Fix some bit of fetching.
137
    for o in objects.itervalues():
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
138
        if isinstance(o, Commit):
139
            rev = mapping.import_commit(o)
0.200.158 by Jelmer Vernooij
fetch works \o/
140
            root_trees[rev.revision_id] = objects[o.tree]
141
            revisions[rev.revision_id] = rev
142
            graph.append((rev.revision_id, rev.parent_ids))
143
    # Order the revisions
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
144
    # Create the inventory objects
0.200.158 by Jelmer Vernooij
fetch works \o/
145
    for i, revid in enumerate(topo_sort(graph)):
146
        if pb is not None:
147
            pb.update("fetching revisions", i, len(graph))
148
        root_tree = root_trees[revid]
149
        rev = revisions[revid]
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
150
        # We have to do this here, since we have to walk the tree and 
151
        # we need to make sure to import the blobs / trees with the riht 
152
        # path; this may involve adding them more than once.
153
        inv = Inventory()
0.200.157 by Jelmer Vernooij
Fix some bit of fetching.
154
        inv.revision_id = rev.revision_id
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
155
        def lookup_object(sha):
0.200.153 by Jelmer Vernooij
Merge new dulwich.
156
            if sha in objects:
157
                return objects[sha]
158
            return reconstruct_git_object(repo, mapping, sha)
0.200.158 by Jelmer Vernooij
fetch works \o/
159
        parent_invs = [repo.get_inventory(r) for r in rev.parent_ids]
160
        import_git_tree(repo, mapping, "", root_tree, inv, parent_invs, lookup_object)
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
161
        repo.add_revision(rev.revision_id, rev, inv)
0.200.141 by Jelmer Vernooij
Separate out local and remote fetching.
162
163
0.200.153 by Jelmer Vernooij
Merge new dulwich.
164
def reconstruct_git_commit(repo, rev):
165
    raise NotImplementedError(self.reconstruct_git_commit)
166
167
168
def reconstruct_git_object(repo, mapping, sha):
169
    # Commit
170
    revid = mapping.revision_id_foreign_to_bzr(sha)
171
    try:
172
        rev = repo.get_revision(revid)
173
    except NoSuchRevision:
174
        pass
175
    else:
176
        return reconstruct_git_commit(rev)
177
178
    # TODO: Tree
179
    # TODO: Blob
180
    raise KeyError("No such object %s" % sha)
181
182
0.200.141 by Jelmer Vernooij
Separate out local and remote fetching.
183
class InterGitRepository(InterRepository):
0.200.135 by Jelmer Vernooij
Add stub for fetching data.
184
0.200.143 by Jelmer Vernooij
Reoncile InterGitRepository objects.
185
    _matching_repo_format = GitFormat()
186
187
    @staticmethod
188
    def _get_repo_format_to_test():
189
        return None
190
0.200.135 by Jelmer Vernooij
Add stub for fetching data.
191
    def copy_content(self, revision_id=None, pb=None):
192
        """See InterRepository.copy_content."""
193
        self.fetch(revision_id, pb, find_ghosts=False)
194
195
    def fetch(self, revision_id=None, pb=None, find_ghosts=False, 
196
              mapping=None):
0.200.141 by Jelmer Vernooij
Separate out local and remote fetching.
197
        if mapping is None:
198
            mapping = self.source.get_mapping()
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
199
        def progress(text):
200
            if pb is not None:
201
                pb.note("git: %s" % text)
202
            else:
203
                info("git: %s" % text)
0.200.141 by Jelmer Vernooij
Separate out local and remote fetching.
204
        def determine_wants(heads):
205
            if revision_id is None:
206
                ret = heads.values()
207
            else:
208
                ret = [mapping.revision_id_bzr_to_foreign(revision_id)]
0.200.147 by Jelmer Vernooij
Merge new dulwich; fetching objects from local repository works now; they aren't converted yet though.
209
            return [rev for rev in ret if not self.target.has_revision(mapping.revision_id_foreign_to_bzr(rev))]
0.200.143 by Jelmer Vernooij
Reoncile InterGitRepository objects.
210
        graph_walker = BzrFetchGraphWalker(self.target, mapping)
0.200.141 by Jelmer Vernooij
Separate out local and remote fetching.
211
        self.target.lock_write()
212
        try:
0.200.157 by Jelmer Vernooij
Fix some bit of fetching.
213
            self.target.start_write_group()
214
            try:
215
                import_git_objects(self.target, mapping,
216
                    iter(self.source.fetch_objects(determine_wants, graph_walker, 
0.200.158 by Jelmer Vernooij
fetch works \o/
217
                        progress)), pb)
0.200.157 by Jelmer Vernooij
Fix some bit of fetching.
218
            finally:
219
                self.target.commit_write_group()
0.200.141 by Jelmer Vernooij
Separate out local and remote fetching.
220
        finally:
221
            self.target.unlock()
222
223
    @staticmethod
224
    def is_compatible(source, target):
225
        """Be compatible with GitRepository."""
226
        # FIXME: Also check target uses VersionedFile
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
227
        return (isinstance(source, LocalGitRepository) and 
228
                target.supports_rich_root())