bin/unfuck-hggit-mapfile @ b0566e3d38e6
spa ce
| author | Steve Losh <steve@stevelosh.com> |
|---|---|
| date | Mon, 07 Dec 2015 15:48:10 +0000 |
| parents | dab975004291 |
| children | 4ad9d3c4ebbe |
#!/usr/bin/env python from __future__ import print_function import collections import sys import subprocess import pprint hg_dir = sys.argv[1] git_dir = sys.argv[2] nodetempl = "--template={node}\\n" prettytempl = '--pretty=format:%H' def log(msg): sys.stderr.write(str(msg) + '\n') sys.stderr.flush() def die(msg): sys.stderr.write(msg + '\n') sys.exit(1) def hg(*args): l = ["hg", "--repository", "./" + hg_dir] + list(args) return subprocess.check_output(l).strip() def git(*args): l = ["git", "-C", "./" + git_dir] + list(args) return subprocess.check_output(l).strip() def find_hg_root_revision(): rev = hg('log', '-r', 'roots(all())', nodetempl).split() if len(rev) != 1: die("Can't determine a single hg root revision.") return rev[0] def find_git_root_revision(): rev = git('log', '--max-parents=0', prettytempl).split() if len(rev) != 1: die("Can't determine a single git root revision.") return rev[0] def find_git_children_mapping(): result = collections.defaultdict(list) for l in git('rev-list', '--all', '--parents').split('\n'): parts = l.split() for parent in parts[1:]: result[parent].append(parts[0]) return result def find_hg_children(rev): return hg('log', '-r', 'children(%s)' % rev, nodetempl).split() def get_hg_desc(rev): return hg('log', '-r', rev, '--template={desc}') def get_git_desc(rev): return git('log', '--format=%B', '-n', '1', rev) hg_root = find_hg_root_revision() git_root = find_git_root_revision() git_children_map = find_git_children_mapping() # hg -> git mapping = {hg_root: git_root} todo = [hg_root] n = 0 while todo: log(n) n += 1 h = todo.pop() g = mapping[h] hg_children = find_hg_children(h) git_children = git_children_map[g] if len(hg_children) == len(git_children) == 1: if hg_children[0] not in mapping: mapping[hg_children[0]] = git_children[0] todo.append(hg_children[0]) else: log("Multiple children, attempting to differentiate") for hg_child in hg_children: hg_desc = get_hg_desc(hg_child) matching = [ git_child for git_child in git_children if hg_desc.startswith(get_git_desc(git_child)) ] if len(matching) == 1: log("Found a match based on message for %s" % hg_child) if hg_child not in mapping: mapping[hg_child] = matching[0] todo.append(hg_child) else: log("no match found...") for h, g in mapping.items(): print(g, h)