# just a small script to convert a bk-repo to git.

import os
import time

# start with some config...
bk_dir = "/home/andersg/xmms2"
git_dir = "/home/andersg/xmms2.git"
tmp_dir = "/tmp/xmms2-export"

#bk only have "email" not full name.
committers = {
    "andersg@0x63.nu": "Anders Gustafsson",
    "andersg@chernushka.(none)": "Anders Gustafsson",
    "andersg@genesis.xmms.se": "Anders Gustafsson",
    "andersg@netintact.se": "Anders Gustafsson",
    "andersg@xmms.org": "Anders Gustafsson",
    "blow@hal.(none)": "Anders Gustafsson",
    "cmorgan@captainmorgan.(none)": "Chris Morgan",
    "daniel@nittionio.nu": "Daniel Svensson",
    "eleusis@eleusis.f2o.org": "Sham Chukoury",
    "jlt_speex@shamrock.dyndns.org": "Jens Taprogge",
    "jlt_xmms2@shamrock.dyndns.org": "Jens Taprogge",
    "lindgren@debian.(none)": "Michael Lindgren",
    "lindgren@debian.as": "Michael Lindgren",
    "ln@maggie.taprogge.wh": "Jens Taprogge",
    "ln@shamrock.dyndns.org": "Jens Taprogge",
    "nano@insomnia.(none)": "Daniel Svensson",
    "nano@insomnia.nittionio.nu": "Daniel Svensson",
    "nano@neurozine.(none)": "Daniel Svensson",
    "nano@nittionio.nu": "Daniel Svensson",
    "nano@purgatory.lan": "Daniel Svensson",
    "olle@xmms.org": "Olle Hallnas",
    "peter@data.netintact.se": "Peter Alm",
    "peter@dumburk.ithora.nu": "Peter Alm",
    "softchill@blacky.sympatico.ca": "Kristian Benoit",
    "tbe@bernhard.hemma.tobbe.nu": "Tobias Bengtsson",
    "thomas@xmms.org": "Thomas Nilsson",
    "tilman@code-monkey.de": "Tilman Sauerbeck",
    "tru@arclight.local": "Tobias Rundstrom",
    "tru@burnout.home.ithora.nu": "Tobias Rundstrom",
    "tru@darkangel.(none)": "Tobias Rundstrom",
    "tru@electronaut.(none)": "Tobias Rundstrom",
    "tru@electronaut.tobi.debian.as": "Tobias Rundstrom",
    "tru@forsaken.debian.as": "Tobias Rundstrom",
    "tru@nellie.tobi.nu": "Tobias Rundstrom",
    "tru@netintact.se": "Tobias Rundstrom",
    "tru@purgatory.guldkusten.com": "Tobias Rundstrom",
    "tru@shift.local": "Tobias Rundstrom",
    "tru@solitude.debian.as": "Tobias Rundstrom",
    "tru@worf.(none)": "Tobias Rundstrom",
    "tru@xmms.org": "Tobias Rundstrom",
    }




f = os.popen("cd %s; bk prs -d':REV:\\t:PARENT:\\t:MPARENT:\\t\\n' ChangeSet" % bk_dir)
f.readline()
parents={}
for rev in f:
    [n,p] = rev.rstrip().split("\t",1)
    parents[n] = p.split("\t")

os.putenv("GIT_OBJECT_DIRECTORY","%s/objects/" % git_dir)
os.putenv("GIT_INDEX_FILE","%s/index" % git_dir)

os.system("mkdir %s; cd %s; git-init-db" % (git_dir, git_dir))


unknown = {}

def get_name(email):
    if committers.has_key(email):
        return committers[email]
    unknown[email] = True
    return ""

def git_commit(rev, p):
    os.system("cd %s; git-ls-files --deleted | xargs git-update-cache --remove" % tmp_dir)
    os.system("cd %s; git-ls-files --others | xargs git-update-cache --add" % tmp_dir)
    os.system("cd %s; git-ls-files -z | xargs -0 git-update-cache" % tmp_dir)
    treeid = os.popen("git-write-tree").read().rstrip()
    print "wrote tree as %s" % treeid
    os.system("rm -Rf %s" % tmp_dir)

    bk_info = os.popen("cd %s; bk prs -r%s -d':KEY:\\n:UTC:\\n:USER:@:HOST:\\n$each(:C:){:C\\n}\\n' ChangeSet | sed 1d" % (bk_dir, rev)).read()

    [key, date, user, comments] = bk_info.split("\n", 3)
    f = file("/tmp/git-comments","w")
    f.write(comments)
    f.write("\nBK KEY: %s\n" % key)
    f.close()
    os.putenv("GIT_AUTHOR_DATE", str(int(time.mktime(time.strptime(date+" UTC", "%Y%m%d%H%M%S %Z")))))
    os.putenv("GIT_AUTHOR_EMAIL", user)
    os.putenv("GIT_AUTHOR_NAME", get_name(user))
    os.putenv("GIT_COMMITTER_EMAIL", user)
    os.putenv("GIT_COMMITTER_NAME", get_name(user))
    
    commitid = os.popen("git-commit-tree %s %s < /tmp/git-comments" % (treeid, " ".join(["-p "+a for a in p]))).read().rstrip()
    print "committed %s as %s" % (rev, commitid)
    return commitid

os.system("mkdir %s; touch %s/initial" % (tmp_dir, tmp_dir))
resolved = {'1.1': git_commit("1.1",[])}

def res(ver):
    if resolved.has_key(ver):
        return
    
    for v in parents[ver]:
        res(v)
    os.system("cd %s; bk export -r%s %s" % (bk_dir, ver, tmp_dir))
    resolved[ver] = git_commit(ver, [resolved[v] for v in parents[ver]])
    return resolved[ver]

tot = os.popen("cd %s; bk prs -r+ -d':REV:' ChangeSet | tail -n 1" % bk_dir).read()
print "Exporting bitkeeper up to version %s" % tot

HEAD = res(tot)
print "HEAD: %s" % HEAD
os.mkdir("%s/refs" % git_dir)
os.mkdir("%s/refs/tags" % git_dir)
os.mkdir("%s/refs/heads" % git_dir)
file("%s/refs/heads/master" % git_dir,"w").write(HEAD + "\n")
os.symlink("refs/heads/master", "%s/HEAD" % git_dir)
print unknown.keys()

