李順利
          隨筆-50  評(píng)論-170  文章-0  trackbacks-0

           

           

          SVN遷移到Git的過(guò)程(+ 一些技巧)

          李順利

          Key Words

          SVNGitCloneConversionTipsVCSPro Git

           

          關(guān)于在VCSSVNGit之間的遷移(Clone)這個(gè)部分網(wǎng)上已經(jīng)有大批的文章介紹,而且都非常不錯(cuò),能夠滿足我們的常見(jiàn)的需求,這里介紹的是我自己整理的一些技巧和使用中出現(xiàn)的一些問(wèn)題和疑問(wèn)。

          閱讀本篇文章,請(qǐng)先有一些GitSVN的使用經(jīng)驗(yàn)(又是經(jīng)驗(yàn),經(jīng)驗(yàn)到底是什么?我都不知道)。

           

           

          第一部分

           

          今天的實(shí)驗(yàn)對(duì)象是,把 http://code.google.com/p/jdbcdslog-exp/ 這個(gè)使用SVN管理的project遷移到 Git上面,Git托管網(wǎng)站選擇githubSVN遷移到Git,當(dāng)然要清楚git svn 命令了。

          首先請(qǐng)?jiān)?/font>github上面創(chuàng)建一個(gè)repository,這個(gè)簡(jiǎn)單,就不說(shuō)了,然后就是使用強(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)命名方法,即 trunktagsbranches,這個(gè)參數(shù)有時(shí)很重要,建議使用,命令后面還可以加個(gè)文件夾名字作為clone后的目錄,如果沒(méi)有默認(rèn)是當(dāng)前路徑。

          git svn fetch 這個(gè)步驟,可能碰到只想從某個(gè)版本開(kāi)始進(jìn)行fetch,那么請(qǐng)需要 –r 參數(shù)。

          例如:

          $ git svn fetch -r 1342:HEAD

          注:1342是你想要從這個(gè)版本開(kāi)始fetch,如何查看這個(gè)版本號(hào),你可以使用 svn 命令(windows下需要安裝Subversion Cliente.g. sliksvn),簡(jiǎn)單使用就是 svn log svn_url ,這個(gè)時(shí)候,你可能看到整屏在刷新,沒(méi)關(guān)系,看到log就行。當(dāng)然更簡(jiǎn)單的就是使用TortoiseSVN-> Show log

          亦或者你可以這樣使用:

          $ git svn clone https://jdbcdslog-exp.googlecode.com/svn/ -sr 1342:HEAD jdbcdslog-exp

                到這步的時(shí)候,本地已經(jīng)cloneSVN倉(cāng)庫(kù),現(xiàn)在需要的就是提交到遠(yuǎn)程了。首先,關(guān)聯(lián)github遠(yuǎn)程倉(cāng)庫(kù),如下:

          $ git remote add origin git@github.com:usc/jdbcdslog-exp.git

           

           

          普通青年這個(gè)時(shí)候,肯定就會(huì)選擇使用

          $ git push -u origin master

           

           

          github上面查看這個(gè)倉(cāng)庫(kù)(repository),大致效果如下(https://github.com/usc/jdbcdslog-exp

          screenshot-20120113110127

           

          二逼青年當(dāng)然要看看文檔或者倉(cāng)庫(kù)信息,有沒(méi)有什么值得注意的,你瞧瞧,出現(xiàn)了很多branches,并沒(méi)有tagSVN倉(cāng)庫(kù)目錄是標(biāo)準(zhǔn)目錄,其中tags下有幾個(gè)版本的代碼,而branches下是沒(méi)有代碼的),是不是很奇怪(上圖實(shí)際上也說(shuō)明了一些問(wèn)題,只有一個(gè)branches),既然出現(xiàn)了這樣,就要想辦法解決了。

          screenshot-20120113104705

          問(wèn)題的解決直接來(lái)自《Pro Git》電子書,下面一段copy自《Pro Git》。

          【引用開(kāi)始】

          你還需要一點(diǎn)post-import(導(dǎo)入后) 清理工作。最起碼的,應(yīng)該清理一下git svn 創(chuàng)

          建的那些怪異的索引結(jié)構(gòu)。首先要移動(dòng)標(biāo)簽,把它們從奇怪的遠(yuǎn)程分支變成實(shí)際的標(biāo)簽,然

          后把剩下的分支移動(dòng)到本地。

          要把標(biāo)簽變成合適的Git 標(biāo)簽,運(yùn)行

          $ cp -Rf .git/refs/remotes/tags/* .git/refs/tags/

          $ rm -Rf .git/refs/remotes/tags

           

           

           

          該命令將原本以tag/ 開(kāi)頭的遠(yuǎn)程分支的索引變成真正的(輕巧的)標(biāo)簽。

          接下來(lái),把refs/remotes 下面剩下的索引變成本地分支:

          $ cp -Rf .git/refs/remotes/* .git/refs/heads/

          $ rm -Rf .git/refs/remotes

           

           

           

          現(xiàn)在所有的舊分支都變成真正的Git 分支,所有的舊標(biāo)簽也變成真正的Git 標(biāo)簽。最后,一項(xiàng)工作就是把新建的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)有些問(wèn)題的,并不能如它所說(shuō),分支和標(biāo)簽(branches and tags)都在git服務(wù)器中,請(qǐng)看下面截圖:

          clip_image006[16]

          screenshot-20120113110706

          實(shí)際上,只提交了branchesgithub上面,并沒(méi)有提交tags,當(dāng)然,很簡(jiǎn)單,你可以使用 git push –h 查看下幫助,就會(huì)發(fā)現(xiàn),你應(yīng)該知道怎么做了,使用 git push –tags 就可以了。

          screenshot-20120113110856

          (使用git push –tags效果)

          screenshot-20120113110914

           

          為了完整,還是說(shuō)說(shuō)文藝青年吧。文藝青年還需要搞技術(shù)嗎?當(dāng)然是找個(gè)上面的普通青年或者二逼青年就搞定了。

           

           

          第二部分

           

          到此,任務(wù)已經(jīng)差不多完成了,之所以說(shuō)差不多了,是因?yàn)樵凇?/font>Pro Git》發(fā)現(xiàn)了兩個(gè)更讓人遺忘的技巧。

          第一, Log中的信息(主要是作者)

          請(qǐng)看完成上面步驟后產(chǎn)生的git log,會(huì)是如何

          screenshot-20120113105115

          Pro Git》上面也有說(shuō)明,需要先把作者信息抓取出來(lái),寫到一個(gè)文件(假如是user.txt,放在git 當(dāng)前目錄下)中,

          git svn clone https://jdbcdslog-exp.googlecode.com/svn/ -sr 1342:HEAD --authors-file=user.txt --no-metadata jdbcdslog

           

           

          再來(lái)看看效果

          clip_image018[16]

           

          第二,git ignores

          【下面來(lái)自《Pro Git》第八章】

          假如克隆了一個(gè)包含了svn:ignore 屬性的Subversion 倉(cāng)庫(kù),就有必要建立對(duì)應(yīng)的.gitignore 文件來(lái)防止意外提交一些不應(yīng)該提交的文件。git svn 有兩個(gè)有益于改善該問(wèn)題的命令。第一個(gè)是git svn create-ignore,它自動(dòng)建立對(duì)應(yīng)的.gitignore 文件,以便下次提交的時(shí)候可以包含它。

          第二個(gè)命令是git svn show-ignore,它把需要放進(jìn).gitignore 文件中的內(nèi)容打印到標(biāo)

          準(zhǔn)輸出,方便我們把輸出重定向到項(xiàng)目的黑名單文件:

          $ git svn show-ignore > .git/info/exclude

           

           

          這樣一來(lái),避免了.gitignore 對(duì)項(xiàng)目的干擾。如果你是一個(gè)Subversion 團(tuán)隊(duì)里唯一的

          Git 用戶,而其他隊(duì)友不喜歡項(xiàng)目包含.gitignore,該方法是你的不二之選。

          【引用結(jié)束】

           

           

          第三部分

           

          現(xiàn)在代碼即在SVN(google code)上面托管著,也在Git(github)上面托管著,當(dāng)然提交代碼的時(shí)候,就需要注意點(diǎn)點(diǎn)。代碼的提交大致會(huì)有兩種情況,提交到SVN還是Git

          ²  提交到SVN

          開(kāi)發(fā)以SVN為主,大部分Members 都使用SVN,那么如果你使用Git管理你的代碼,那么如何同步到SVN上面了?很簡(jiǎn)單,使用下面命令就可以了,

          $ git svn rebase

          $ git svn dcommit

          原則和SVN提交差不多,先更新后提交(個(gè)人總結(jié))

           

          ²  提交到Git

          如果想提交到Git上面,當(dāng)然先要拉取SVN Repo最新的代碼,當(dāng)你push的時(shí)候,你可能就會(huì)發(fā)現(xiàn)有些問(wèn)題,

          clip_image020[16]

          根據(jù)提示,你可以很容易就知道如何處理,實(shí)際上,這也是git方便的地方,很多時(shí)候,提示 + -h 都能搞定問(wèn)題。好了,整個(gè)步驟如下:

          $ git svn rebase

          $ git pull

          $ git commit –am “xxx”

          $ git push

           

           

          第四部分

           

          隨著Project的開(kāi)發(fā),可能SVN URL改變了(很多原因,比如域名改變,比如版本升級(jí),再比如一不小心使用了http,想換到https等),那么如果使用SVN,很簡(jiǎn)單,直接relocate就可以了,但是以前同步使用的Git Project如何跟著變化了,上網(wǎng)查了一下,發(fā)現(xiàn)比較有效的來(lái)自下面。

          https://git.wiki.kernel.org/articles/g/i/t/GitSvnSwitch_8828.html

          【引用開(kāi)始】

          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é)束】

          注:紅色部分請(qǐng)注意下。

          本人已經(jīng)驗(yàn)證這個(gè)方法是可以成功切換SVN URL的。

           

           

          如果想更了解清楚,請(qǐng)參考《Pro Git》第八章——Git 與其他系統(tǒng)。實(shí)際上這些內(nèi)容,全部在《Pro Git》一書中,以前也沒(méi)仔細(xì)閱讀,現(xiàn)在發(fā)現(xiàn),它不僅提供了基礎(chǔ)知識(shí),而且還想到了我們會(huì)出現(xiàn)困難或者疑問(wèn)的地方,并給出了解決辦法或思路。

          碰到問(wèn)題再想著解決,這種“需求驅(qū)動(dòng)學(xué)習(xí)”的方式是最能讓你銘記的。

           

          如果有興趣的話,后面可以介紹下,在不同的google code project中進(jìn)行同步(sync)或者備份(SVN遷移到SVN)。

           

          如果你有什么問(wèn)題和交流,非常歡迎通過(guò)Email(lishunli.me@gmail.com) 聯(lián)系我或者微博@李順利Me(http://weibo.com/lishunli)

               

           

          順利

          2012115

           

           

          參考

          http://progit.org/book/

          http://progit.org/book/zh/

          SVN+GIT=魚與熊掌兼得

          git svn實(shí)戰(zhàn)

          如何在svn系統(tǒng)中使用git

          小試git-svn

          https://git.wiki.kernel.org/articles/g/i/t/GitSvnSwitch_8828.html



          博客中的一些下載已經(jīng)放到了百度云了,請(qǐng)根據(jù)需要下載。【點(diǎn)我去百度云下載】

          最后弱弱地說(shuō)一下,如果可以的話,轉(zhuǎn)載請(qǐng)?zhí)峁┏鎏? ),謝謝。
          posted on 2012-01-15 19:44 李順利 閱讀(36663) 評(píng)論(2)  編輯  收藏 所屬分類: VCS

          評(píng)論:
          # re: SVN遷移到Git的過(guò)程(+ 一些技巧)[未登錄](méi) 2014-07-09 09:12 | 小小
          啥玩意了嘛  回復(fù)  更多評(píng)論
            
          # re: SVN遷移到Git的過(guò)程(+ 一些技巧) 2015-08-28 11:23 | ohblue@qq.com
          git branch -a列出來(lái)許多tag
          但是 .git/refs/remotes/tags/ 目錄下面沒(méi)東西  回復(fù)  更多評(píng)論
            

          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 深泽县| 乌拉特前旗| 喜德县| 惠安县| 沛县| 隆尧县| 恩平市| 满洲里市| 沙坪坝区| 旬邑县| 罗江县| 高邑县| 钟山县| 彩票| 宁武县| 扶余县| 五寨县| 呼和浩特市| 连州市| 松滋市| 安溪县| 香河县| 布拖县| 阳新县| 涡阳县| 鄂伦春自治旗| 西吉县| 白银市| 翁源县| 南通市| 威远县| 平泉县| 德化县| 阿图什市| 西峡县| 扎囊县| 平湖市| 河源市| 博白县| 潮安县| 昭通市|