Re: importing bk into git

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux