/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

Partially fix pull.

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
 
18
from bzrlib.errors import InvalidRevisionId, NoSuchRevision
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
29
30
from bzrlib.plugins.git.remote import RemoteGitRepository
30
31
 
31
32
import dulwich as git
74
75
        return None
75
76
 
76
77
 
77
 
def import_git_blob(repo, mapping, path, blob, inv, parent_invs, executable):
 
78
def import_git_blob(repo, mapping, path, blob, inv, parent_invs, gitmap, executable):
78
79
    """Import a git blob object into a bzr repository.
79
80
 
80
81
    :param repo: bzr repository
91
92
    ie.text_size = len(blob.data)
92
93
    ie.text_sha1 = osutils.sha_string(blob.data)
93
94
    ie.executable = executable
94
 
 
95
 
 
96
 
def import_git_tree(repo, mapping, path, tree, inv, parent_invs, lookup_object):
 
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):
97
100
    """Import a git tree object into a bzr repository.
98
101
 
99
102
    :param repo: A Bzr repository object
108
111
        [])
109
112
    ie = inv.add_path(path, "directory", file_id)
110
113
    ie.revision = text_revision
 
114
    gitmap._idmap.add_entry(tree.sha().hexdigest(), "tree", (file_id, text_revision))
111
115
    for mode, name, hexsha in tree.entries():
112
116
        entry_kind = (mode & 0700000) / 0100000
113
117
        basename = name.decode("utf-8")
117
121
            child_path = urlutils.join(path, name)
118
122
        if entry_kind == 0:
119
123
            tree = lookup_object(hexsha)
120
 
            import_git_tree(repo, mapping, child_path, tree, inv, parent_invs, lookup_object)
 
124
            import_git_tree(repo, mapping, child_path, tree, inv, parent_invs, gitmap, lookup_object)
121
125
        elif entry_kind == 1:
122
126
            blob = lookup_object(hexsha)
123
127
            fs_mode = mode & 0777
124
 
            import_git_blob(repo, mapping, child_path, blob, inv, parent_invs, bool(fs_mode & 0111))
 
128
            import_git_blob(repo, mapping, child_path, blob, inv, parent_invs, gitmap, bool(fs_mode & 0111))
125
129
        else:
126
130
            raise AssertionError("Unknown blob kind, perms=%r." % (mode,))
127
131
 
128
132
 
129
 
def import_git_objects(repo, mapping, num_objects, object_iter, pb=None):
 
133
def import_git_objects(repo, mapping, object_iter, target_git_object_retriever, 
 
134
        pb=None):
130
135
    """Import a set of git objects into a bzr repository.
131
136
 
132
137
    :param repo: Bazaar repository
133
138
    :param mapping: Mapping to use
134
 
    :param num_objects: Number of objects.
135
139
    :param object_iter: Iterator over Git objects.
136
140
    """
137
141
    # 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
143
142
    graph = []
144
143
    root_trees = {}
145
144
    revisions = {}
146
145
    # Find and convert commit objects
147
 
    for o in objects.itervalues():
 
146
    for o in object_iter.iterobjects():
148
147
        if isinstance(o, Commit):
149
148
            rev = mapping.import_commit(o)
150
 
            root_trees[rev.revision_id] = objects[o.tree]
 
149
            root_trees[rev.revision_id] = object_iter[o.tree]
151
150
            revisions[rev.revision_id] = rev
152
151
            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 objects:
167
 
                return objects[sha]
168
 
            return reconstruct_git_object(repo, mapping, sha)
 
166
            if sha in object_iter:
 
167
                return object_iter[sha]
 
168
            return target_git_object_retriever[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
 
            lookup_object)
 
171
            target_git_object_retriever, 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
 
 
194
175
class InterGitNonGitRepository(InterRepository):
195
176
 
196
177
    _matching_repo_format = GitFormat()
203
184
        """See InterRepository.copy_content."""
204
185
        self.fetch(revision_id, pb, find_ghosts=False)
205
186
 
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()
 
187
    def fetch_objects(self, determine_wants, mapping, pb=None):
210
188
        def progress(text):
211
189
            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))]
218
190
        graph_walker = BzrFetchGraphWalker(self.target, mapping)
219
191
        create_pb = None
220
192
        if pb is None:
221
193
            create_pb = pb = ui.ui_factory.nested_progress_bar()
 
194
        target_git_object_retriever = GitObjectConverter(self.target, mapping)
 
195
        
222
196
        try:
223
197
            self.target.lock_write()
224
198
            try:
225
199
                self.target.start_write_group()
226
200
                try:
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)
 
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)
232
207
                finally:
233
208
                    self.target.commit_write_group()
234
209
            finally:
237
212
            if create_pb:
238
213
                create_pb.finished()
239
214
 
 
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
 
240
227
    @staticmethod
241
228
    def is_compatible(source, target):
242
229
        """Be compatible with GitRepository."""