15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
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
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.
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))
98
def import_git_tree(repo, mapping, path, tree, inv, parent_invs,
99
gitmap, lookup_object):
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.
102
99
:param repo: A Bzr repository object
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))
130
126
raise AssertionError("Unknown blob kind, perms=%r." % (mode,))
133
def import_git_objects(repo, mapping, object_iter, target_git_object_retriever,
129
def import_git_objects(repo, mapping, object_iter, pb=None):
135
130
"""Import a set of git objects into a bzr repository.
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)
172
166
repo.add_revision(rev.revision_id, rev, inv)
169
def reconstruct_git_commit(repo, rev):
170
raise NotImplementedError(self.reconstruct_git_commit)
173
def reconstruct_git_object(repo, mapping, sha):
175
revid = mapping.revision_id_foreign_to_bzr(sha)
177
rev = repo.get_revision(revid)
178
except NoSuchRevision:
181
return reconstruct_git_commit(rev)
185
raise KeyError("No such object %s" % sha)
175
188
class InterGitNonGitRepository(InterRepository):
177
190
_matching_repo_format = GitFormat()
184
197
"""See InterRepository.copy_content."""
185
198
self.fetch(revision_id, pb, find_ghosts=False)
187
def fetch_objects(self, determine_wants, mapping, pb=None):
200
def fetch(self, revision_id=None, pb=None, find_ghosts=False,
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:
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)
193
215
create_pb = pb = ui.ui_factory.nested_progress_bar()
194
target_git_object_retriever = GitObjectConverter(self.target, mapping)
197
217
self.target.lock_write()
199
219
self.target.start_write_group()
201
221
objects_iter = self.source.fetch_objects(determine_wants,
203
target_git_object_retriever.__getitem__,
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)
208
225
self.target.commit_write_group()
213
230
create_pb.finished()
215
def fetch(self, revision_id=None, pb=None, find_ghosts=False,
218
mapping = self.source.get_mapping()
219
def determine_wants(heads):
220
if revision_id is None:
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)
228
233
def is_compatible(source, target):
229
234
"""Be compatible with GitRepository."""