我的项目在网络文件系统上有一个 Subversion 存储库,新团队希望使用 Git 访问它,并能够提交它并从中获取更新。
我的想法是创建一个新的裸git-svn
在同一网络文件系统上克隆 Subversion 存储库,并确保这两个存储库始终彼此保持最新。
做到这一点的方法可能是为 Subversion 和新的 Git 存储库添加一个提交后挂钩,这将分别更新对方的存储库。
Subversion 提交后挂钩将包括git svn rebase
,以及 Git 的git svn dcommit
.
问题是我必须使用某种锁来确保没有人提交到任何一个存储库,而其他存储库也被提交,因为它们在任何提交之前始终必须保持同步。这有几个缺点,其中包括提交到 Subversion 或推送到 Git 存储库所需的时间(必须等待挂钩完成),以及某些用户可能无法运行git svn
(因为它没有安装在他们的机器上),这意味着他们在提交/推送时无法更新其他存储库。
我该如何解决这些问题? Subversion 和 Git 挂钩会是什么样子?
这是我想出的:
-
创建git-svn
存储库(如果尚不存在):
git svn init --std-layout <svn_url> <git-svn_path>
The 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
并创建 post-receive 挂钩来重置并将提交发送到 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
重置是必要的,因为否则当前分支在每次接收后都会过时。
-
最后,创建挂钩以从 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 post-commit 挂钩调用它:
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
存储库,如这个答案 https://stackoverflow.com/questions/2014422/hooks-for-git-svn/2032889#2032889。
我选择使用一个非裸机git-svn
存储库也是中央存储库。
任何人都可以通过克隆使用 Git 来处理该项目<git_path>
并推送到它,或者通过检查来使用 Subversion<svn_url>
并致力于此。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)