SVN遷移到Git的過程(+ 一些技巧)
李順利
Key Words
SVN,Git,Clone,Conversion,Tips,VCS,Pro Git
關(guān)于在VCS中SVN和Git之間的遷移(Clone)這個部分網(wǎng)上已經(jīng)有大批的文章介紹,而且都非常不錯,能夠滿足我們的常見的需求,這里介紹的是我自己整理的一些技巧和使用中出現(xiàn)的一些問題和疑問。
閱讀本篇文章,請先有一些Git和SVN的使用經(jīng)驗(又是經(jīng)驗,經(jīng)驗到底是什么?我都不知道)。
第一部分
今天的實驗對象是,把 http://code.google.com/p/jdbcdslog-exp/ 這個使用SVN管理的project遷移到 Git上面,Git托管網(wǎng)站選擇github。SVN遷移到Git,當(dāng)然要清楚git svn 命令了。
首先請在github上面創(chuàng)建一個repository,這個簡單,就不說了,然后就是使用強(qiáng)大的git了。
$ git svn init https://jdbcdslog-exp.googlecode.com/svn/ -s $ git svn fetch |
當(dāng)然上面的兩步,可以作一步處理
$ git svn clone https://jdbcdslog-exp.googlecode.com/svn/ -s |
注: -s 參數(shù)是表面使用的是svn標(biāo)準(zhǔn)命名方法,即 trunk,tags,branches,這個參數(shù)有時很重要,建議使用,命令后面還可以加個文件夾名字作為clone后的目錄,如果沒有默認(rèn)是當(dāng)前路徑。
git svn fetch 這個步驟,可能碰到只想從某個版本開始進(jìn)行fetch,那么請需要 –r 參數(shù)。
例如:
$ git svn fetch -r 1342:HEAD |
注:1342是你想要從這個版本開始fetch,如何查看這個版本號,你可以使用 svn 命令(windows下需要安裝Subversion Client,e.g. sliksvn),簡單使用就是 svn log svn_url ,這個時候,你可能看到整屏在刷新,沒關(guān)系,看到log就行。當(dāng)然更簡單的就是使用TortoiseSVN-> Show log。
亦或者你可以這樣使用:
$ git svn clone https://jdbcdslog-exp.googlecode.com/svn/ -sr 1342:HEAD jdbcdslog-exp |
到這步的時候,本地已經(jīng)clone了SVN倉庫,現(xiàn)在需要的就是提交到遠(yuǎn)程了。首先,關(guān)聯(lián)github遠(yuǎn)程倉庫,如下:
$ git remote add origin git@github.com:usc/jdbcdslog-exp.git |
普通青年這個時候,肯定就會選擇使用
$ git push -u origin master |
到github上面查看這個倉庫(repository),大致效果如下(https://github.com/usc/jdbcdslog-exp)
二逼青年當(dāng)然要看看文檔或者倉庫信息,有沒有什么值得注意的,你瞧瞧,出現(xiàn)了很多branches,并沒有tag(SVN倉庫目錄是標(biāo)準(zhǔn)目錄,其中tags下有幾個版本的代碼,而branches下是沒有代碼的),是不是很奇怪(上圖實際上也說明了一些問題,只有一個branches),既然出現(xiàn)了這樣,就要想辦法解決了。
問題的解決直接來自《Pro Git》電子書,下面一段copy自《Pro Git》。
【引用開始】
你還需要一點(diǎn)post-import(導(dǎo)入后) 清理工作。最起碼的,應(yīng)該清理一下git svn 創(chuàng)
建的那些怪異的索引結(jié)構(gòu)。首先要移動標(biāo)簽,把它們從奇怪的遠(yuǎn)程分支變成實際的標(biāo)簽,然
后把剩下的分支移動到本地。
要把標(biāo)簽變成合適的Git 標(biāo)簽,運(yùn)行
$ cp -Rf .git/refs/remotes/tags/* .git/refs/tags/ $ rm -Rf .git/refs/remotes/tags |
該命令將原本以tag/ 開頭的遠(yuǎn)程分支的索引變成真正的(輕巧的)標(biāo)簽。
接下來,把refs/remotes 下面剩下的索引變成本地分支:
$ cp -Rf .git/refs/remotes/* .git/refs/heads/ $ rm -Rf .git/refs/remotes |
現(xiàn)在所有的舊分支都變成真正的Git 分支,所有的舊標(biāo)簽也變成真正的Git 標(biāo)簽。最后,一項工作就是把新建的Git 服務(wù)器添加為遠(yuǎn)程服務(wù)器并且向它推送。為了讓所有的分支和標(biāo)簽都得到上傳,我們使用這條命令:
$ git push origin –all |
所有的分支和標(biāo)簽現(xiàn)在都應(yīng)該整齊干凈的躺在新的Git 服務(wù)器里了。
【引用完畢】
上面最后部分(git push origin –all),我運(yùn)行發(fā)現(xiàn)有些問題的,并不能如它所說,分支和標(biāo)簽(branches and tags)都在git服務(wù)器中,請看下面截圖:
實際上,只提交了branches到github上面,并沒有提交tags,當(dāng)然,很簡單,你可以使用 git push –h 查看下幫助,就會發(fā)現(xiàn),你應(yīng)該知道怎么做了,使用 git push –tags 就可以了。
(使用git push –tags效果)
為了完整,還是說說文藝青年吧。文藝青年還需要搞技術(shù)嗎?當(dāng)然是找個上面的普通青年或者二逼青年就搞定了。
第二部分
到此,任務(wù)已經(jīng)差不多完成了,之所以說差不多了,是因為在《Pro Git》發(fā)現(xiàn)了兩個更讓人遺忘的技巧。
第一, Log中的信息(主要是作者)
請看完成上面步驟后產(chǎn)生的git log,會是如何
《Pro Git》上面也有說明,需要先把作者信息抓取出來,寫到一個文件(假如是user.txt,放在git 當(dāng)前目錄下)中,
git svn clone https://jdbcdslog-exp.googlecode.com/svn/ -sr 1342:HEAD --authors-file=user.txt --no-metadata jdbcdslog |
再來看看效果
第二,git ignores
【下面來自《Pro Git》第八章】
假如克隆了一個包含了svn:ignore 屬性的Subversion 倉庫,就有必要建立對應(yīng)的.gitignore 文件來防止意外提交一些不應(yīng)該提交的文件。git svn 有兩個有益于改善該問題的命令。第一個是git svn create-ignore,它自動建立對應(yīng)的.gitignore 文件,以便下次提交的時候可以包含它。
第二個命令是git svn show-ignore,它把需要放進(jìn).gitignore 文件中的內(nèi)容打印到標(biāo)
準(zhǔn)輸出,方便我們把輸出重定向到項目的黑名單文件:
$ git svn show-ignore > .git/info/exclude |
這樣一來,避免了.gitignore 對項目的干擾。如果你是一個Subversion 團(tuán)隊里唯一的
Git 用戶,而其他隊友不喜歡項目包含.gitignore,該方法是你的不二之選。
【引用結(jié)束】
第三部分
現(xiàn)在代碼即在SVN(google code)上面托管著,也在Git(github)上面托管著,當(dāng)然提交代碼的時候,就需要注意點(diǎn)點(diǎn)。代碼的提交大致會有兩種情況,提交到SVN還是Git。
² 提交到SVN
開發(fā)以SVN為主,大部分Members 都使用SVN,那么如果你使用Git管理你的代碼,那么如何同步到SVN上面了?很簡單,使用下面命令就可以了,
$ git svn rebase $ git svn dcommit |
原則和SVN提交差不多,先更新后提交(個人總結(jié))
² 提交到Git
如果想提交到Git上面,當(dāng)然先要拉取SVN Repo最新的代碼,當(dāng)你push的時候,你可能就會發(fā)現(xiàn)有些問題,
根據(jù)提示,你可以很容易就知道如何處理,實際上,這也是git方便的地方,很多時候,提示 + -h 都能搞定問題。好了,整個步驟如下:
$ git svn rebase $ git pull $ git commit –am “xxx” $ git push |
第四部分
隨著Project的開發(fā),可能SVN URL改變了(很多原因,比如域名改變,比如版本升級,再比如一不小心使用了http,想換到https等),那么如果使用SVN,很簡單,直接relocate就可以了,但是以前同步使用的Git Project如何跟著變化了,上網(wǎng)查了一下,發(fā)現(xiàn)比較有效的來自下面。
https://git.wiki.kernel.org/articles/g/i/t/GitSvnSwitch_8828.html
【引用開始】
General Case
What immediately sprang to mind, and what was suggested e.g. on the mailing list, was to simply edit your .git/config, and change the url= in the section [svn-remote "svn"]. That doesn't work, however. Instead, I found several suggestions to use variations of this theme:
l Edit the svn-remote url URL in .git/config to point to the new domain name
l Run git svn fetch - This needs to fetch at least one new revision from svn!
l Change svn-remote url back to the original url
l Run git svn rebase -l to do a local rebase (with the changes that came in with the last fetch operation)
l Change svn-remote url back to the new url
l Run git svn rebase should now work again!
This will only work, if the git svn fetch step actually fetches anything! (Took me a while to discover that... I had to put in a dummy revision to our svn repository to make it happen!)
【引用結(jié)束】
注:紅色部分請注意下。
本人已經(jīng)驗證這個方法是可以成功切換SVN URL的。
如果想更了解清楚,請參考《Pro Git》第八章——Git 與其他系統(tǒng)。實際上這些內(nèi)容,全部在《Pro Git》一書中,以前也沒仔細(xì)閱讀,現(xiàn)在發(fā)現(xiàn),它不僅提供了基礎(chǔ)知識,而且還想到了我們會出現(xiàn)困難或者疑問的地方,并給出了解決辦法或思路。
碰到問題再想著解決,這種“需求驅(qū)動學(xué)習(xí)”的方式是最能讓你銘記的。
如果有興趣的話,后面可以介紹下,在不同的google code project中進(jìn)行同步(sync)或者備份(SVN遷移到SVN)。
如果你有什么問題和交流,非常歡迎通過Email(lishunli.me@gmail.com) 聯(lián)系我或者微博@李順利Me(http://weibo.com/lishunli)。
順利
2012年1月15日
參考
https://git.wiki.kernel.org/articles/g/i/t/GitSvnSwitch_8828.html
博客中的一些下載已經(jīng)放到了百度云了,請根據(jù)需要下載。【點(diǎn)我去百度云下載】
最后弱弱地說一下,如果可以的話,轉(zhuǎn)載請?zhí)峁┏鎏? ),謝謝。
