/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

Fix branch cloning.

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
24
25
from bzrlib.plugins.git.repository import (
25
26
        LocalGitRepository, 
26
27
        GitRepository, 
28
29
        )
29
30
from bzrlib.plugins.git.remote import RemoteGitRepository
30
31
 
31
 
import dulwich as git
32
 
from dulwich.client import SimpleFetchGraphWalker
33
32
from dulwich.objects import Commit
34
33
 
35
34
from cStringIO import StringIO
36
35
 
37
36
 
38
37
class BzrFetchGraphWalker(object):
39
 
    """GraphWalker implementation that uses a Bazaar repository."""
40
38
 
41
39
    def __init__(self, repository, mapping):
42
40
        self.repository = repository
45
43
        self.heads = set(repository.all_revision_ids())
46
44
        self.parents = {}
47
45
 
48
 
    def __iter__(self):
49
 
        return iter(self.next, None)
50
 
 
51
46
    def ack(self, sha):
52
47
        revid = self.mapping.revision_id_foreign_to_bzr(sha)
53
48
        self.remove(revid)
54
49
 
55
50
    def remove(self, revid):
56
51
        self.done.add(revid)
57
 
        if revid in self.heads:
 
52
        if ref in self.heads:
58
53
            self.heads.remove(revid)
59
54
        if revid in self.parents:
60
55
            for p in self.parents[revid]:
68
63
            self.heads.update([p for p in ps if not p in self.done])
69
64
            try:
70
65
                self.done.add(ret)
71
 
                return self.mapping.revision_id_bzr_to_foreign(ret)[0]
 
66
                return self.mapping.revision_id_bzr_to_foreign(ret)
72
67
            except InvalidRevisionId:
73
68
                pass
74
69
        return None
134
129
    :param object_iter: Iterator over Git objects.
135
130
    """
136
131
    # TODO: a more (memory-)efficient implementation of this
 
132
    objects = {}
 
133
    for i, o in enumerate(object_iter):
 
134
        if pb is not None:
 
135
            pb.update("fetching objects", i) 
 
136
        objects[o.id] = o
137
137
    graph = []
138
138
    root_trees = {}
139
139
    revisions = {}
140
140
    # Find and convert commit objects
141
 
    for o in object_iter.iterobjects():
 
141
    for o in objects.itervalues():
142
142
        if isinstance(o, Commit):
143
143
            rev = mapping.import_commit(o)
144
 
            root_trees[rev.revision_id] = object_iter[o.tree]
 
144
            root_trees[rev.revision_id] = objects[o.tree]
145
145
            revisions[rev.revision_id] = rev
146
146
            graph.append((rev.revision_id, rev.parent_ids))
147
147
    # Order the revisions
157
157
        inv = Inventory()
158
158
        inv.revision_id = rev.revision_id
159
159
        def lookup_object(sha):
160
 
            if sha in object_iter:
161
 
                return object_iter[sha]
 
160
            if sha in objects:
 
161
                return objects[sha]
162
162
            return reconstruct_git_object(repo, mapping, sha)
163
163
        parent_invs = [repo.get_inventory(r) for r in rev.parent_ids]
164
 
        import_git_tree(repo, mapping, "", root_tree, inv, parent_invs, 
165
 
            lookup_object)
 
164
        import_git_tree(repo, mapping, "", root_tree, inv, parent_invs, lookup_object)
166
165
        repo.add_revision(rev.revision_id, rev, inv)
167
166
 
168
167
 
185
184
    raise KeyError("No such object %s" % sha)
186
185
 
187
186
 
188
 
class InterGitNonGitRepository(InterRepository):
 
187
class InterGitRepository(InterRepository):
189
188
 
190
189
    _matching_repo_format = GitFormat()
191
190
 
202
201
        if mapping is None:
203
202
            mapping = self.source.get_mapping()
204
203
        def progress(text):
205
 
            pb.update("git: %s" % text.rstrip("\r\n"), 0, 0)
 
204
            pb.note("git: %s", text)
206
205
        def determine_wants(heads):
207
206
            if revision_id is None:
208
207
                ret = heads.values()
209
208
            else:
210
 
                ret = [mapping.revision_id_bzr_to_foreign(revision_id)[0]]
 
209
                ret = [mapping.revision_id_bzr_to_foreign(revision_id)]
211
210
            return [rev for rev in ret if not self.target.has_revision(mapping.revision_id_foreign_to_bzr(rev))]
212
211
        graph_walker = BzrFetchGraphWalker(self.target, mapping)
213
212
        create_pb = None
218
217
            try:
219
218
                self.target.start_write_group()
220
219
                try:
221
 
                    objects_iter = self.source.fetch_objects(determine_wants, 
222
 
                                graph_walker, progress)
223
 
                    import_git_objects(self.target, mapping, objects_iter, pb)
 
220
                    import_git_objects(self.target, mapping,
 
221
                        iter(self.source.fetch_objects(determine_wants, graph_walker, 
 
222
                            progress)), pb)
224
223
                finally:
225
224
                    self.target.commit_write_group()
226
225
            finally:
234
233
        """Be compatible with GitRepository."""
235
234
        # FIXME: Also check target uses VersionedFile
236
235
        return (isinstance(source, GitRepository) and 
237
 
                target.supports_rich_root() and
238
 
                not isinstance(target, GitRepository))
239
 
 
240
 
 
241
 
class InterGitRepository(InterRepository):
242
 
 
243
 
    _matching_repo_format = GitFormat()
244
 
 
245
 
    @staticmethod
246
 
    def _get_repo_format_to_test():
247
 
        return None
248
 
 
249
 
    def copy_content(self, revision_id=None, pb=None):
250
 
        """See InterRepository.copy_content."""
251
 
        self.fetch(revision_id, pb, find_ghosts=False)
252
 
 
253
 
    def fetch(self, revision_id=None, pb=None, find_ghosts=False, 
254
 
              mapping=None):
255
 
        if mapping is None:
256
 
            mapping = self.source.get_mapping()
257
 
        def progress(text):
258
 
            info("git: %s", text)
259
 
        r = self.target._git
260
 
        if revision_id is None:
261
 
            determine_wants = lambda x: [y for y in x.values() if not y in r.object_store]
262
 
        else:
263
 
            args = [mapping.revision_id_bzr_to_foreign(revision_id)[0]]
264
 
            determine_wants = lambda x: [y for y in args if not y in r.object_store]
265
 
 
266
 
        graphwalker = SimpleFetchGraphWalker(r.heads().values(), r.get_parents)
267
 
        f, commit = r.object_store.add_pack()
268
 
        try:
269
 
            self.source._git.fetch_pack(path, determine_wants, graphwalker, f.write, progress)
270
 
            f.close()
271
 
            commit()
272
 
        except:
273
 
            f.close()
274
 
            raise
275
 
 
276
 
    @staticmethod
277
 
    def is_compatible(source, target):
278
 
        """Be compatible with GitRepository."""
279
 
        return (isinstance(source, GitRepository) and 
280
 
                isinstance(target, GitRepository))
 
236
                target.supports_rich_root())