我的项目在网络文件系统上有一个 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 会是什么样子?
最佳答案
这是我想出的:
创建
git-svn
存储库(如果尚不存在):git svn init --std-layout <svn_url> <git-svn_path>
master
自动创建分支以跟踪trunk
.为避免 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
为每个 Subversion 分支创建一个 Subversion 跟踪分支:
for BRANCH in $(svn ls <svn_url>/branches/); do git branch $BRANCH remotes/svn/$BRANCH done
确保没有在中央 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
允许推送到中央 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
重置是必要的,否则当前分支在每次接收后都已过时。
最后,创建 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/