# HG changeset patch # User Steve Losh # Date 1449503077 0 # Node ID dab9750042910906db9155be0fbcdc0029215380 # Parent 6a75b5bfa46ce1bb4aff4e3782a7fc56dd8fcdf7 Stare into the abyss. diff -r 6a75b5bfa46c -r dab975004291 bin/unfuck-hggit-mapfile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bin/unfuck-hggit-mapfile Mon Dec 07 15:44:37 2015 +0000 @@ -0,0 +1,98 @@ +#!/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)