/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

Add FOSDEM roundtripping notes.

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, object_iter, pb=None):
135
130
    """Import a set of git objects into a bzr repository.
136
131
 
137
132
    :param repo: Bazaar repository
149
144
            root_trees[rev.revision_id] = object_iter[o.tree]
150
145
            revisions[rev.revision_id] = rev
151
146
            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
147
    # Order the revisions
154
148
    # Create the inventory objects
155
149
    for i, revid in enumerate(topo_sort(graph)):
165
159
        def lookup_object(sha):
166
160
            if sha in object_iter:
167
161
                return object_iter[sha]
168
 
            return target_git_object_retriever[sha]
 
162
            return reconstruct_git_object(repo, mapping, sha)
169
163
        parent_invs = [repo.get_inventory(r) for r in rev.parent_ids]
170
164
        import_git_tree(repo, mapping, "", root_tree, inv, parent_invs, 
171
 
            target_git_object_retriever, lookup_object)
 
165
            lookup_object)
172
166
        repo.add_revision(rev.revision_id, rev, inv)
173
167
 
174
168
 
 
169
def reconstruct_git_commit(repo, rev):
 
170
    raise NotImplementedError(self.reconstruct_git_commit)
 
171
 
 
172
 
 
173
def reconstruct_git_object(repo, mapping, sha):
 
174
    # Commit
 
175
    revid = mapping.revision_id_foreign_to_bzr(sha)
 
176
    try:
 
177
        rev = repo.get_revision(revid)
 
178
    except NoSuchRevision:
 
179
        pass
 
180
    else:
 
181
        return reconstruct_git_commit(rev)
 
182
 
 
183
    # TODO: Tree
 
184
    # TODO: Blob
 
185
    raise KeyError("No such object %s" % sha)
 
186
 
 
187
 
175
188
class InterGitNonGitRepository(InterRepository):
176
189
 
177
190
    _matching_repo_format = GitFormat()
184
197
        """See InterRepository.copy_content."""
185
198
        self.fetch(revision_id, pb, find_ghosts=False)
186
199
 
187
 
    def fetch_objects(self, determine_wants, mapping, pb=None):
 
200
    def fetch(self, revision_id=None, pb=None, find_ghosts=False, 
 
201
              mapping=None):
 
202
        if mapping is None:
 
203
            mapping = self.source.get_mapping()
188
204
        def progress(text):
189
205
            pb.update("git: %s" % text.rstrip("\r\n"), 0, 0)
 
206
        def determine_wants(heads):
 
207
            if revision_id is None:
 
208
                ret = heads.values()
 
209
            else:
 
210
                ret = [mapping.revision_id_bzr_to_foreign(revision_id)[0]]
 
211
            return [rev for rev in ret if not self.target.has_revision(mapping.revision_id_foreign_to_bzr(rev))]
190
212
        graph_walker = BzrFetchGraphWalker(self.target, mapping)
191
213
        create_pb = None
192
214
        if pb is None:
193
215
            create_pb = pb = ui.ui_factory.nested_progress_bar()
194
 
        target_git_object_retriever = GitObjectConverter(self.target, mapping)
195
 
        
196
216
        try:
197
217
            self.target.lock_write()
198
218
            try:
199
219
                self.target.start_write_group()
200
220
                try:
201
221
                    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)
 
222
                                graph_walker, progress)
 
223
                    import_git_objects(self.target, mapping, objects_iter, pb)
207
224
                finally:
208
225
                    self.target.commit_write_group()
209
226
            finally:
212
229
            if create_pb:
213
230
                create_pb.finished()
214
231
 
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
232
    @staticmethod
228
233
    def is_compatible(source, target):
229
234
        """Be compatible with GitRepository."""