# HG changeset patch # User Scott Chacon <schacon@gmail.com> # Date 1240860404 25200 # Mon Apr 27 12:26:44 2009 -0700 # Node ID 13b9a020e38203760c903000bbcb387b5a260488 # Parent 9a93e8b0ec641a65e9ef3a9648a96806478c7657 gpush coming along. will now write blobs it doesn't have yet to git repo. diff --git a/dulwich/repo.py b/dulwich/repo.py --- a/dulwich/repo.py +++ b/dulwich/repo.py @@ -20,6 +20,8 @@ import os import stat +import sha +import zlib from errors import ( MissingCommitError, @@ -36,6 +38,7 @@ Tag, Tree, ) +from misc import make_sha OBJECTDIR = 'objects' SYMREF = 'ref: ' @@ -332,6 +335,22 @@ def get_blob(self, sha): return self._get_object(sha, Blob) + def write_blob(self, contents): + sha = self.write_object('blob', contents) + return sha + + def write_object(self, obj_type, obj_contents): + raw_data = "%s %d\0%s" % (obj_type, len(obj_contents), obj_contents) + git_sha = make_sha(raw_data) + git_hex_sha = git_sha.hexdigest() + if not git_hex_sha in self.object_store: + object_dir = os.path.join(self.path, OBJECTDIR, git_hex_sha[0:2]) + if not os.path.exists(object_dir): + os.mkdir(object_dir) + object_path = os.path.join(object_dir, git_hex_sha[2:38]) + data = zlib.compress(raw_data) + open(object_path, 'w').write(data) # write the object + return git_hex_sha # takes a commit object and a file path # returns the contents of that file at that commit diff --git a/git_handler.py b/git_handler.py --- a/git_handler.py +++ b/git_handler.py @@ -31,16 +31,34 @@ ## FILE LOAD AND SAVE METHODS + def map_set(self, gitsha, hgsha): + self._map_git[gitsha] = hgsha + self._map_hg[hgsha] = gitsha + + def map_hg_get(self, gitsha): + if gitsha in self._map_git: + return self._map_git[gitsha] + else: + return None + + def map_git_get(self, hgsha): + if hgsha in self._map_hg: + return self._map_hg[hgsha] + else: + return None + def load_map(self): - self._map = {} + self._map_git = {} + self._map_hg = {} if os.path.exists(self.repo.join('git-mapfile')): for line in self.repo.opener('git-mapfile'): gitsha, hgsha = line.strip().split(' ', 1) - self._map[gitsha] = hgsha + self._map_git[gitsha] = hgsha + self._map_hg[hgsha] = gitsha def save_map(self): file = self.repo.opener('git-mapfile', 'w+') - for gitsha, hgsha in self._map.iteritems(): + for gitsha, hgsha in self._map_git.iteritems(): file.write("%s %s\n" % (gitsha, hgsha)) file.close() @@ -81,10 +99,50 @@ def remote_name_to_url(self, remote_name): return self._config['remote.' + remote_name + '.url'] + def export_git_objects(self): + print "exporting git objects" + for rev in self.repo.changelog: + node = self.repo.changelog.lookup(rev) + hgsha = hex(node) + git_sha = self.map_git_get(hgsha) + if not git_sha: + self.export_hg_commit(rev) + + def export_hg_commit(self, rev): + # convert this commit into git objects + # go through the manifest, convert all blobs/trees we don't have + # write the commit object (with metadata info) + print "EXPORT" + node = self.repo.changelog.lookup(rev) + parents = self.repo.parents(rev) + + print parents # TODO: make sure parents are converted first + + ctx = self.repo.changectx(rev) + man = ctx.manifest() + for filename in man.keys(): + print "WRITE BLOB/TREE OBJECT" + print filename + fctx = ctx.filectx(filename) + file_id = hex(fctx.filenode()) + git_sha = self.map_git_get(file_id) + print git_sha + + print fctx.data() + self.git.write_blob(fctx.data()) + + print "WRITE COMMIT OBJECT" + print ctx.user() + print ctx.date() + print ctx.description() + print ctx.branch() + print ctx.tags() + + def remote_head(self, remote_name): for head, sha in self.git.remote_refs(remote_name).iteritems(): if head == 'HEAD': - return self._map[sha] + return self.map_hg_get(sha) return None def upload_pack(self, remote_name): @@ -139,15 +197,10 @@ # update Hg bookmarks bms = {} for head, sha in self.git.remote_refs(remote_name).iteritems(): - hgsha = hex_to_sha(self._map[sha]) + hgsha = hex_to_sha(self.map_hg_get(sha)) if not head == 'HEAD': bms[remote_name + '/' + head] = hgsha - if hasattr(self.repo, '_bookmarkcurrent'): - bookmarks.write(self.repo, bms) - else: - self.repo.ui.warn('bookmarks are not enabled, not writing' - ' them out!') - + bookmarks.write(self.repo, bms) def import_git_commit(self, commit): print "importing: " + commit.id @@ -162,10 +215,10 @@ p2 = "0" * 40 if len(commit.parents) > 0: sha = commit.parents[0] - p1 = self._map[sha] + p1 = self.map_hg_get(sha) if len(commit.parents) > 1: sha = commit.parents[1] - p2 = self._map[sha] + p2 = self.map_hg_get(sha) if len(commit.parents) > 2: # TODO : map extra parents to the extras file pass @@ -185,7 +238,7 @@ p2 = hex(self.repo.changelog.tip()) # save changeset to mapping file gitsha = commit.id - self._map[gitsha] = p2 + self.map_set(gitsha, p2) def getfilectx(self, source, repo, memctx, f): v = files[f] @@ -193,9 +246,6 @@ e = source.getmode(f, v) return context.memfilectx(f, data, 'l' in e, 'x' in e, copies.get(f)) - def export_git_objects(self): - pass - def check_bookmarks(self): if self.ui.config('extensions', 'hgext.bookmarks') is not None: print "YOU NEED TO SETUP BOOKMARKS"