/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.169 by Jelmer Vernooij
Fix branch cloning.
25
from bzrlib.plugins.git.repository import (
26
        LocalGitRepository, 
27
        GitRepository, 
28
        GitFormat,
29
        )
0.200.141 by Jelmer Vernooij
Separate out local and remote fetching.
30
from bzrlib.plugins.git.remote import RemoteGitRepository
0.216.4 by Jelmer Vernooij
Add basic pack fetch infrastructure.
31
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
32
from dulwich.client import SimpleFetchGraphWalker
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
33
from dulwich.objects import Commit
34
0.216.4 by Jelmer Vernooij
Add basic pack fetch infrastructure.
35
from cStringIO import StringIO
36
37
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
38
class BzrFetchGraphWalker(object):
0.216.4 by Jelmer Vernooij
Add basic pack fetch infrastructure.
39
40
    def __init__(self, repository, mapping):
41
        self.repository = repository
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
42
        self.mapping = mapping
43
        self.done = set()
44
        self.heads = set(repository.all_revision_ids())
0.216.4 by Jelmer Vernooij
Add basic pack fetch infrastructure.
45
        self.parents = {}
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
46
47
    def ack(self, sha):
48
        revid = self.mapping.revision_id_foreign_to_bzr(sha)
49
        self.remove(revid)
50
51
    def remove(self, revid):
52
        self.done.add(revid)
0.200.177 by Jelmer Vernooij
Add git-import command.
53
        if revid in self.heads:
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
54
            self.heads.remove(revid)
55
        if revid in self.parents:
56
            for p in self.parents[revid]:
57
                self.remove(p)
0.216.4 by Jelmer Vernooij
Add basic pack fetch infrastructure.
58
59
    def next(self):
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
60
        while self.heads:
61
            ret = self.heads.pop()
62
            ps = self.repository.get_parent_map([ret])[ret]
0.216.4 by Jelmer Vernooij
Add basic pack fetch infrastructure.
63
            self.parents[ret] = ps
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
64
            self.heads.update([p for p in ps if not p in self.done])
65
            try:
66
                self.done.add(ret)
67
                return self.mapping.revision_id_bzr_to_foreign(ret)
68
            except InvalidRevisionId:
69
                pass
0.216.4 by Jelmer Vernooij
Add basic pack fetch infrastructure.
70
        return None
71
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
72
0.200.159 by Jelmer Vernooij
Fix branch tests.
73
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.
74
    """Import a git blob object into a bzr repository.
75
76
    :param repo: bzr repository
77
    :param path: Path in the tree
78
    :param blob: A git blob
79
    """
80
    file_id = mapping.generate_file_id(path)
0.200.158 by Jelmer Vernooij
fetch works \o/
81
    text_revision = inv.revision_id
82
    repo.texts.add_lines((file_id, text_revision),
83
        [(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.
84
        osutils.split_lines(blob.data))
0.200.157 by Jelmer Vernooij
Fix some bit of fetching.
85
    ie = inv.add_path(path, "file", file_id)
0.200.158 by Jelmer Vernooij
fetch works \o/
86
    ie.revision = text_revision
87
    ie.text_size = len(blob.data)
88
    ie.text_sha1 = osutils.sha_string(blob.data)
0.200.159 by Jelmer Vernooij
Fix branch tests.
89
    ie.executable = executable
0.200.158 by Jelmer Vernooij
fetch works \o/
90
91
92
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.
93
    """Import a git tree object into a bzr repository.
94
95
    :param repo: A Bzr repository object
96
    :param path: Path in the tree
97
    :param tree: A git tree object
98
    :param inv: Inventory object
99
    """
100
    file_id = mapping.generate_file_id(path)
0.200.158 by Jelmer Vernooij
fetch works \o/
101
    text_revision = inv.revision_id
102
    repo.texts.add_lines((file_id, text_revision),
103
        [(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.
104
        [])
0.200.158 by Jelmer Vernooij
fetch works \o/
105
    ie = inv.add_path(path, "directory", file_id)
106
    ie.revision = text_revision
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
107
    for mode, name, hexsha in tree.entries():
108
        entry_kind = (mode & 0700000) / 0100000
109
        basename = name.decode("utf-8")
110
        if path == "":
111
            child_path = name
112
        else:
113
            child_path = urlutils.join(path, name)
114
        if entry_kind == 0:
0.200.157 by Jelmer Vernooij
Fix some bit of fetching.
115
            tree = lookup_object(hexsha)
0.200.158 by Jelmer Vernooij
fetch works \o/
116
            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.
117
        elif entry_kind == 1:
0.200.157 by Jelmer Vernooij
Fix some bit of fetching.
118
            blob = lookup_object(hexsha)
0.200.159 by Jelmer Vernooij
Fix branch tests.
119
            fs_mode = mode & 0777
120
            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.
121
        else:
122
            raise AssertionError("Unknown blob kind, perms=%r." % (mode,))
123
124
0.200.188 by Jelmer Vernooij
Merge dulwich.
125
def import_git_objects(repo, mapping, num_objects, object_iter, pb=None):
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
126
    """Import a set of git objects into a bzr repository.
127
128
    :param repo: Bazaar repository
129
    :param mapping: Mapping to use
0.200.188 by Jelmer Vernooij
Merge dulwich.
130
    :param num_objects: Number of objects.
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
131
    :param object_iter: Iterator over Git objects.
132
    """
133
    # TODO: a more (memory-)efficient implementation of this
134
    objects = {}
0.200.158 by Jelmer Vernooij
fetch works \o/
135
    for i, o in enumerate(object_iter):
136
        if pb is not None:
0.200.188 by Jelmer Vernooij
Merge dulwich.
137
            pb.update("fetching objects", i, num_objects) 
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
138
        objects[o.id] = o
0.200.158 by Jelmer Vernooij
fetch works \o/
139
    graph = []
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
140
    root_trees = {}
0.200.158 by Jelmer Vernooij
fetch works \o/
141
    revisions = {}
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
142
    # Find and convert commit objects
0.200.157 by Jelmer Vernooij
Fix some bit of fetching.
143
    for o in objects.itervalues():
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
144
        if isinstance(o, Commit):
145
            rev = mapping.import_commit(o)
0.200.158 by Jelmer Vernooij
fetch works \o/
146
            root_trees[rev.revision_id] = objects[o.tree]
147
            revisions[rev.revision_id] = rev
148
            graph.append((rev.revision_id, rev.parent_ids))
149
    # Order the revisions
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
150
    # Create the inventory objects
0.200.158 by Jelmer Vernooij
fetch works \o/
151
    for i, revid in enumerate(topo_sort(graph)):
152
        if pb is not None:
153
            pb.update("fetching revisions", i, len(graph))
154
        root_tree = root_trees[revid]
155
        rev = revisions[revid]
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
156
        # We have to do this here, since we have to walk the tree and 
157
        # we need to make sure to import the blobs / trees with the riht 
158
        # path; this may involve adding them more than once.
159
        inv = Inventory()
0.200.157 by Jelmer Vernooij
Fix some bit of fetching.
160
        inv.revision_id = rev.revision_id
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
161
        def lookup_object(sha):
0.200.153 by Jelmer Vernooij
Merge new dulwich.
162
            if sha in objects:
163
                return objects[sha]
164
            return reconstruct_git_object(repo, mapping, sha)
0.200.158 by Jelmer Vernooij
fetch works \o/
165
        parent_invs = [repo.get_inventory(r) for r in rev.parent_ids]
0.200.170 by Jelmer Vernooij
Merge new dulwich.
166
        import_git_tree(repo, mapping, "", root_tree, inv, parent_invs, 
167
            lookup_object)
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
168
        repo.add_revision(rev.revision_id, rev, inv)
0.200.141 by Jelmer Vernooij
Separate out local and remote fetching.
169
170
0.200.153 by Jelmer Vernooij
Merge new dulwich.
171
def reconstruct_git_commit(repo, rev):
172
    raise NotImplementedError(self.reconstruct_git_commit)
173
174
175
def reconstruct_git_object(repo, mapping, sha):
176
    # Commit
177
    revid = mapping.revision_id_foreign_to_bzr(sha)
178
    try:
179
        rev = repo.get_revision(revid)
180
    except NoSuchRevision:
181
        pass
182
    else:
183
        return reconstruct_git_commit(rev)
184
185
    # TODO: Tree
186
    # TODO: Blob
187
    raise KeyError("No such object %s" % sha)
188
189
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
190
class InterGitNonGitRepository(InterRepository):
0.200.135 by Jelmer Vernooij
Add stub for fetching data.
191
0.200.143 by Jelmer Vernooij
Reoncile InterGitRepository objects.
192
    _matching_repo_format = GitFormat()
193
194
    @staticmethod
195
    def _get_repo_format_to_test():
196
        return None
197
0.200.135 by Jelmer Vernooij
Add stub for fetching data.
198
    def copy_content(self, revision_id=None, pb=None):
199
        """See InterRepository.copy_content."""
200
        self.fetch(revision_id, pb, find_ghosts=False)
201
202
    def fetch(self, revision_id=None, pb=None, find_ghosts=False, 
203
              mapping=None):
0.200.141 by Jelmer Vernooij
Separate out local and remote fetching.
204
        if mapping is None:
205
            mapping = self.source.get_mapping()
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
206
        def progress(text):
0.217.41 by John Carr
Don't fill screen with muttering
207
            pb.update("git: %s" % text.rstrip("\r\n"), 0, 0)
0.200.141 by Jelmer Vernooij
Separate out local and remote fetching.
208
        def determine_wants(heads):
209
            if revision_id is None:
210
                ret = heads.values()
211
            else:
212
                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.
213
            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.
214
        graph_walker = BzrFetchGraphWalker(self.target, mapping)
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
215
        create_pb = None
216
        if pb is None:
217
            create_pb = pb = ui.ui_factory.nested_progress_bar()
0.200.141 by Jelmer Vernooij
Separate out local and remote fetching.
218
        try:
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
219
            self.target.lock_write()
0.200.157 by Jelmer Vernooij
Fix some bit of fetching.
220
            try:
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
221
                self.target.start_write_group()
222
                try:
0.200.188 by Jelmer Vernooij
Merge dulwich.
223
                    (num_objects, objects_iter) = \
224
                            self.source.fetch_objects(determine_wants, 
0.200.189 by Jelmer Vernooij
Fix syntax error.
225
                                graph_walker, progress)
0.200.188 by Jelmer Vernooij
Merge dulwich.
226
                    import_git_objects(self.target, mapping, num_objects, 
227
                                       objects_iter, pb)
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
228
                finally:
229
                    self.target.commit_write_group()
0.200.157 by Jelmer Vernooij
Fix some bit of fetching.
230
            finally:
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
231
                self.target.unlock()
0.200.141 by Jelmer Vernooij
Separate out local and remote fetching.
232
        finally:
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
233
            if create_pb:
234
                create_pb.finished()
0.200.141 by Jelmer Vernooij
Separate out local and remote fetching.
235
236
    @staticmethod
237
    def is_compatible(source, target):
238
        """Be compatible with GitRepository."""
239
        # FIXME: Also check target uses VersionedFile
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
240
        return (isinstance(source, GitRepository) and 
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
241
                target.supports_rich_root() and
242
                not isinstance(target, GitRepository))
243
244
245
class InterGitRepository(InterRepository):
246
247
    _matching_repo_format = GitFormat()
248
249
    @staticmethod
250
    def _get_repo_format_to_test():
251
        return None
252
253
    def copy_content(self, revision_id=None, pb=None):
254
        """See InterRepository.copy_content."""
255
        self.fetch(revision_id, pb, find_ghosts=False)
256
257
    def fetch(self, revision_id=None, pb=None, find_ghosts=False, 
258
              mapping=None):
259
        if mapping is None:
260
            mapping = self.source.get_mapping()
261
        def progress(text):
262
            info("git: %s", text)
263
        r = self.target._git
264
        if revision_id is None:
265
            determine_wants = lambda x: [y for y in x.values() if not y in r.object_store]
266
        else:
267
            args = [mapping.revision_id_bzr_to_foreign(revision_id)]
268
            determine_wants = lambda x: [y for y in args if not y in r.object_store]
269
270
        graphwalker = SimpleFetchGraphWalker(r.heads().values(), r.get_parents)
271
        f, commit = r.object_store.add_pack()
272
        try:
273
            self.source._git.fetch_pack(path, determine_wants, graphwalker, f.write, progress)
274
            f.close()
275
            commit()
276
        except:
277
            f.close()
278
            raise
279
280
    @staticmethod
281
    def is_compatible(source, target):
282
        """Be compatible with GitRepository."""
283
        return (isinstance(source, GitRepository) and 
284
                isinstance(target, GitRepository))