Dan*_*ich 6 svn git git-svn githooks svn-hooks
我的项目在网络文件系统上有一个Subversion存储库,一个新团队希望使用Git访问它,并能够提交它并从中获取更新.
我想到的是git-svn
在同一网络文件系统上创建Subversion存储库的新裸克隆,并确保这两个存储库始终相互更新.
这样做的方法可能是为Subversion和新的Git存储库添加一个post-commit钩子,它们将更新另一个的存储库.
Subversion后提交钩子将包含git svn rebase
,而Git则包含git svn dcommit
.
问题是我将不得不使用某种锁来确保没有人提交到任何一个存储库,而其他人也被提交,因为它们总是必须在任何提交之前保持同步.这有几个缺点,其中包括提交Subversion或推送到Git存储库所需的时间(它必须等待钩子完成),以及一些用户可能无法运行的事实git svn
(因为它是没有安装在他们的机器上),这意味着他们在提交/推送时无法更新其他存储库.
我该如何解决这些问题?Subversion和Git钩子会是什么样子?
Dan*_*ich 13
这是我提出的:
git-svn
如果存储库尚不存在,请创建存储库:
git svn init --std-layout <svn_url> <git-svn_path>
Run Code Online (Sandbox Code Playgroud)
该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
Run Code Online (Sandbox Code Playgroud)为每个Subversion分支创建一个Subversion跟踪分支:
for BRANCH in $(svn ls <svn_url>/branches/); do
git branch $BRANCH remotes/svn/$BRANCH
done
Run Code Online (Sandbox Code Playgroud)确保在中央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
Run Code Online (Sandbox Code Playgroud)允许推送到中央Git存储库:
git config receive.denyCurrentBranch ignore
git config receive.denyNonFastForwards true
git config push.default current
Run Code Online (Sandbox Code Playgroud)
并创建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
Run Code Online (Sandbox Code Playgroud)
重置是必要的,因为否则当前分支在每次接收后都是过时的.
最后,创建钩子以从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
Run Code Online (Sandbox Code Playgroud)
并从Subversion post-commit钩子调用它:
cat <svn_path>/hooks/post-commit
cd <git_path>
. .git/hooks/svn-rebase-all
chmod +x <svn_path>/hooks/post-commit
Run Code Online (Sandbox Code Playgroud)git-svn
可以使用裸中央Git存储库和中间非裸git-svn
存储库,而不是使用单个中央存储库,如本答案所示.我选择使用一个非裸git-svn
存储库,它也是中央存储库.
任何人都可以通过克隆<git_path>
和推送使用Git来处理项目,或者通过签出<svn_url>
和提交来使用Subversion .