使用 TortoiseGit 將 SVN 轉移到 Git 的紀錄

Git(官網)在 Heresy 來看,他最大的好處,就是它是一個分散式版本控款系統;有別於 SVN 這類的中央控管式的版本控管系統,Git 最大的好處是,你可以簡單地把一個 Server 上的「Repository」複製下來,在自己的電腦上、獨立進行版本控管,並且在必要的時候,還可以透過 push / pull 的機制、簡單地和 Server 端的東西最整合!所以就算是沒有網路,也可以自己在自己的電腦上、進行版本控管的動作~

而這篇文章,是 Heresyn 自己在試著透過 TortoiseGit 把版本控管系統,由 Subversion(SVN、官網),轉移成 GIT的紀錄。在環境的部分,Heresy 這邊是在 Windows 環境下進行,本來就已經安裝、設定好了這兩者在 Windows 上所使用的工具;這邊 Heresy 所使用的是 TortoiseSVN(官網)和 TortoiseGit(官網)這兩套軟體。

不過這邊也先強調一下,這邊的方法應該不是最完美的方法,雖然應該是可以用、但是還是有一點小問題的

首先,Git 本身就有提供使用 SVN 的 Repository 當作來源的功能,所以其實也是可以透過 TortoiseGit,來存取 SVN 的 Repository 的!(參考

而這邊轉移方法的概念,主要就是:

先透過 Git 把 SVN 上的 repository 整個複製(clone)下來,
然後再建立一個新的 Git bare repository,並把這個 clone 下來的 repository 上傳到這個新建的 Git bare repository 裡。
而之後,就可以用這個新建立出來的 Git repository 了!


SVN Repository 來源

不過,由於 Git 的 SVN 功能僅能透過 SVN、Http 或 SSH 這些通訊協定來存取 SVN repository(也就是svn://x.x.x/http://x.x.x/ssh://x.x.x/ 這樣形式),並不支援本機上的 repository(file://… 的形式);所以如果是要使用本機上的 repository,則需要先建立起一個 SVN Server。而如果本來就有 SVN Server 的話,這部分就可以跳過了。

要建立 SVN Server 最簡單的方法,就是透過 TortoiseSVN 的安裝目錄下的 bin 資料夾裡面的 svnserve.exe 這個程式,來建立臨時的 SVN Server。使用方法基本上就是再命令提示字元裡面,執行下面的指令:

svnserve.exe -d --listen-port 1111 -r E:\TestSVN

其中,「1111」是他要使用的網路連接埠,可以自己選擇;而 E:\TestSVN 則是 SVN repository 的所在路徑。

執行完這個指令後,命令提示字元視窗並不會有任何反應,而是會就停在那不動,不過這個時候,其實就已經建立好 SVN Server、並可以透過 svn:://localhost:1111 來做存取了。


透過 TortoiseGit 複製 SVN Repository

在確定 SVN Server 是可以存取的情況下,接下來就可以透過 TortoiseGit、來把 SVN Repository 整個複製下來了~

要進行這個動作的方法很簡單,就是透過檔案總管右鍵選單裡、選取 TortoiseGit 所提供「Git Clone…」的這個功能,來做操作。

在這個視窗裡面,基本上就是在「URL」的欄位裡,填入 SVN repository 的位址(例如上面的 svn:://localhost:1111)、設定要輸出的目錄(Directory、這邊假設是「E:\TestGit」),並且把下方的「From SVN Repository」勾起來,接下來就按下方的「OK」,就可以開始複製了~

不過,由於 Git 會把 SVN repository 裡面的紀錄,一筆一筆抓下來,所以如果 SVN repository 比較大的話,這個流程會拖得很久…所以個人是建議,執行後就放在那不要管他,等個晚一點再來確認他的進度就好了。

另外,如果 SVN Server 是需要登入的話,最好也設定好可以讓他自動登入,以避免在複製的過程中,因為頻繁地跳出要輸入帳號密碼的對話框而造成的麻煩、甚至因為太久沒輸入而失敗。
如果是 SSH 的話,就是用 pagent 來加上 ssh key、作為驗證;不過Heresy 自己在 clone SSH 的 SVN repository 的時候,還必須要把 URL 加上使用者帳戶(例如:ssh:://heresy@localhost:1111),不然他會一直問使用者帳號。

當整個複製完成之後,這個資料夾,就是一個可以使用 TortoiseGit 來管理的版本控管系統了~而除了可以使用 Git 的功能外,也是可以把本來的 SVN Repository 當作一個特別的 remote repository 來操作的。


SVN 的 branch 與 tag

到上面為止,已經算是轉移到一個段落了。不過,由於這時候,雖然他是把 SVN Repository 當作一個遠端的來源,並不會把 SVN Repository 裡的 branch 和 tag 都在 local 建立出來,而是會以 remotes/<branch_name>remotes/tags/<tag_name> 的形式,統一當作遠端的 branch 來做處理。

而如果希望把這些遠端的 branch 建立成 local Repository 的 branch 的話,則是要透過 Giut Bash 執行下面的指令:

git fetch . refs/remotes/*:refs/heads/*

這樣在 local 端,就可以直接看到這些 branch 了。

不過比較討厭的,就是 Git 會把 SVN 的 tag,都當作 branch 來做處理;如果需要把它修正成為真正的 Git 的 tag 的話,則是要執行下面的指令:

git for-each-ref --format='%(refname)' refs/heads/tags |
cut -d / -f 4 |
while read ref
do
  git tag "$ref" "refs/heads/tags/$ref";
  git branch -D "tags/$ref";
done

這樣的話,他就會去掃過所有的 remotes/tags/<tag_name>,把所有的被當作 branch 的 tag 刪掉,並建立真正的 tag 出來。


建立新的 Git Bare Repository

所謂的「Bare Repository」,算是 GIT 裡面一種特別的 repository。一般的 Git Repository 除了 Git 的資料庫外,還會有一份 working copy,也就是現在要用來操作的檔案,所以可以直接用來做操作。

而 bare repository 則就比較類似 SVN 的 repository,是用來當中央伺服器用的,裡面只有資料庫、沒有 working copy,不能直接拿來使用;能對他做的操作,基本上就是複製(clone)和同步(push、pull 等等)了。

所以,基本上 bare repository 算是在團隊裡面,放在 Server 上共用、用來同步的 repository。如果已經有建立好的 Git bare repository 的話,基本上應該就是用現有的就可以了。

而如果沒有的話,在 Windows 上建立一個 bare repository 的方法,基本上就是先建立一個新的資料夾(這邊假設是「E:\BareGit」)、在裡面點選滑鼠右鍵,選擇 TortoiseGit 的「Git Create repository here…」;然後再跳出的 Git Init 的視窗裡面,則是把「Make it Bare」打勾後、按「OK」就可以了。


把資料上傳到 Git Bare Repository

當 Git 的 Bare Repository 準備好後,接下來就是把剛剛從 SVN repository 複製下來的東西(E:\TestGit),都傳到這個新的 Bare Repository 了。

這邊的方法,基本上就是使用 Git 的「Push」這個功能。只要在剛剛複製好的 Git Repository (E:\TestGit)裡,選擇又見選單裡、TortoiseGit 的「Push…」這個指令,然後進行下列設定:

  1. 點選「Destination」右方的「Manage」,把剛剛新建立(或已有的)Bare Repository,加到 URL 裡(以上面的例子來說,就是「E:\BareGit」),並幫它取個名字後,按下下方的「Add New / Save」,來建立新的 Remote Git Repository。

  2. 回到「Push」的介面後,把「Ref」下的「Push All branches」勾起來,以把所有的分支都存到 Git Bare Repository 裡。

  3. 如果要把「tag」也傳上去,則是要把下方的「Options」裡的「Include Tags」也勾起來。

都設定好了之後,按下「OK」,他就會把所有的版本訊息,都傳到 Git Bare Repository(E:\BareGit)裡了~而之後呢,就是使用這個 Git Bare Repository 來當作版本控管的主要來源就可以了!

如果要有一個乾淨的 Git Repository 來做之後的操作的話,就是再從這裡,重新 Clone 一分就可以了。
而同時,除了 Git Bare Repository(E:\BareGit)以外、剛剛建立出來的臨時 Git Repository 資料夾(E:\TestGit),也可以刪掉了~


參考資料:

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。