/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

Merge thin-pack work.

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.shamap import GitObjectConverter
29
30
from bzrlib.plugins.git.remote import RemoteGitRepository
30
31
 
31
32
import dulwich as git
36
37
 
37
38
 
38
39
class BzrFetchGraphWalker(object):
 
40
    """GraphWalker implementation that uses a Bazaar repository."""
39
41
 
40
42
    def __init__(self, repository, mapping):
41
43
        self.repository = repository
44
46
        self.heads = set(repository.all_revision_ids())
45
47
        self.parents = {}
46
48
 
 
49
    def __iter__(self):
 
50
        return iter(self.next, None)
 
51
 
47
52
    def ack(self, sha):
48
53
        revid = self.mapping.revision_id_foreign_to_bzr(sha)
49
54
        self.remove(revid)
122
127
            raise AssertionError("Unknown blob kind, perms=%r." % (mode,))
123
128
 
124
129
 
125
 
def import_git_objects(repo, mapping, num_objects, object_iter, pb=None):
 
130
def import_git_objects(repo, mapping, object_iter, target_git_object_retriever, 
 
131
        pb=None):
126
132
    """Import a set of git objects into a bzr repository.
127
133
 
128
134
    :param repo: Bazaar repository
129
135
    :param mapping: Mapping to use
130
 
    :param num_objects: Number of objects.
131
136
    :param object_iter: Iterator over Git objects.
132
137
    """
133
138
    # TODO: a more (memory-)efficient implementation of this
134
 
    objects = {}
135
 
    for i, (o, _) in enumerate(object_iter):
136
 
        if pb is not None:
137
 
            pb.update("fetching objects", i, num_objects) 
138
 
        objects[o.id] = o
139
139
    graph = []
140
140
    root_trees = {}
141
141
    revisions = {}
142
142
    # Find and convert commit objects
143
 
    for o in objects.itervalues():
 
143
    for o in object_iter.iterobjects():
144
144
        if isinstance(o, Commit):
145
145
            rev = mapping.import_commit(o)
146
 
            root_trees[rev.revision_id] = objects[o.tree]
 
146
            root_trees[rev.revision_id] = object_iter[o.tree]
147
147
            revisions[rev.revision_id] = rev
148
148
            graph.append((rev.revision_id, rev.parent_ids))
149
149
    # Order the revisions
159
159
        inv = Inventory()
160
160
        inv.revision_id = rev.revision_id
161
161
        def lookup_object(sha):
162
 
            if sha in objects:
163
 
                return objects[sha]
164
 
            return reconstruct_git_object(repo, mapping, sha)
 
162
            if sha in object_iter:
 
163
                return object_iter[sha]
 
164
            return target_git_object_retriever(sha)
165
165
        parent_invs = [repo.get_inventory(r) for r in rev.parent_ids]
166
166
        import_git_tree(repo, mapping, "", root_tree, inv, parent_invs, 
167
167
            lookup_object)
168
168
        repo.add_revision(rev.revision_id, rev, inv)
169
169
 
170
170
 
171
 
def reconstruct_git_commit(repo, rev):
172
 
    raise NotImplementedError(self.reconstruct_git_commit)
173
 
 
174
 
 
175
171
def reconstruct_git_object(repo, mapping, sha):
176
 
    # Commit
177
 
    revid = mapping.revision_id_foreign_to_bzr(sha)
178
 
    try:
179
 
        rev = repo.get_revision(revid)
180
 
    except NoSuchRevision:
181
 
        pass
182
 
    else:
183
 
        return reconstruct_git_commit(rev)
 
172
    import pdb; pdb.set_trace()
184
173
 
185
174
    # TODO: Tree
186
175
    # TODO: Blob
199
188
        """See InterRepository.copy_content."""
200
189
        self.fetch(revision_id, pb, find_ghosts=False)
201
190
 
202
 
    def fetch(self, revision_id=None, pb=None, find_ghosts=False, 
203
 
              mapping=None):
204
 
        if mapping is None:
205
 
            mapping = self.source.get_mapping()
 
191
    def fetch_objects(self, determine_wants, mapping, pb=None):
206
192
        def progress(text):
207
193
            pb.update("git: %s" % text.rstrip("\r\n"), 0, 0)
208
 
        def determine_wants(heads):
209
 
            if revision_id is None:
210
 
                ret = heads.values()
211
 
            else:
212
 
                ret = [mapping.revision_id_bzr_to_foreign(revision_id)[0]]
213
 
            return [rev for rev in ret if not self.target.has_revision(mapping.revision_id_foreign_to_bzr(rev))]
214
194
        graph_walker = BzrFetchGraphWalker(self.target, mapping)
215
195
        create_pb = None
216
196
        if pb is None:
217
197
            create_pb = pb = ui.ui_factory.nested_progress_bar()
 
198
        target_git_object_retriever = GitObjectConverter(self.target, mapping)
 
199
        
218
200
        try:
219
201
            self.target.lock_write()
220
202
            try:
221
203
                self.target.start_write_group()
222
204
                try:
223
 
                    (num_objects, objects_iter) = \
224
 
                            self.source.fetch_objects(determine_wants, 
225
 
                                graph_walker, progress)
226
 
                    import_git_objects(self.target, mapping, num_objects, 
227
 
                                       objects_iter, pb)
 
205
                    objects_iter = self.source.fetch_objects(determine_wants, 
 
206
                                graph_walker, 
 
207
                                target_git_object_retriever.__getitem__, 
 
208
                                progress)
 
209
                    import_git_objects(self.target, mapping, objects_iter, 
 
210
                            target_git_object_retriever, pb)
228
211
                finally:
229
212
                    self.target.commit_write_group()
230
213
            finally:
233
216
            if create_pb:
234
217
                create_pb.finished()
235
218
 
 
219
    def fetch(self, revision_id=None, pb=None, find_ghosts=False, 
 
220
              mapping=None):
 
221
        if mapping is None:
 
222
            mapping = self.source.get_mapping()
 
223
        def determine_wants(heads):
 
224
            if revision_id is None:
 
225
                ret = heads.values()
 
226
            else:
 
227
                ret = [mapping.revision_id_bzr_to_foreign(revision_id)[0]]
 
228
            return [rev for rev in ret if not self.target.has_revision(mapping.revision_id_foreign_to_bzr(rev))]
 
229
        return self.fetch_objects(determine_wants, mapping, pb)
 
230
 
236
231
    @staticmethod
237
232
    def is_compatible(source, target):
238
233
        """Be compatible with GitRepository."""