bin/remap-hggit-mapfile @ d1b9a524e5fe default tip
More
| author | Steve Losh <steve@stevelosh.com> |
|---|---|
| date | Wed, 22 Oct 2025 15:48:44 -0400 |
| parents | 4e0ee24c82a7 |
| children | (none) |
#!/usr/bin/env python3 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().decode('utf-8') def git(*args): l = ["git", "-C", git_dir] + list(args) return subprocess.check_output(l).strip().decode('utf-8') 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_mapping(): result = collections.defaultdict(list) for l in hg('log', '--template', '{node} {p1node} {p2node}\\n').split('\n'): parts = l.split() for parent in parts[1:]: if parent != "0000000000000000000000000000000000000": 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() hg_children_map = find_hg_children_mapping() git_children_map = find_git_children_mapping() # hg -> git mapping = {hg_root: git_root} todo = [hg_root] n = 0 while todo: h = todo.pop() g = mapping[h] log("%4d %s %s" % (n, h[:12], g[:12])) n += 1 hg_children = hg_children_map[h] git_children = git_children_map[g] if len(hg_children) == len(git_children) == 0: log("Head node, no children...") elif 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 (%d hg / %d git) children, attempting to differentiate" % (len(hg_children), len(git_children))) 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).split('\n')[0]) ] 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("already done, skipping...") elif len(matching) == 0: log("no match found...") else: log("multiple matches found...") for h, g in mapping.items(): print(g, h)