Mercurial > hg-git
changeset 165:cb922a0ca22d
almost got everything working
author | Scott Chacon <schacon@gmail.com> |
---|---|
date | Mon, 01 Jun 2009 14:57:19 -0700 |
parents | 7e98757deadc |
children | 405a915bf352 |
files | __init__.py git_handler.py hgrepo.py |
diffstat | 3 files changed, 146 insertions(+), 16 deletions(-) [+] |
line wrap: on
line diff
--- a/__init__.py Fri May 29 13:10:14 2009 -0700 +++ b/__init__.py Mon Jun 01 14:57:19 2009 -0700 @@ -20,8 +20,9 @@ from git_handler import GitHandler # support for `hg clone git://github.com/defunkt/facebox.git` -import gitrepo +import gitrepo, hgrepo hg.schemes['git'] = gitrepo +hg.schemes['file'] = hgrepo def gclone(ui, git_url, hg_repo_path=None): # determine new repo name @@ -32,6 +33,8 @@ hg_repo_path += '-hg' dest_repo = hg.repository(ui, hg_repo_path, create=True) + print dest_repo + # fetch the initial git data git = GitHandler(dest_repo, ui) git.remote_add('origin', git_url)
--- a/git_handler.py Fri May 29 13:10:14 2009 -0700 +++ b/git_handler.py Mon Jun 01 14:57:19 2009 -0700 @@ -284,12 +284,13 @@ extra_message += "rename : " + oldfile + " => " + newfile + "\n" for key, value in extra.iteritems(): - if key in ['committer', 'encoding', 'branch', 'hg-git', 'git']: + if key in ['committer', 'encoding', 'branch', 'hg-git']: continue else: add_extras = True extra_message += "extra : " + key + " : " + urllib.quote(value) + "\n" + if add_extras: commit['message'] += "\n--HG--\n" + extra_message @@ -635,7 +636,6 @@ split = message.split("\n\n--HG--\n", 1) renames = {} extra = {} - files = [] branch = False if len(split) == 2: message, meta = split @@ -651,15 +651,13 @@ renames[after] = before if command == 'branch': branch = data - if command == 'files': - files.append(data) if command == 'extra': before, after = data.split(" : ", 1) extra[before] = urllib.unquote(after) - return (message, renames, branch, files, extra) + return (message, renames, branch, extra) def pseudo_import_git_commit(self, commit): - (strip_message, hg_renames, hg_branch) = self.extract_hg_metadata(commit.message) + (strip_message, hg_renames, hg_branch, extra) = self.extract_hg_metadata(commit.message) cs = self.map_hg_get(commit.id) p1 = nullid p2 = nullid @@ -685,11 +683,11 @@ # TODO : Do something less coarse-grained than try/except on the # get_file call for removed files - (strip_message, hg_renames, hg_branch, files, extra) = self.extract_hg_metadata(commit.message) + (strip_message, hg_renames, hg_branch, extra) = self.extract_hg_metadata(commit.message) # get a list of the changed, added, removed files files = self.git.get_files_changed(commit) - + date = (commit.author_time, -commit.author_timezone) text = strip_message @@ -714,7 +712,7 @@ def commit_octopus(p1, p2): ctx = context.memctx(self.repo, (p1, p2), text, files, getfilectx, commit.author, date, {'hg-git': 'octopus'}) - return hex(self.repo.commitctx(ctx)) + return hex(self.repo.commitctx(ctx, None)) octopus = len(gparents) > 2 p2 = gparents.pop() @@ -725,15 +723,17 @@ else: if gparents: p1 = gparents.pop() + + files = list(set(files)) - # wierd hack for explicit file renames in first but not second branch + pa = None if not (p2 == nullid): - vals = [item for item in self.renames[p1].values() if not item in self.renames[p2].values()] - for removefile in vals: - files.remove(removefile) + node1 = self.repo.changectx(p1) + node2 = self.repo.changectx(p2) + pa = node1.ancestor(node2) + author = commit.author - extra = {} if ' <none@none>' in commit.author: author = commit.author[:-12] @@ -756,7 +756,8 @@ ctx = context.memctx(self.repo, (p1, p2), text, files, getfilectx, author, date, extra) - node = self.repo.commitctx(ctx) + + node = self.repo.commitctx(ctx, pa) # save changeset to mapping file cs = hex(node)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hgrepo.py Mon Jun 01 14:57:19 2009 -0700 @@ -0,0 +1,126 @@ +from mercurial import localrepo, lock, node +from mercurial import changelog, dirstate, filelog, manifest, context, weakref +from mercurial.node import bin, hex, nullid, nullrev, short + +class hgrepo(localrepo.localrepository): + + def commitctx(self, wctx, ancestor): + + tr = None + valid = 0 # don't save the dirstate if this isn't set + try: + force=False + force_editor=False + empty_ok=False + use_dirstate=False + update_dirstate=False + + commit = sorted(wctx.modified() + wctx.added()) + remove = wctx.removed() + extra = wctx.extra().copy() + branchname = extra['branch'] + user = wctx.user() + text = wctx.description() + + p1, p2 = [p.node() for p in wctx.parents()] + c1 = self.changelog.read(p1) + c2 = self.changelog.read(p2) + m1 = self.manifest.read(c1[0]).copy() + m2 = self.manifest.read(c2[0]) + ma = None + if ancestor: + ma = ancestor.manifest() + + xp1 = hex(p1) + if p2 == nullid: xp2 = '' + else: xp2 = hex(p2) + + tr = self.transaction() + trp = weakref.proxy(tr) + + # retarded. this is retarded. + for f in m1: + if (f in m2) and (not f in commit) and (not m1[f] == m2[f]): + commit.append(f) + + # check in files + new = {} + changed = [] + linkrev = len(self) + for f in commit: + self.ui.note(f + "\n") + try: + fctx = wctx.filectx(f) + newflags = fctx.flags() + new[f] = self.filecommit(fctx, m1, m2, linkrev, trp, changed) + if ((not changed or changed[-1] != f) and + m2.get(f) != new[f]): + # mention the file in the changelog if some + # flag changed, even if there was no content + # change. + if m1.flags(f) != newflags: + changed.append(f) + m1.set(f, newflags) + + except (OSError, IOError): + remove.append(f) + + print 'CHANGED' + print changed + + updated, added = [], [] + for f in sorted(changed): + if f in m1 or f in m2: + updated.append(f) + else: + added.append(f) + + # update manifest + m1.update(new) + removed = [f for f in sorted(remove) if f in m1 or f in m2] + removed1 = [] + + for f in removed: + if f in m1: + del m1[f] + removed1.append(f) + else: + if ma and (f in ma): + del ma[f] + removed.remove(f) + + mn = self.manifest.add(m1, trp, linkrev, c1[0], c2[0], + (new, removed1)) + + lines = [line.rstrip() for line in text.rstrip().splitlines()] + while lines and not lines[0]: + del lines[0] + if not lines and use_dirstate: + raise util.Abort(_("empty commit message")) + text = '\n'.join(lines) + + self.changelog.delayupdate() + n = self.changelog.add(mn, changed + removed, text, trp, p1, p2, + user, wctx.date(), extra) + p = lambda: self.changelog.writepending() and self.root or "" + self.hook('pretxncommit', throw=True, node=hex(n), parent1=xp1, + parent2=xp2, pending=p) + self.changelog.finalize(trp) + tr.close() + + if self.branchcache: + self.branchtags() + + if update_dirstate: + self.dirstate.setparents(n) + valid = 1 # our dirstate updates are complete + + self.hook("commit", node=hex(n), parent1=xp1, parent2=xp2) + return n + finally: + if not valid: # don't save our updated dirstate + self.dirstate.invalidate() + del tr + + +instance = hgrepo