[英]Automatically synchronizing a Subversion repository and a Git repository
我的項目在網絡文件系統上有一個Subversion存儲庫,一個新團隊希望使用Git訪問它,並能夠提交它並從中獲取更新。
我想到的是在同一網絡文件系統上創建Subversion存儲庫的新裸git-svn
克隆,並確保這兩個存儲庫始終相互更新。
這樣做的方法可能是為Subversion和新的Git存儲庫添加一個post-commit鈎子,它們將更新另一個的存儲庫。
Subversion post-commit鈎子將包括git svn rebase
,以及Git one git svn dcommit
。
問題是我將不得不使用某種鎖來確保沒有人提交到任何一個存儲庫,而其他人也被提交,因為它們總是必須在任何提交之前保持同步。 這有幾個缺點,其中包括提交Subversion或推送到Git存儲庫所需的時間(它必須等待鈎子完成),以及一些用戶可能無法運行git svn
的事實(因為它沒有安裝在他們的機器上),這意味着他們在提交/推送時無法更新其他存儲庫。
我該如何解決這些問題? Subversion和Git鈎子會是什么樣子?
這是我提出的:
如果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
並創建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存儲庫和中間非裸git-svn
存儲庫,而不是使用單個git-svn
中央存儲庫,如本答案所示 。 我選擇使用一個非裸git-svn
存儲庫,它也是中央存儲庫。
任何人都可以使用Git通過克隆<git_path>
並推送到它來工作,或者通過簽出<svn_url>
並提交它來使用Subversion。
只需讓每個開發人員學會直接使用git-svn
你就會變得更好。 git和SVN模型之間存在太多的阻抗不匹配,無法穩健地實現您所需的功能。 你可以讓它幾乎可靠地工作的唯一方法是制定與git-svn
相同的限制,但是有更多移動部件可能會破壞。 在我看來,你的修訂控制系統並不是你想要部分可靠的東西。
或者,如果可能的話,只需完全拋棄SVN並一直移動到git。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.