天天看點

《走進git時代系列二》 從SVN遷移到GIT教程

本篇文章是走進git時代系列之二,如何遷移到git的教程, 不了解git的同學可以先看系列一《走進git時代系列一》 你該怎麼玩?

svn 遷移到 git 的簡單原理

圖文教程從taocode svn 遷移到 yuncode git

如何混用svn+git

本文所涉及的工具隻有一個 git-svn , 包含在1.7.1以上的git用戶端版本内, 該工具詳細介紹見: https://www.kernel.org/pub/software/scm/git/docs/git-svn.html

那麼, 有了這個工具, svn to git 就變的沒那麼複雜了, 基本的思路如下:

初始化本地代碼庫: <code>git svn clone -s svn-repository-url</code>

建立分支,切換,送出,合并等純git操作

推送到遠端git 倉庫中

目前分支和遠端svn同步: <code>git svn rebase</code> 。 當同步svn時出現沖突,需要手動修改沖突,git add 添加後繼續rebase: <code>git svn rebase --continue</code>

或者送出到遠端的svn倉庫中,假如你本地是git , 遠端是svn, <code>git svn dcommit</code>

svn和git的工作原理畢竟不同,git對代碼送出的非線性特性在svn中難以再現,如果使用了git-merge或者git-pull,再送出到svn,相關分支上的送出曆史有可能無法展現在svn上。從svn的使用者的角度,無法辨識這是一個送出還是一次合并,是以在和svn協作過程中,盡量讓代碼庫保持線性。

盡量保持git代碼庫的線性特征。比如在new_branch分支中,先和master做rebase,再合并到master分支中:

git rebase master

git checkout master

git merge new_branch

然後在master上做dcommit,就可以在svn代碼庫中看到完整的送出曆史

下面進入正題部分, 我将示範如何從一個svn倉庫遷移到git倉庫中, 示範過程中的代碼庫均為開源代碼,大家可以直接下載下傳來練習:

svn 位址為淘蝌蚪開源社群中的一個推薦倉庫: http://code.taobao.org/svn/qlexpress/

首先我們看一下本地的svn和git用戶端版本:

《走進git時代系列二》 從SVN遷移到GIT教程

使用指令<code>git svn clone -s http://code.taobao.org/svn/qlexpress/</code> , 為什麼要加-s , 因為這個倉庫是按照标準的tags、trunk、branches結構劃分的,則git svn會将對應的分支、标簽識别存放到git的結構中。 如果不加-s,不會将tags、branch按照git的結構進行劃分 。

《走進git時代系列二》 從SVN遷移到GIT教程

從圖中可以看到, git svn 是将每次svn 的送出計算出來寫入git的每一個commit version, 是以, 如果你的svn代碼庫version 非常多, 這個過程會很慢, 那麼,我們可以通過 <code>git svn clone -s -r$revnumber:head http://svnurl/yourrepo</code> 來檢出最後的幾個版本。 舉個栗子:

先通過<code>svn log http://svnurl/yourrepo| tail -4 | head -1</code> 擷取目前倉庫的起始version,假設是r10, 那我們如果要檢出所有版本,指令為<code>git svn clone -s -r10:head http://svnurl/yourrepo</code>

再通過<code>svn info http://svnurl/yourrepo | grep revision</code> 擷取最新的svn版本号,假設我們要最後10個版本,則指令為<code>git svn clone -s --prefix=svn/ -r90:head http://svnurl/yourrepo</code> , 示例圖如下 :

《走進git時代系列二》 從SVN遷移到GIT教程

這裡我們将全部version 都檢出,經過幾分鐘的過程,我們可以看到此目錄下同時具備svn和git的一些資訊:(注:截圖裡st=status , br=branch)

《走進git時代系列二》 從SVN遷移到GIT教程

svn的資訊:

《走進git時代系列二》 從SVN遷移到GIT教程

通過<code>git show-ref</code> 可以看到有master這個本地分支,同時有remote 分支trunk , 1.4.1, 2.1.0 等, 通過git version 發現trunk 和 master分支的版本是一樣的, 其他幾個分支和svn用戶端branches 目錄下的結構是一樣的。 說明 git svn 将svn的主幹和其他分支 轉換為了git的 master 和其他branch 。

《走進git時代系列二》 從SVN遷移到GIT教程

假如你的svn倉庫是非标結構的,也可以用“-t 主幹名 -b 分支名 -t 标簽名”參數分别指定歸類,

例1: <code>git svn clone http://svnurl/yourrepo -t trunk -b branches -t release</code> 這裡制定了release是一個标簽集。

例2:<code>git svn clone http://svnurl/yourrepo/project1 -t rpm -b branches -t release</code> 這裡指定了svn庫中的rpm目錄是主幹、branches目錄是分支集,release目錄是标簽集,而project1下的其他目錄會被忽視。

這時我們發現有一些remote 分支,不是本地倉庫的分支, 我們還沒有設定remote, 那就需要執行以下的指令将remote 分支移回本地分支。

這個示例倉庫沒有tag ,隻有branch ,是以隻要把branch 挪到本地即可, 執行後效果如下:

《走進git時代系列二》 從SVN遷移到GIT教程

這時我們就需要一個真正遠端的git 倉庫了, 我們使用https://code.aliyun.com 來建立。 首先使用阿裡雲賬戶登入code.aliyun.com , 然後在左側導航内“個人資料設定” --&gt; “ssh 秘鑰” 這裡添加一個我本地的公鑰,本地公私鑰 通過 <code>ssh-keygen</code> 指令 一路回車後建立, 然後将~/.ssh/id_rsa.pub的内容粘貼到下圖中:

《走進git時代系列二》 從SVN遷移到GIT教程
《走進git時代系列二》 從SVN遷移到GIT教程

現在回到網址首頁,建立一個同名為qlexpress 的開源代碼庫:

《走進git時代系列二》 從SVN遷移到GIT教程

先在我本地做git 的基本全局設定:

可以看到這是一個空的git代碼庫:

《走進git時代系列二》 從SVN遷移到GIT教程

在本地的倉庫中,增加遠端git remote 位址:<code>git remote add origin [email protected]:tangrong111/qlexpress.git</code> , 這些指令在雲code 中建立代碼庫後頁面裡有提示,可以直接複制,當然我這個是從svn 倒過來的代碼庫,隻需要這一個遠端位址即可,不需要git 初始化之類的操作:

《走進git時代系列二》 從SVN遷移到GIT教程

這時,我們通過<code>git status</code> 檢視一下,避免本地有其他不小心的修改, 然後再執行 <code>git push origin --all</code> , 就可以鑒證這偉大的時刻了:

《走進git時代系列二》 從SVN遷移到GIT教程

同樣通過<code>git log</code> 可以看到每一個commit 都有記錄 對應的svn版本位址, 而且svn的 commit log 也被轉換為了 git的commit log, 是不是很神奇。 這時,我們重新整理一下https://code.aliyun.com/tangrong111/qlexpress 這個頁面,代碼庫已經被推送上來,并記錄了大小,分支,送出次數等資訊:

《走進git時代系列二》 從SVN遷移到GIT教程

看下檔案清單:

《走進git時代系列二》 從SVN遷移到GIT教程

最後看一下commit 記錄, 可以檢視每個分支的,每個記錄都有,是不是很帥! 從此就可以快樂的在yuncode上玩耍了!

《走進git時代系列二》 從SVN遷移到GIT教程

最後我介紹一下, 如何在本地使用git, 同時遠端有git和svn并存的情況,以及沒有遠端git隻有遠端svn,但你本地又想用git的情況(這種屬于公司内隻有svn,你又是個git死忠,當然你可以推薦你們公司使用yuncode ,也有saas版可以單獨部署的哦)

遠端git和svn都使用,流程如下:

那麼本地svn分支對應svn的遠端倉庫,本地master分支對應git的遠端倉庫

你可以繼續建立本地分支進行開發, 當要送出到遠端git時,切換到master分支下, 合并你的分支, git push 到git遠端上

如果代碼要更新到svn上:

如果沒有遠端git倉庫, 那麼:

修改本地代碼後, 通過 <code>git add/commit</code>送出到本地git庫

定期rebase 擷取svn, 定期 dcommit 送出到svn庫

沖突與解決

假設其他同學也在同時開發,已經送出了新版本到svn中, 當你git svn dcommit 的時候提示本地檔案已經過期

你通過 git svn rebase 擷取svn的最新檔案版本, 導緻檔案出現沖突

不過這個時候svn的版本資訊已經添加到本地的git庫裡, 通過git log 可以看到

那麼,打開沖突檔案,修改代碼,解決沖突。 執行

此時git的版本成功加入到本地版本庫, 可以通過git log 檢視。

執行 <code>git svn dcommit</code>把解決後的檔案同步到svn遠端庫中,到此算是完成一次沖突解決。

其實, 你如果對svn 的log 不是那麼看中, 最簡單的就是在 code.aliyun.com 上建立一個git 倉庫,然後代碼拷貝過去, 從第一個version 開始新的裡程 ~~

假設你看完這篇文章明白了 怎麼從svn 遷移到 git 中, 那麼就敬請期待 走進git 時代的系列三 : <code>《玩轉雲code最佳實踐》</code> 吧 !