/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to fetch.py

Pass repository object to versionedfiles.

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
from bzrlib.trace import info
22
22
from bzrlib.tsort import topo_sort
23
23
 
24
 
from bzrlib.plugins.git import git
25
24
from bzrlib.plugins.git.repository import (
26
25
        LocalGitRepository, 
27
26
        GitRepository, 
29
28
        )
30
29
from bzrlib.plugins.git.remote import RemoteGitRepository
31
30
 
 
31
import dulwich as git
 
32
from dulwich.client import SimpleFetchGraphWalker
32
33
from dulwich.objects import Commit
33
34
 
34
35
from cStringIO import StringIO
35
36
 
36
37
 
37
38
class BzrFetchGraphWalker(object):
 
39
    """GraphWalker implementation that uses a Bazaar repository."""
38
40
 
39
41
    def __init__(self, repository, mapping):
40
42
        self.repository = repository
43
45
        self.heads = set(repository.all_revision_ids())
44
46
        self.parents = {}
45
47
 
 
48
    def __iter__(self):
 
49
        return iter(self.next, None)
 
50
 
46
51
    def ack(self, sha):
47
52
        revid = self.mapping.revision_id_foreign_to_bzr(sha)
48
53
        self.remove(revid)
49
54
 
50
55
    def remove(self, revid):
51
56
        self.done.add(revid)
52
 
        if ref in self.heads:
 
57
        if revid in self.heads:
53
58
            self.heads.remove(revid)
54
59
        if revid in self.parents:
55
60
            for p in self.parents[revid]:
63
68
            self.heads.update([p for p in ps if not p in self.done])
64
69
            try:
65
70
                self.done.add(ret)
66
 
                return self.mapping.revision_id_bzr_to_foreign(ret)
 
71
                return self.mapping.revision_id_bzr_to_foreign(ret)[0]
67
72
            except InvalidRevisionId:
68
73
                pass
69
74
        return None
121
126
            raise AssertionError("Unknown blob kind, perms=%r." % (mode,))
122
127
 
123
128
 
124
 
def import_git_objects(repo, mapping, object_iter, pb=None):
 
129
def import_git_objects(repo, mapping, num_objects, object_iter, pb=None):
125
130
    """Import a set of git objects into a bzr repository.
126
131
 
127
132
    :param repo: Bazaar repository
128
133
    :param mapping: Mapping to use
 
134
    :param num_objects: Number of objects.
129
135
    :param object_iter: Iterator over Git objects.
130
136
    """
131
137
    # TODO: a more (memory-)efficient implementation of this
132
138
    objects = {}
133
 
    for i, o in enumerate(object_iter):
 
139
    for i, (o, _) in enumerate(object_iter):
134
140
        if pb is not None:
135
 
            pb.update("fetching objects", i) 
 
141
            pb.update("fetching objects", i, num_objects) 
136
142
        objects[o.id] = o
137
143
    graph = []
138
144
    root_trees = {}
161
167
                return objects[sha]
162
168
            return reconstruct_git_object(repo, mapping, sha)
163
169
        parent_invs = [repo.get_inventory(r) for r in rev.parent_ids]
164
 
        import_git_tree(repo, mapping, "", root_tree, inv, parent_invs, lookup_object)
 
170
        import_git_tree(repo, mapping, "", root_tree, inv, parent_invs, 
 
171
            lookup_object)
165
172
        repo.add_revision(rev.revision_id, rev, inv)
166
173
 
167
174
 
184
191
    raise KeyError("No such object %s" % sha)
185
192
 
186
193
 
187
 
class InterGitRepository(InterRepository):
 
194
class InterGitNonGitRepository(InterRepository):
188
195
 
189
196
    _matching_repo_format = GitFormat()
190
197
 
201
208
        if mapping is None:
202
209
            mapping = self.source.get_mapping()
203
210
        def progress(text):
204
 
            pb.note("git: %s", text)
 
211
            pb.update("git: %s" % text.rstrip("\r\n"), 0, 0)
205
212
        def determine_wants(heads):
206
213
            if revision_id is None:
207
214
                ret = heads.values()
208
215
            else:
209
 
                ret = [mapping.revision_id_bzr_to_foreign(revision_id)]
 
216
                ret = [mapping.revision_id_bzr_to_foreign(revision_id)[0]]
210
217
            return [rev for rev in ret if not self.target.has_revision(mapping.revision_id_foreign_to_bzr(rev))]
211
218
        graph_walker = BzrFetchGraphWalker(self.target, mapping)
212
219
        create_pb = None
217
224
            try:
218
225
                self.target.start_write_group()
219
226
                try:
220
 
                    import_git_objects(self.target, mapping,
221
 
                        iter(self.source.fetch_objects(determine_wants, graph_walker, 
222
 
                            progress)), pb)
 
227
                    (num_objects, objects_iter) = \
 
228
                            self.source.fetch_objects(determine_wants, 
 
229
                                graph_walker, progress)
 
230
                    import_git_objects(self.target, mapping, num_objects, 
 
231
                                       objects_iter, pb)
223
232
                finally:
224
233
                    self.target.commit_write_group()
225
234
            finally:
233
242
        """Be compatible with GitRepository."""
234
243
        # FIXME: Also check target uses VersionedFile
235
244
        return (isinstance(source, GitRepository) and 
236
 
                target.supports_rich_root())
 
245
                target.supports_rich_root() and
 
246
                not isinstance(target, GitRepository))
 
247
 
 
248
 
 
249
class InterGitRepository(InterRepository):
 
250
 
 
251
    _matching_repo_format = GitFormat()
 
252
 
 
253
    @staticmethod
 
254
    def _get_repo_format_to_test():
 
255
        return None
 
256
 
 
257
    def copy_content(self, revision_id=None, pb=None):
 
258
        """See InterRepository.copy_content."""
 
259
        self.fetch(revision_id, pb, find_ghosts=False)
 
260
 
 
261
    def fetch(self, revision_id=None, pb=None, find_ghosts=False, 
 
262
              mapping=None):
 
263
        if mapping is None:
 
264
            mapping = self.source.get_mapping()
 
265
        def progress(text):
 
266
            info("git: %s", text)
 
267
        r = self.target._git
 
268
        if revision_id is None:
 
269
            determine_wants = lambda x: [y for y in x.values() if not y in r.object_store]
 
270
        else:
 
271
            args = [mapping.revision_id_bzr_to_foreign(revision_id)[0]]
 
272
            determine_wants = lambda x: [y for y in args if not y in r.object_store]
 
273
 
 
274
        graphwalker = SimpleFetchGraphWalker(r.heads().values(), r.get_parents)
 
275
        f, commit = r.object_store.add_pack()
 
276
        try:
 
277
            self.source._git.fetch_pack(path, determine_wants, graphwalker, f.write, progress)
 
278
            f.close()
 
279
            commit()
 
280
        except:
 
281
            f.close()
 
282
            raise
 
283
 
 
284
    @staticmethod
 
285
    def is_compatible(source, target):
 
286
        """Be compatible with GitRepository."""
 
287
        return (isinstance(source, GitRepository) and 
 
288
                isinstance(target, GitRepository))