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
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
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.
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
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))
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.
99
102
:param repo: A Bzr repository object
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))
126
130
raise AssertionError("Unknown blob kind, perms=%r." % (mode,))
129
def import_git_objects(repo, mapping, object_iter, pb=None):
133
def import_git_objects(repo, mapping, object_iter, target_git_object_retriever,
130
135
"""Import a set of git objects into a bzr repository.
132
137
:param repo: Bazaar repository
144
149
root_trees[rev.revision_id] = object_iter[o.tree]
145
150
revisions[rev.revision_id] = rev
146
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))
147
153
# Order the revisions
148
154
# Create the inventory objects
149
155
for i, revid in enumerate(topo_sort(graph)):
159
165
def lookup_object(sha):
160
166
if sha in object_iter:
161
167
return object_iter[sha]
162
return reconstruct_git_object(repo, mapping, sha)
168
return target_git_object_retriever[sha]
163
169
parent_invs = [repo.get_inventory(r) for r in rev.parent_ids]
164
170
import_git_tree(repo, mapping, "", root_tree, inv, parent_invs,
171
target_git_object_retriever, lookup_object)
166
172
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)
188
175
class InterGitNonGitRepository(InterRepository):
190
177
_matching_repo_format = GitFormat()
197
184
"""See InterRepository.copy_content."""
198
185
self.fetch(revision_id, pb, find_ghosts=False)
200
def fetch(self, revision_id=None, pb=None, find_ghosts=False,
203
mapping = self.source.get_mapping()
187
def fetch_objects(self, determine_wants, mapping, pb=None):
204
188
def progress(text):
205
189
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))]
212
190
graph_walker = BzrFetchGraphWalker(self.target, mapping)
215
193
create_pb = pb = ui.ui_factory.nested_progress_bar()
194
target_git_object_retriever = GitObjectConverter(self.target, mapping)
217
197
self.target.lock_write()
219
199
self.target.start_write_group()
221
201
objects_iter = self.source.fetch_objects(determine_wants,
222
graph_walker, progress)
223
import_git_objects(self.target, mapping, objects_iter, pb)
203
target_git_object_retriever.__getitem__,
205
import_git_objects(self.target, mapping, objects_iter,
206
target_git_object_retriever, pb)
225
208
self.target.commit_write_group()
230
213
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)
233
228
def is_compatible(source, target):
234
229
"""Be compatible with GitRepository."""