svn2git结合在一起

时间:2015-04-15 19:08:45

标签: git svn svn2git

svn2git converter我有一个非常奇怪的问题。

我有2个svn repos(svn 1.7和Windows开发)。我已经创建了一个python3脚本来自动同步repos并将其每天推送到我们的gitlab服务器(转换器在虚拟ubuntu实例上运行)。一切都很好,但今天我看到我的回购搞砸了。第一个repo包含来自第二个repo的内容,第二个repo包含来自第一个repo的内容。 怎么可能??? ???

有没有人对svn2git有这样的问题? 有没有人知道一个好的工具来自动检查每次提交的回购(svn vs git),以确保每次提交都没问题?

编辑: 这是我使用的脚本(它有点hacky :-))

# convert.py

import os,sys,subprocess

__filedir = os.path.dirname(os.path.realpath(__file__))
__migratescript = os.path.join(__filedir,"svn2git_repo/bin/svn2git")
__authors = os.path.join(__filedir,"authors.txt")
__repodir = os.path.join(__filedir,"repos")

class CurDirScope:
    def __init__(self,newdir):
        self.newdir = newdir
        self.olddir = os.getcwd()

    def __enter__(self):
        self.__chdir((self.newdir))

    def __exit__(self,type,value,traceback):
        self.__chdir(self.olddir)

    def __chdir(self,dir):
        if(os.path.exists(dir)):
            print("change current directory to {0}".format(dir))
            os.chdir(dir)

def gitSVNClone(directory,repo):

    dir = os.path.join(__repodir,directory)
    print("try clone {0} to {1}".format(repo,dir))
    gitpath = os.path.join(dir,".git")
    if(os.path.exists(gitpath)):
        raise Exception("repo directory does already exists {}".format(gitpath))
    print("create directory {0}".format(dir))
    os.makedirs(dir)

    with CurDirScope(dir) as scope:
        cmd = ["svn2git",repo,"--authors=" + __authors]
        print("start git svn clone")
        rc=subprocess.call(cmd)
        print("end of clone")
        if(rc != 0):
            raise Exception("git svn clone failed - rc: {0}".format(rc))

def syncRepo(directory):
    dirs = []
    if(directory == "all"):
        dirs = os.listdir(__repodir)
    else:
        dirs =[directory]

    if(len(dirs) <= 0):
        print("nothing to sync")
        return

    errors = []

    for dir in dirs:
        try:
            absdir = os.path.join(__repodir,dir)
            if(os.path.exists(absdir) == False):
                raise Exception("directory does not exists '{0}'".format(absdir))
            print(absdir)

            with CurDirScope(absdir) as scope:
                cmd = ["svn2git","--rebase","--authors=" + __authors]
                print("start git repo sync {0}".format(absdir))
                print(str(cmd))
                rc=subprocess.call(cmd,shell=False)
                print("end of sync")
                if(rc != 0):
                    raise Exception("rebase repo failed - rc: {0}".format(rc))

        except BaseException as ex:
            errors.append(str(ex))

    if(len(errors) > 0):
        print("# Error: ")
        for msg in errors:
            print(msg)
        raise Exception("{0} error(s) happend".format(str(len(errors))))

def pushRepo(directory,TagsOnly=False):
    dirs = []
    if(directory == "all"):
        dirs = os.listdir(__repodir)
    else:
        dirs =[directory]

    if(len(dirs) <= 0):
        print("nothing to push")
        return

    pushcommand = "--all"
    if(TagsOnly):
        pushcommand = "--tags"

    errors = []

    for dir in dirs:
        try:
            absdir = os.path.join(__repodir,dir)
            if(os.path.exists(absdir) == False):
                raise Exception("directory does not exists '{0}'".format(absdir))
            print(absdir)

            with CurDirScope(absdir) as scope:
                cmd = ["git","push","origin",pushcommand]
                print("start git repo push to origin '{0}'".format(absdir))
                print(str(cmd))
                rc=subprocess.call(cmd,shell=False)
                print("end of push")
                if(rc != 0):
                    raise Exception("push repo {0} failed - rc: {1}".format(dir,rc))
        except BaseException as ex:
            errors.append(str(ex))

    if(len(errors) > 0):
        print("# Error: ")
        for msg in errors:
            print(msg)
        raise Exception("{0} error(s) happend".format(str(len(errors))))



if __name__ == "__main__":
    try:
        args = sys.argv[1:]
        print(str(args))
        al = len(args)

        if(al <= 0):
            raise Exception("not enough arguments")

        cmd = args[0]

        args = args[1:]
        al = len(args)

        if(os.path.exists(__repodir) == False):
            os.makedirs(__repodir)

        if(cmd == "clone"):
            if(al < 2):
                raise Exception("not enough arguments for clone")

            dir = args[0]
            repo = args[1]
            gitSVNClone(dir,repo)

        elif(cmd == "sync"):
            if(al < 1):
                raise Exception("not enough arguments for sync")

            dir = args[0]
            syncRepo(dir)

        elif(cmd == "push" or cmd == "pushtags"):
            if(al < 1):
                raise Exception("not enough arguments for sync")

            tagsonly = False
            if(cmd == "pushtags"):
                tagsonly = True

            dir = args[0]
            pushRepo(dir,tagsonly)

        else:
            raise Exception("unknown command '{0}'".format(cmd))


    except BaseException as ex:
        if(ex == None):
            ex = "internal error"
        print("Error: {0}".format(str(ex)))
        sys.exit(1)

克隆示例:

python3 convert.py clone MyLocalDir http://mysvnrepopath

它将我的svn-repo克隆到我的local-repo目录(存储了所有已转换的repos),其本地目录名为 MyLocalDir

同步示例:

python3 convert.py sync all

参数all同步我的repo目录中的每个repo。我也可以使用目录名而不是MyLocalDir,但我使用了99%的all参数

推送示例:

python3 convert.py push all

pushtags示例:

python3 convert.py pushtags all

问候 通卡

0 个答案:

没有答案