G'day, I modified that script to convert a number of our repositories in February. The version below worked for me at the time, but I'm not able to test it now as our BK license has expired. In particular I'm not sure if the bk_info.split line is correct; I had a reduced form of this line in the file which now looks obviously wrong. The script is slow; most of the time is in the bk export for every revision. There are probably dumb things in there; I don't know python and I was just starting with git. Changes from the version I downloaded from the web include: - sundry changes to make it work for me - separate committers file to translate user names to full names - specify a git dir template - copy tags from BK - minimal conversion of ignore files - increased recursion limit to handle large number of commits I hope this is useful to someone. regards, David. --snip,snip-- # Convert a BK repository to GIT # usage: bk2git BK_REPO [GIT_REPO] # Single branch only. import os import time import sys sys.setrecursionlimit(10000); templates_dir = "/tmp/bk2git/templates" committers_file = "/tmp/bk2git/committers" tmp_dir = "/tmp/bk-export%d" % os.getpid() # Get repository locations. if len(sys.argv) < 2 or len(sys.argv) > 3: print "usage: bk2git BK_REPO [GIT_REPO]" sys.exit(1); bk_dir = sys.argv[1] if len(sys.argv) == 3: git_dir = sys.argv[2] else: git_dir = bk_dir + ".git" print "BK " + bk_dir print "GIT " + git_dir # Get committer names. f = file(committers_file, "r") committers = {} for line in f: [m,n] = line.split(" ",1) committers[m] = n.strip(); f.close() # Get tree of commits. 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") f.close() # Get tags. f = os.popen("cd %s; bk changes -t -n -d':I:\\t:TAG:'" % bk_dir) tags={} for rev in f: [n,t] = rev.rstrip().split("\t",1) tags[n] = t f.close() # Initialize git repository. os.system("mkdir %s" % git_dir) os.chdir(git_dir) os.system("git --bare init --template=%s" % templates_dir) os.system("git-config core.bare false") unknown = {} def get_name(email): if committers.has_key(email): return committers[email] unknown[email] = True return "*Unknown*" def git_commit(rev, p): os.chdir(tmp_dir) os.symlink(git_dir, "%s/.git" % tmp_dir) # os.system("pwd; ls -AlR") os.system("git-ls-files -z --deleted | xargs -0 git-update-index --remove") os.system("git-ls-files -z --others | xargs -0 git-update-index --add") os.system("git-ls-files -z | xargs -0 git-update-index") treeid = os.popen("git-write-tree").read().rstrip() print "wrote tree as %s" % treeid os.chdir(git_dir) 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) # [key, date, user] = bk_info.split("\n", 2) [name, machine] = user.split("@", 1); f = file("/tmp/git-comments","w") f.write(comments) f.write("BK KEY: %s\n" % key) f.close() sdate = str(int(time.mktime(time.strptime(date+" UTC", "%Y%m%d%H%M%S %Z")))) os.putenv("GIT_AUTHOR_DATE", sdate) os.putenv("GIT_AUTHOR_EMAIL", user) os.putenv("GIT_AUTHOR_NAME", get_name(name)) os.putenv("GIT_COMMITTER_DATE", sdate) os.putenv("GIT_COMMITTER_EMAIL", user) os.putenv("GIT_COMMITTER_NAME", get_name(name)) 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) if tags.has_key(rev): os.system("git-tag %s %s" % (tags[rev], commitid)) print "tagged %s" % tags[rev] 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)) ignore = "%s/.gitignore" % tmp_dir os.system("cd %s; bk co -kpq -r@%s BitKeeper/etc/ignore | sed '/^BitKeeper/d;/^PENDING/d' > %s" % (bk_dir, ver, ignore)) os.system("test -s %s || rm %s" % (ignore, ignore)) 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 file("%s/refs/heads/master" % git_dir,"w").write(HEAD + "\n") os.system("git-config core.bare true") os.system("git gc") print unknown.keys() --snip,snip-- -- IMPORTANT: This email remains the property of the Australian Defence Organisation and is subject to the jurisdiction of section 70 of the CRIMES ACT 1914. If you have received this email in error, you are requested to contact the sender and delete the email. - To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html