/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

Try to import nothing other than __init__ when not opening git repositories.

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
17
from bzrlib import osutils, ui, urlutils
18
 
from bzrlib.errors import InvalidRevisionId, NoSuchRevision
 
18
from bzrlib.errors import InvalidRevisionId
19
19
from bzrlib.inventory import Inventory
20
20
from bzrlib.repository import InterRepository
21
21
from bzrlib.trace import info
26
26
        GitRepository, 
27
27
        GitFormat,
28
28
        )
29
 
from bzrlib.plugins.git.converter import GitObjectConverter
30
29
from bzrlib.plugins.git.remote import RemoteGitRepository
31
30
 
32
31
import dulwich as git
75
74
        return None
76
75
 
77
76
 
78
 
def import_git_blob(repo, mapping, path, blob, inv, parent_invs, gitmap, executable):
 
77
def import_git_blob(repo, mapping, path, blob, inv, parent_invs, executable):
79
78
    """Import a git blob object into a bzr repository.
80
79
 
81
80
    :param repo: bzr repository
92
91
    ie.text_size = len(blob.data)
93
92
    ie.text_sha1 = osutils.sha_string(blob.data)
94
93
    ie.executable = executable
95
 
    gitmap._idmap.add_entry(blob.sha().hexdigest(), "blob", (ie.file_id, ie.revision))
96
 
 
97
 
 
98
 
def import_git_tree(repo, mapping, path, tree, inv, parent_invs, 
99
 
                    gitmap, lookup_object):
 
94
 
 
95
 
 
96
def import_git_tree(repo, mapping, path, tree, inv, parent_invs, lookup_object):
100
97
    """Import a git tree object into a bzr repository.
101
98
 
102
99
    :param repo: A Bzr repository object
111
108
        [])
112
109
    ie = inv.add_path(path, "directory", file_id)
113
110
    ie.revision = text_revision
114
 
    gitmap._idmap.add_entry(tree.sha().hexdigest(), "tree", (file_id, text_revision))
115
111
    for mode, name, hexsha in tree.entries():
116
112
        entry_kind = (mode & 0700000) / 0100000
117
113
        basename = name.decode("utf-8")
121
117
            child_path = urlutils.join(path, name)
122
118
        if entry_kind == 0:
123
119
            tree = lookup_object(hexsha)
124
 
            import_git_tree(repo, mapping, child_path, tree, inv, parent_invs, gitmap, lookup_object)
 
120
            import_git_tree(repo, mapping, child_path, tree, inv, parent_invs, lookup_object)
125
121
        elif entry_kind == 1:
126
122
            blob = lookup_object(hexsha)
127
123
            fs_mode = mode & 0777
128
 
            import_git_blob(repo, mapping, child_path, blob, inv, parent_invs, gitmap, bool(fs_mode & 0111))
 
124
            import_git_blob(repo, mapping, child_path, blob, inv, parent_invs, bool(fs_mode & 0111))
129
125
        else:
130
126
            raise AssertionError("Unknown blob kind, perms=%r." % (mode,))
131
127
 
132
128
 
133
 
def import_git_objects(repo, mapping, object_iter, target_git_object_retriever, 
134
 
        pb=None):
 
129
def import_git_objects(repo, mapping, num_objects, object_iter, pb=None):
135
130
    """Import a set of git objects into a bzr repository.
136
131
 
137
132
    :param repo: Bazaar repository
138
133
    :param mapping: Mapping to use
 
134
    :param num_objects: Number of objects.
139
135
    :param object_iter: Iterator over Git objects.
140
136
    """
141
137
    # TODO: a more (memory-)efficient implementation of this
 
138
    objects = {}
 
139
    for i, (o, _) in enumerate(object_iter):
 
140
        if pb is not None:
 
141
            pb.update("fetching objects", i, num_objects) 
 
142
        objects[o.id] = o
142
143
    graph = []
143
144
    root_trees = {}
144
145
    revisions = {}
145
146
    # Find and convert commit objects
146
 
    for o in object_iter.iterobjects():
 
147
    for o in objects.itervalues():
147
148
        if isinstance(o, Commit):
148
149
            rev = mapping.import_commit(o)
149
 
            root_trees[rev.revision_id] = object_iter[o.tree]
 
150
            root_trees[rev.revision_id] = objects[o.tree]
150
151
            revisions[rev.revision_id] = rev
151
152
            graph.append((rev.revision_id, rev.parent_ids))
152
 
            target_git_object_retriever._idmap.add_entry(o.sha().hexdigest(), "commit", (rev.revision_id, o._tree))
153
153
    # Order the revisions
154
154
    # Create the inventory objects
155
155
    for i, revid in enumerate(topo_sort(graph)):
163
163
        inv = Inventory()
164
164
        inv.revision_id = rev.revision_id
165
165
        def lookup_object(sha):
166
 
            if sha in object_iter:
167
 
                return object_iter[sha]
168
 
            return target_git_object_retriever[sha]
 
166
            if sha in objects:
 
167
                return objects[sha]
 
168
            return reconstruct_git_object(repo, mapping, sha)
169
169
        parent_invs = [repo.get_inventory(r) for r in rev.parent_ids]
170
170
        import_git_tree(repo, mapping, "", root_tree, inv, parent_invs, 
171
 
            target_git_object_retriever, lookup_object)
 
171
            lookup_object)
172
172
        repo.add_revision(rev.revision_id, rev, inv)
173
173
 
174
174
 
 
175
def reconstruct_git_commit(repo, rev):
 
176
    raise NotImplementedError(self.reconstruct_git_commit)
 
177
 
 
178
 
 
179
def reconstruct_git_object(repo, mapping, sha):
 
180
    # Commit
 
181
    revid = mapping.revision_id_foreign_to_bzr(sha)
 
182
    try:
 
183
        rev = repo.get_revision(revid)
 
184
    except NoSuchRevision:
 
185
        pass
 
186
    else:
 
187
        return reconstruct_git_commit(rev)
 
188
 
 
189
    # TODO: Tree
 
190
    # TODO: Blob
 
191
    raise KeyError("No such object %s" % sha)
 
192
 
 
193
 
175
194
class InterGitNonGitRepository(InterRepository):
176
195
 
177
196
    _matching_repo_format = GitFormat()
184
203
        """See InterRepository.copy_content."""
185
204
        self.fetch(revision_id, pb, find_ghosts=False)
186
205
 
187
 
    def fetch_objects(self, determine_wants, mapping, pb=None):
 
206
    def fetch(self, revision_id=None, pb=None, find_ghosts=False, 
 
207
              mapping=None):
 
208
        if mapping is None:
 
209
            mapping = self.source.get_mapping()
188
210
        def progress(text):
189
211
            pb.update("git: %s" % text.rstrip("\r\n"), 0, 0)
 
212
        def determine_wants(heads):
 
213
            if revision_id is None:
 
214
                ret = heads.values()
 
215
            else:
 
216
                ret = [mapping.revision_id_bzr_to_foreign(revision_id)[0]]
 
217
            return [rev for rev in ret if not self.target.has_revision(mapping.revision_id_foreign_to_bzr(rev))]
190
218
        graph_walker = BzrFetchGraphWalker(self.target, mapping)
191
219
        create_pb = None
192
220
        if pb is None:
193
221
            create_pb = pb = ui.ui_factory.nested_progress_bar()
194
 
        target_git_object_retriever = GitObjectConverter(self.target, mapping)
195
 
        
196
222
        try:
197
223
            self.target.lock_write()
198
224
            try:
199
225
                self.target.start_write_group()
200
226
                try:
201
 
                    objects_iter = self.source.fetch_objects(determine_wants, 
202
 
                                graph_walker, 
203
 
                                target_git_object_retriever.__getitem__, 
204
 
                                progress)
205
 
                    import_git_objects(self.target, mapping, objects_iter, 
206
 
                            target_git_object_retriever, 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)
207
232
                finally:
208
233
                    self.target.commit_write_group()
209
234
            finally:
212
237
            if create_pb:
213
238
                create_pb.finished()
214
239
 
215
 
    def fetch(self, revision_id=None, pb=None, find_ghosts=False, 
216
 
              mapping=None):
217
 
        if mapping is None:
218
 
            mapping = self.source.get_mapping()
219
 
        def determine_wants(heads):
220
 
            if revision_id is None:
221
 
                ret = heads.values()
222
 
            else:
223
 
                ret = [mapping.revision_id_bzr_to_foreign(revision_id)[0]]
224
 
            return [rev for rev in ret if not self.target.has_revision(mapping.revision_id_foreign_to_bzr(rev))]
225
 
        return self.fetch_objects(determine_wants, mapping, pb)
226
 
 
227
240
    @staticmethod
228
241
    def is_compatible(source, target):
229
242
        """Be compatible with GitRepository."""