1

我对svn2git 转换器有一个非常奇怪的问题。

我有 2 个 svn 存储库(都是 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

它使用本地目录名称MyLocalDir将我的 svn-repo 克隆到我的 local-repo 目录(存储所有转换的 repos 的地方)

同步示例:

python3 convert.py sync all

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

推送示例:

python3 convert.py push all

推送标签示例:

python3 convert.py pushtags all

问候唐卡

4

0 回答 0