/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
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)
70
75
        return None
71
76
 
72
77
 
73
 
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):
74
79
    """Import a git blob object into a bzr repository.
75
80
 
76
81
    :param repo: bzr repository
87
92
    ie.text_size = len(blob.data)
88
93
    ie.text_sha1 = osutils.sha_string(blob.data)
89
94
    ie.executable = executable
90
 
 
91
 
 
92
 
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):
93
100
    """Import a git tree object into a bzr repository.
94
101
 
95
102
    :param repo: A Bzr repository object
104
111
        [])
105
112
    ie = inv.add_path(path, "directory", file_id)
106
113
    ie.revision = text_revision
 
114
    gitmap._idmap.add_entry(tree.sha().hexdigest(), "tree", (file_id, text_revision))
107
115
    for mode, name, hexsha in tree.entries():
108
116
        entry_kind = (mode & 0700000) / 0100000
109
117
        basename = name.decode("utf-8")
113
121
            child_path = urlutils.join(path, name)
114
122
        if entry_kind == 0:
115
123
            tree = lookup_object(hexsha)
116
 
            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)
117
125
        elif entry_kind == 1:
118
126
            blob = lookup_object(hexsha)
119
127
            fs_mode = mode & 0777
120
 
            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))
121
129
        else:
122
130
            raise AssertionError("Unknown blob kind, perms=%r." % (mode,))
123
131
 
124
132
 
125
 
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):
126
135
    """Import a set of git objects into a bzr repository.
127
136
 
128
137
    :param repo: Bazaar repository
129
138
    :param mapping: Mapping to use
130
 
    :param num_objects: Number of objects.
131
139
    :param object_iter: Iterator over Git objects.
132
140
    """
133
141
    # 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
142
    graph = []
140
143
    root_trees = {}
141
144
    revisions = {}
142
145
    # Find and convert commit objects
143
 
    for o in objects.itervalues():
 
146
    for o in object_iter.iterobjects():
144
147
        if isinstance(o, Commit):
145
148
            rev = mapping.import_commit(o)
146
 
            root_trees[rev.revision_id] = objects[o.tree]
 
149
            root_trees[rev.revision_id] = object_iter[o.tree]
147
150
            revisions[rev.revision_id] = rev
148
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))
149
153
    # Order the revisions
150
154
    # Create the inventory objects
151
155
    for i, revid in enumerate(topo_sort(graph)):
159
163
        inv = Inventory()
160
164
        inv.revision_id = rev.revision_id
161
165
        def lookup_object(sha):
162
 
            if sha in objects:
163
 
                return objects[sha]
164
 
            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]
165
169
        parent_invs = [repo.get_inventory(r) for r in rev.parent_ids]
166
170
        import_git_tree(repo, mapping, "", root_tree, inv, parent_invs, 
167
 
            lookup_object)
 
171
            target_git_object_retriever, lookup_object)
168
172
        repo.add_revision(rev.revision_id, rev, inv)
169
173
 
170
174
 
171
 
def reconstruct_git_commit(repo, rev):
172
 
    raise NotImplementedError(self.reconstruct_git_commit)
173
 
 
174
 
 
175
 
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)
184
 
 
185
 
    # TODO: Tree
186
 
    # TODO: Blob
187
 
    raise KeyError("No such object %s" % sha)
188
 
 
189
 
 
190
175
class InterGitNonGitRepository(InterRepository):
191
176
 
192
177
    _matching_repo_format = GitFormat()
199
184
        """See InterRepository.copy_content."""
200
185
        self.fetch(revision_id, pb, find_ghosts=False)
201
186
 
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()
 
187
    def fetch_objects(self, determine_wants, mapping, pb=None):
206
188
        def progress(text):
207
189
            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
190
        graph_walker = BzrFetchGraphWalker(self.target, mapping)
215
191
        create_pb = None
216
192
        if pb is None:
217
193
            create_pb = pb = ui.ui_factory.nested_progress_bar()
 
194
        target_git_object_retriever = GitObjectConverter(self.target, mapping)
 
195
        
218
196
        try:
219
197
            self.target.lock_write()
220
198
            try:
221
199
                self.target.start_write_group()
222
200
                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)
 
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)
228
207
                finally:
229
208
                    self.target.commit_write_group()
230
209
            finally:
233
212
            if create_pb:
234
213
                create_pb.finished()
235
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
 
236
227
    @staticmethod
237
228
    def is_compatible(source, target):
238
229
        """Be compatible with GitRepository."""