dab975004291

Stare into the abyss.
[view raw] [browse files]
author Steve Losh <steve@stevelosh.com>
date Mon, 07 Dec 2015 15:44:37 +0000
parents 6a75b5bfa46c
children b0566e3d38e6
branches/tags (none)
files bin/unfuck-hggit-mapfile

Changes

--- /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)