大貓共和國

Meow

用git管理具有external的svn Repository

睡不著爬起來寫blog,明天要早起的說 Orz



git是一套目前非常流行的分散式版本控制系統
相信很多人和我一樣,熟析git後就不會想用svn或cvs來管理源碼

我最近碰到這樣的問題:
專案主要使用svn做版本控制,但是我個人想用git管理
大家第一個想到的應該是git-svn
但git-svn對於svn external的支援並不完善

然而我目前的專案大量的使用了svn:external

src/
src/A => external to another project
src/B => external to another project
src/C => external to another project

更糟的是,因為專案開發時間的因素
A,B,C專案與主專案是共同開發的
有的時候我必需修改external library的API,並commit回去
有時其他人修改了external library,主專案必需跟著修改
(I know it doesn’t sound good, but it’s real world problem…)

我試過不管是單純的使用git-svn,或者借助一些shell script
都無法順利的處理這個工作流程

直到今天我想到一個實在是很瞎的方法:

mkdir gitrepo
cd gitrepo
git init
svn checkout svn://my-svn-repo-addr svnrepo
echo .svn > .gitignore
git add .
git commit
git chekcout -b svn-tracker

白話解釋一下:
在gitrepo/ 開一個git repository
在gitrepo/svnrepo 開一個svn repository
把.svn ignore掉 =.=
做一個名為svn-tracker的branch

這個看來愚蠢的方法 (對我目前的環境) 出手意料的好用
在改code時我都切換到其他branch (並且忘了svn的存在)
做任何svn操作時,我先切回svn-tracker branch

要做svn update的話就是
svn update
git add .
git commit -a

要commit自己的東西回svn mainstream就是
git merge work-branch
svn add *
svn commit

當然這些事可以寫shell script來完成



目前最大的缺點大概是沒法將git branch對應到svn branch (很麻煩)
不過還好我沒有很在乎….反正mainstream svn上沒有人在用branch & tag 功能,大家都只改trunk



這樣做還得到了意外的好處:
當要回退到舊版本時,如果沒有特別指定external的revision
就算update trunk to older revision,external還是會是最新版的
這樣會造成舊trunk + 新external,版本不相容的問題 (如果external行為或API有變)

上面的流程,每跑一次svn update
就等於把當時的情況做一次snapshot存進git
之後也就可以正確地回退版本….

Comments