svn - 自动同步 Subversion 存储库和 Git 存储库

标签 svn git git-svn githooks svn-hooks

我的项目在网络文件系统上有一个 Subversion 存储库,一个新团队希望使用 Git 访问它,并能够提交它并从中获取更新。

我的想法是在同一网络文件系统上创建一个新的 Subversion 存储库的裸 git-svn 克隆,并确保这两个存储库始终保持最新彼此。

这样做的方法可能是为 Subversion 和新的 Git 存储库添加一个提交后 Hook ,这将各自更新对方的存储库。

Subversion post-commit Hook 将包括 git svn rebase 和 Git one git svn dcommit

问题是我将不得不使用某种锁来确保没有人提交到任何一个存储库,而其他人也正在提交,因为它们在任何提交之前总是必须同步。这有几个缺点,其中包括提交到 Subversion 或推送到 Git 存储库所需的时间(必须等待 Hook 完成),以及一些用户可能无法运行 git svn(因为它没有安装在他们的机器上),这意味着他们在提交/推送时无法更新其他存储库。

如何解决这些问题? Subversion 和 Git Hook 会是什么样子?

最佳答案

这是我想出的:

  1. 创建 git-svn存储库(如果尚不存在):

    git svn init --std-layout <svn_url> <git-svn_path>
    

    master自动创建分支以跟踪 trunk .

  2. 为避免 Subversion 跟踪分支的名称歧义,请将原始 Subversion 分支显示为 remotes/svn/<branch name> : 转到新创建的 git-svn存储库并运行

    git config svn-remote.svn.fetch trunk:refs/remotes/svn/trunk
    git config svn-remote.svn.branches branches/*:refs/remotes/svn/*
    git config svn-remote.svn.tags tags/*:refs/remotes/svn/tags/*
    
    rm .git/refs/remotes/*
    git svn fetch
    
  3. 为每个 Subversion 分支创建一个 Subversion 跟踪分支:

    for BRANCH in $(svn ls <svn_url>/branches/); do
        git branch $BRANCH remotes/svn/$BRANCH
    done
    
  4. 确保没有在中央 Git 存储库上创建非 Subversion 跟踪分支:

    # Used by hooks/update:
    git config hooks.denyCreateBranch true
    git config hooks.allowDeleteBranch false
    
    cp .git/hooks/update.sample .git/hooks/update
    chmod +x .git/hooks/update
    
  5. 允许推送到中央 Git 存储库:

    git config receive.denyCurrentBranch ignore
    git config receive.denyNonFastForwards true
    git config push.default current
    

    并创建接收后 Hook 以重置并将提交发送到 Subversion:

    cat .git/hooks/post-receive
    
        #!/bin/sh
    
        date >> receive.log
        git reset --quiet --hard
        while read LINE
        do
            BRANCH=${LINE##*/}
            echo Updating $BRANCH
            git checkout --quiet --force $BRANCH
            git svn dcommit
        done 2>&1 | tee -a receive.log
        git checkout --quiet --force master
    
    chmod +x .git/hooks/post-receive
    

    重置是必要的,否则当前分支在每次接收后都已过时。

  6. 最后,创建 Hook 以从 Subversion 获取更新:

    cat .git/hooks/svn-rebase-all
    
        #!/bin/sh
    
        date >> .git/svn-rebase.log
        git reset --quiet --hard
        for REF in .git/refs/heads/*
        do
            BRANCH=${REF##*/}
            echo Updating $BRANCH
            git checkout --quiet --force $BRANCH
            git svn rebase
        done 2>&1 | tee -a .git/svn-rebase.log
        git checkout --quiet --force master
    
    chmod +x .git/hooks/svn-rebase-all
    

    并从 Subversion 提交后 Hook 调用它:

    cat <svn_path>/hooks/post-commit
    
        cd <git_path>
        . .git/hooks/svn-rebase-all
    
    chmod +x <svn_path>/hooks/post-commit
    

而不是使用单个 git-svn中央存储库,可以使用裸中央 Git 存储库和中间非裸 git-svn存储库,如 this answer . 我选择使用一个非裸 git-svn存储库,也是中央存储库。

任何人都可以通过克隆 <git_path> 使用 Git 来处理这个项目。并推送给它,或者通过查看 <svn_url> 使用 Subversion并致力于此。

关于svn - 自动同步 Subversion 存储库和 Git 存储库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5586993/

相关文章:

git - 为什么 git svn fetch 这么慢?

适用于 Mac OSX 的 SVN 服务器

git - 如何将 chmod 666 的 checkout 后 Hook 写入所有文件?

macos - Git check out /删除带有特殊字符的文件

git - 如何在 Git 上发送 pull 请求

SVN 与二进制文件的合并处理

apache - svn up error 413 - 尝试了我能找到的所有选项

git - git 如何处理将另一个存储库克隆到子目录中?

git - SVN 到 Git 转换后缺少标签

git svn - 克隆带有所有外部的存储库