使用Git 作為 Subversion 倉庫的客戶端
Git 與 Subversion
Git 和 Subversion兩個大名鼎鼎的版本控制系統,有著各自的特點和長處。筆者更喜歡Git分散式區中心化不依賴網路的便捷和強大的本地分支管理,目前開源專案以及大量的商業專案都使用 Subversion 來管理原始碼。當代碼倉庫為SVN倉庫而又想使用git時,恰好git svn工具可以滿足您的需求。
Warning
在使用 git svn 的時候,你實際是在與 Subversion 互動,Git 比它要高階複雜的多。儘管可以在本地隨意的進行分支和合並,最好還是通過衍合保持線性的提交歷史,儘量避免類似與遠端 Git 倉庫動態互動這樣的操作。 避免修改歷史再重新推送的做法,也不要同時推送到並行的 Git 倉庫來試圖與其他 Git 使用者合作。Subersion 只能儲存單一的線性提交歷史,一不小心就會被搞糊塗。合作團隊中同時有人用 SVN 和 Git,一定要確保所有人都使用 SVN 服務來協作——這會讓生活輕鬆很多。
Start
遠端SVN倉庫地址:
svn://svnbucket.com/****/svn_test
本地git svn clone
git svn clone svn倉庫地址 -s
可以將遠端Subversion 倉庫匯入到一個本地的 Git 倉庫中。-s 命令,它意味著標準佈局(s 是 Standard layout 的首字母):Subversion 倉庫遵循了基本的分支和標籤命名法則(如上圖trunk、tags、branches資料夾命名)。完整命令為:git svn clone svn倉庫地址 -T trunk -b branches -t tags
;若您的倉庫命名與標準不一致請做出相應的改動。
向SVN倉庫提交
可以看到本地git倉庫初始完成之後,原生代碼的管理完全基於git命令,只是向伺服器倉庫提交程式碼有變動使用git svn dcommit
拉取伺服器最新程式碼
sit svn fetch
能獲取最新的資料,git svn rebase
才會在獲取之後在本地進行更新 。
事實上sit svn fetch
類似git fetch會將遠端倉庫程式碼拉取到本地對應分支上:
需要牢記的一點是,Git 要求我們在推送之前先合併上游倉庫中最新的內容,而 git svn 只要求存在衝突的時候才這樣做。假如有人向一個檔案推送了一些修改,這時你要向另一個檔案推送一些修改,那麼 dcommit 將正常工作。 眾所周知SVN倉庫只保持單一的線性提交歷史,而不像git的commit歷史可以有合併的歷史“分叉”,所以使用git的本地分支儘可能使用rebase到主幹master保持乾淨的線性歷史對於svn dcommit來說是一個好的選擇。
分支操作-建立新的 SVN 分支
git svn branch [your_branch_name] -m "message"
命令可以在svn伺服器上建立一個新的分支等價於svn copy trunk branches/your_branch_name
若出現:
git svn branch [your_branch_name] -m "test" --destination branches
詳情參閱:https://stackoverflow.com/questions/2974016/git-svn-branching
上述命令僅僅建立svn分支並不會切換分支。
切換分支並提交到SVN指定分支
使用git svn dcommit命令需要注意:
Git 通過搜尋提交歷史中 Subversion 分支的頭部來決定 dcommit 的目的地——而它應該只有一個,那就是當前分支歷史中最近一次包含 git-svn-id 的提交。
如果要提交到上面步驟在svn倉庫建立的new_branch分支,則需要基於該remote svn 分支建立一個本地分支(上例子的hotfix),基於hotfix分支修改執行dcommit則提交到對應的svn new_branch分支。檢視hotfix分支的log: 可以發現其最近的git-svn-id記錄對應的svn倉庫的new_branch分支,git svn執行dcommit命令以此提交更改到對應遠端對應分支。git svn rebase命令也類似會拉取new_branch的最新修改更新到本地。
合併更改到主分支
若是基於svn new_branch分支做了修改提交,例如在本地的hotfix分支(對應svn的new_branch)分支開發完成了一個新模組想合併到git主分支並且提交到master對應的svn trunk分支該如何操作: 上述情況,new_branch已經有提交"change for test" 而 master分支還停留在"add img"提交處:
git checkout master //切換到主分支
//合併分支使用--squash將commit記錄合併更新為一個新commit
git merge --squash hotfix
git commit -am "merge new_branch branch features"
git svn dcommit
這樣就可以把new_branch通過git svn合併提交到svn的trunk,可以看到略顯麻煩並且在new_branch上的提交記錄被隱藏了;當然也可以選擇使用svn來執行svn 分支的合併然後再通過git svn rebase獲取更新到本地git分支。不過本博文旨在儘量弱化svn操作,儘可能使用git svn來完成版本的管理。
Tag操作
git svn tag操作與git svn branch 操作類似:
分支/Tag的刪除
由於git和svn分支的概念和管理上有很大差異,git svn命令沒有提供刪除svn 分支的方法。刪除svn分支通過svn命令刪除:
//1.刪除遠端svn倉庫的分支
svn rm svn_branch_url -m 'messge:rm branch'
//2.刪除本地git對應的追蹤分支
git branch -D -r remote_name/the_branch
//3.刪除本地git svn檔案
rm -rf .git/svn/refs/remotes/your_branch
tag刪除是類似的:
svn rm $URL/tags/the_tag_will_delete // step 1
git branch -D -r remote_name/tags/your_tag_name
rm -rf .git/svn/refs/remotes/remote_name/tags/your_tag_name