/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

Support submodules during fetch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
41
41
    InventoryDirectory,
42
42
    InventoryFile,
43
43
    InventoryLink,
 
44
    TreeReference,
44
45
    )
45
46
from bzrlib.lru_cache import (
46
47
    LRUCache,
72
73
    RemoteGitRepository,
73
74
    )
74
75
from bzrlib.plugins.git.repository import (
75
 
    GitRepository, 
 
76
    GitRepository,
76
77
    GitRepositoryFormat,
77
78
    LocalGitRepository,
78
79
    )
79
80
 
80
81
 
81
 
def import_git_blob(texts, mapping, path, hexsha, base_inv, base_ie, parent_id, 
 
82
def import_git_blob(texts, mapping, path, hexsha, base_inv, base_ie, parent_id,
82
83
    revision_id, parent_invs, shagitmap, lookup_object, executable, symlink):
83
84
    """Import a git blob object into a bzr repository.
84
85
 
153
154
    else:
154
155
        shamap = []
155
156
    invdelta = []
156
 
    if base_ie is not None: 
 
157
    if base_ie is not None:
157
158
        old_path = base_inv.id2path(file_id)
158
159
        if base_ie.kind == "directory":
159
160
            invdelta.extend(remove_disappeared_children(old_path, base_ie.children, []))
163
164
    return (invdelta, shamap)
164
165
 
165
166
 
166
 
class SubmodulesNotSupported(BzrError):
167
 
 
168
 
    _fmt = """Submodules can not yet be imported (requires nested tree support in Bazaar)."""
 
167
class SubmodulesRequireSubtrees(BzrError):
 
168
    _fmt = """The repository you are fetching from contains submodules. Please run 'bzr upgrade --development-subtree'."""
169
169
    internal = False
170
170
 
171
171
 
172
 
def import_git_submodule(texts, mapping, path, hexsha, base_inv, base_ie, 
 
172
def import_git_submodule(texts, mapping, path, hexsha, base_inv, base_ie,
173
173
    parent_id, revision_id, parent_invs, shagitmap, lookup_object):
174
 
    raise SubmodulesNotSupported()
 
174
    file_id = mapping.generate_file_id(path)
 
175
    ie = TreeReference(file_id, urlutils.basename(path.decode("utf-8")),
 
176
        parent_id)
 
177
    ie.revision = revision_id
 
178
    if base_ie is None:
 
179
        oldpath = None
 
180
    else:
 
181
        oldpath = path
 
182
        if base_ie.kind == ie.kind and base_ie.reference_revision == ie.reference_revision:
 
183
            ie.revision = base_ie.revision
 
184
    ie.reference_revision = mapping.revision_id_foreign_to_bzr(hexsha)
 
185
    texts.insert_record_stream([FulltextContentFactory((file_id, ie.revision), (), None, "")])
 
186
    invdelta = [(oldpath, path, file_id, ie)]
 
187
    return invdelta, {}, {}
175
188
 
176
189
 
177
190
def remove_disappeared_children(path, base_children, existing_children):
186
199
    return ret
187
200
 
188
201
 
189
 
def import_git_tree(texts, mapping, path, hexsha, base_inv, base_ie, parent_id, 
 
202
def import_git_tree(texts, mapping, path, hexsha, base_inv, base_ie, parent_id,
190
203
    revision_id, parent_invs, shagitmap, lookup_object):
191
204
    """Import a git tree object into a bzr repository.
192
205
 
199
212
    invdelta = []
200
213
    file_id = mapping.generate_file_id(path)
201
214
    # We just have to hope this is indeed utf-8:
202
 
    ie = InventoryDirectory(file_id, urlutils.basename(path.decode("utf-8")), 
 
215
    ie = InventoryDirectory(file_id, urlutils.basename(path.decode("utf-8")),
203
216
        parent_id)
204
217
    if base_ie is None:
205
218
        # Newly appeared here
235
248
        child_path = osutils.pathjoin(path, name)
236
249
        if stat.S_ISDIR(mode):
237
250
            subinvdelta, grandchildmodes, subshamap = import_git_tree(
238
 
                    texts, mapping, child_path, child_hexsha, base_inv, 
 
251
                    texts, mapping, child_path, child_hexsha, base_inv,
239
252
                    base_children.get(basename), file_id, revision_id, parent_invs, shagitmap,
240
253
                    lookup_object)
241
254
            invdelta.extend(subinvdelta)
249
262
            child_modes.update(grandchildmodes)
250
263
            shamap.extend(subshamap)
251
264
        else:
252
 
            subinvdelta, subshamap = import_git_blob(texts, mapping, 
 
265
            subinvdelta, subshamap = import_git_blob(texts, mapping,
253
266
                    child_path, child_hexsha, base_inv, base_children.get(basename), file_id,
254
 
                    revision_id, parent_invs, shagitmap, lookup_object, 
 
267
                    revision_id, parent_invs, shagitmap, lookup_object,
255
268
                    mode_is_executable(mode), stat.S_ISLNK(mode))
256
269
            invdelta.extend(subinvdelta)
257
270
            shamap.extend(subshamap)
260
273
            child_modes[child_path] = mode
261
274
    # Remove any children that have disappeared
262
275
    if base_ie is not None and base_ie.kind == "directory":
263
 
        invdelta.extend(remove_disappeared_children(base_inv.id2path(file_id), 
 
276
        invdelta.extend(remove_disappeared_children(base_inv.id2path(file_id),
264
277
            base_children, existing_children))
265
278
    shamap.append((hexsha, "tree", (file_id, revision_id)))
266
279
    return invdelta, child_modes, shamap
267
280
 
268
281
 
269
 
def import_git_objects(repo, mapping, object_iter, target_git_object_retriever, 
 
282
def import_git_objects(repo, mapping, object_iter, target_git_object_retriever,
270
283
        heads, pb=None):
271
284
    """Import a set of git objects into a bzr repository.
272
285
 
305
318
            root_trees[rev.revision_id] = o.tree
306
319
            revisions[rev.revision_id] = rev
307
320
            graph.append((rev.revision_id, rev.parent_ids))
308
 
            target_git_object_retriever._idmap.add_entry(o.id, "commit", 
 
321
            target_git_object_retriever._idmap.add_entry(o.id, "commit",
309
322
                    (rev.revision_id, o.tree))
310
323
            heads.extend([p for p in o.parents if p not in checked])
311
324
        elif isinstance(o, Tag):
319
332
        if pb is not None:
320
333
            pb.update("fetching revisions", i, len(graph))
321
334
        rev = revisions[revid]
322
 
        # We have to do this here, since we have to walk the tree and 
323
 
        # we need to make sure to import the blobs / trees with the right 
 
335
        # We have to do this here, since we have to walk the tree and
 
336
        # we need to make sure to import the blobs / trees with the right
324
337
        # path; this may involve adding them more than once.
325
338
        parent_invs = []
326
339
        for parent_id in rev.parent_ids:
336
349
        else:
337
350
            base_inv = parent_invs[0]
338
351
            base_ie = base_inv.root
339
 
        inv_delta, unusual_modes, shamap = import_git_tree(repo.texts, 
340
 
                mapping, "", root_trees[revid], base_inv, base_ie, None, revid, 
 
352
        inv_delta, unusual_modes, shamap = import_git_tree(repo.texts,
 
353
                mapping, "", root_trees[revid], base_inv, base_ie, None, revid,
341
354
                parent_invs, target_git_object_retriever._idmap, lookup_object)
342
355
        target_git_object_retriever._idmap.add_entries(shamap)
343
356
        if unusual_modes != {}:
387
400
 
388
401
 
389
402
class InterGitNonGitRepository(InterGitRepository):
390
 
    """Base InterRepository that copies revisions from a Git into a non-Git 
 
403
    """Base InterRepository that copies revisions from a Git into a non-Git
391
404
    repository."""
392
405
 
393
 
    def fetch_refs(self, revision_id=None, pb=None, find_ghosts=False, 
 
406
    def fetch_refs(self, revision_id=None, pb=None, find_ghosts=False,
394
407
              mapping=None, fetch_spec=None):
395
408
        if mapping is None:
396
409
            mapping = self.source.get_mapping()
431
444
 
432
445
 
433
446
class InterRemoteGitNonGitRepository(InterGitNonGitRepository):
434
 
    """InterRepository that copies revisions from a remote Git into a non-Git 
 
447
    """InterRepository that copies revisions from a remote Git into a non-Git
435
448
    repository."""
436
449
 
437
450
    def get_target_heads(self):
457
470
                wants = determine_wants(heads)
458
471
                recorded_wants.extend(wants)
459
472
                return wants
460
 
        
 
473
 
461
474
            create_pb = None
462
475
            if pb is None:
463
476
                create_pb = pb = ui.ui_factory.nested_progress_bar()
465
478
                self.target.start_write_group()
466
479
                try:
467
480
                    objects_iter = self.source.fetch_objects(
468
 
                                record_determine_wants, graph_walker, 
 
481
                                record_determine_wants, graph_walker,
469
482
                                store.get_raw, progress)
470
 
                    import_git_objects(self.target, mapping, objects_iter, 
 
483
                    import_git_objects(self.target, mapping, objects_iter,
471
484
                            store, recorded_wants, pb)
472
485
                finally:
473
486
                    pack_hint = self.target.commit_write_group()
482
495
    def is_compatible(source, target):
483
496
        """Be compatible with GitRepository."""
484
497
        # FIXME: Also check target uses VersionedFile
485
 
        return (isinstance(source, RemoteGitRepository) and 
 
498
        return (isinstance(source, RemoteGitRepository) and
486
499
                target.supports_rich_root() and
487
500
                not isinstance(target, GitRepository))
488
501
 
489
502
 
490
503
class InterLocalGitNonGitRepository(InterGitNonGitRepository):
491
 
    """InterRepository that copies revisions from a local Git into a non-Git 
 
504
    """InterRepository that copies revisions from a local Git into a non-Git
492
505
    repository."""
493
506
 
494
507
    def fetch_objects(self, determine_wants, mapping, pb=None):
502
515
            try:
503
516
                self.target.start_write_group()
504
517
                try:
505
 
                    import_git_objects(self.target, mapping, 
506
 
                            self.source._git.object_store, 
 
518
                    import_git_objects(self.target, mapping,
 
519
                            self.source._git.object_store,
507
520
                            target_git_object_retriever, wants, pb)
508
521
                finally:
509
522
                    pack_hint = self.target.commit_write_group()
518
531
    def is_compatible(source, target):
519
532
        """Be compatible with GitRepository."""
520
533
        # FIXME: Also check target uses VersionedFile
521
 
        return (isinstance(source, LocalGitRepository) and 
 
534
        return (isinstance(source, LocalGitRepository) and
522
535
                target.supports_rich_root() and
523
536
                not isinstance(target, GitRepository))
524
537
 
531
544
            trace.note("git: %s", text)
532
545
        graphwalker = self.target._git.get_graph_walker()
533
546
        if isinstance(self.source, LocalGitRepository) and isinstance(self.target, LocalGitRepository):
534
 
            return self.source._git.fetch(self.target._git, determine_wants, 
 
547
            return self.source._git.fetch(self.target._git, determine_wants,
535
548
                progress)
536
549
        elif isinstance(self.source, LocalGitRepository) and isinstance(self.target, RemoteGitRepository):
537
550
            raise NotImplementedError
548
561
        else:
549
562
            raise AssertionError
550
563
 
551
 
    def fetch_refs(self, revision_id=None, pb=None, find_ghosts=False, 
 
564
    def fetch_refs(self, revision_id=None, pb=None, find_ghosts=False,
552
565
              mapping=None, fetch_spec=None, branches=None):
553
566
        if mapping is None:
554
567
            mapping = self.source.get_mapping()
569
582
    @staticmethod
570
583
    def is_compatible(source, target):
571
584
        """Be compatible with GitRepository."""
572
 
        return (isinstance(source, GitRepository) and 
 
585
        return (isinstance(source, GitRepository) and
573
586
                isinstance(target, GitRepository))