Subversion版本庫匯入Git的步驟與SVN整合步驟

最近開始將Subversion裡的專案複製到Git,在測試過程中記錄了以下於Windows cmd.exe環境裡的Git相關設定與SVN整合的一些注意事項。

Git安裝

Git for Windows由git-scm.org下載,我安裝到d:\util\git資料夾裡,安裝時唯一要注意的是使用cmd.exe而不使用Bash,安裝完畢後再手動把 d:\util\git\bin加到PATH環境變數,讓Git執行檔與部份的Linux命令都能在cmd.exe內執行。

以下範例都把專案放在d:\git-root資料夾裡。

環境設定

在開始操作Git命令之前先把執行時的選項設定好,先以下列指令建立Git的使用者帳號與電郵:

git config --global user.name USERNAME
git config --global user.email USERNAME@yourmail.com.tw

上列設定會存入C:\Users\USERNAME.gitconfig檔案裡,爾後共用的選項就可以直接編輯此檔案。

在執行git log時會出現下列警告訊息:

WARNING: terminal is not fully functional

只要增加TERM環境變數如下就不會再出現這個警告;其中msys是Minimal SYStem(最簡系統)的意思,表示我們使用的Git for Windows是簡化MinGW而來的Git環境:

set TERM=msys

rem # 永久生效:
setx TERM msys

修正git svn的問題

msysGit 1.9.4版的Git在執行git svn時會出現下列錯誤...perl.exe?沒錯,git svn的底層是Perl scripts:

d:\util\git\bin\perl.exe:  unable to remap d:\util\git\bin\libsvn_repos-1-0.dll to same address as parent -- 0x1E80000
      0 [main] perl 3448 sync_with_child: child 2024(0x230) died before initialization with status code 0x1

我們可以使用下列指令修正:

cd \util\git\bin
rebase -b 0x64000000 libsvn_repos-1-0.dll
rebase -b 0x64200000 libneon-25.dll

找出SVN裡需要的資訊

操作Git時需要作者和電郵,我們可以下載svn-migration-scripts.jar來讀取SVN版本庫而產生作者清單,使用命令如下,PATH環境變數需要能找到java.exe:

java -jar svn-migration-scripts.jar authors SVN_URL > authors.txt

svn-migration-scripts.jar除了能產生專案的作者清單外,也能幫我們檢查Git環境是否安裝正確:

d:\git-root>java -jar svn-migration-scripts.jar verify
svn-migration-scripts: using version 0.1.56bbc7f
Git: using version 1.9.4.msysgit.1
Subversion: using version 1.8.5-SlikSvn-1.8.5-X64
git-svn: using version 1.9.4.msysgit.1

You appear to be running on a case-insensitive file-system. This is unsupported, and can result in data loss.

如果你的SVN版本庫很龐大的話,在複製前最好先找出專案的第一個和最後一個版本號,以方便快速取出資料:

svn log -q SVN_URL

由SVN匯入Git

要將SVN的專案複製到Git的方法有好幾種,基本上都是以git svn指令或SubGit工具來完成,如果你的SVN專案資料夾是依照Subversion標準結構建立的(專案/trunk、專案/branches、專案/tags),那麼可以直接用最快速的SubGit來轉換,但若不是標準結構就必須使用git svn來逐版匯入了,但不管那一種方法都能完整的將SVN的歷史轉換到Git裡。

1. 使用git svn fetch

SVN複製最不容易出錯的步驟是:

  • 先用svn指令找出專案的第一個和最後一個版本:
svn log -q SVN_URL
  

螢幕上會列出所有的修訂版本,找出第一個與最後一個(或者用整個版本庫的最後版本HEAD)。

cd \git-root
    md proj1
    cd proj1
    git svn init SVN_URL
    rem # git svn fetch -r 第一個版本:最後版本或HEAD,例如:
    git svn fetch -r 946:8801

執行時間視專案版本庫的大小而有不同,螢幕上會看到各個Revision的檔案異動。

2. 使用SubGit

SubGit的方法是依指定的SVN網址產生一個空的專案Git資料夾,再透過複製這個空資料夾來匯入SVN的版本記錄,步驟有三:

  • 先用subgit configure產生空的Git專案資料夾,假設空的專案資料夾名稱是proj1.git:
cd \git-root
subgit configure  --minimal-revision 946 --svn-url SVN_URL proj1.git

To complete SubGit installation do the following:

1) Adjust Subversion to Git branches mapping if necessary:
    D:\git-root\les\subgit\config
2) Define at least one Subversion credentials in default SubGit passwd file at:
    D:\git-root\les\subgit\passwd
   OR configure SSH or SSL credentials in the [auth] section of:
    D:\git-root\les\subgit\config
3) Optionally, add custom authors mapping to the authors.txt file(s) at:
    D:\git-root\les\subgit\authors.txt
4) Run SubGit 'install' command:
    subgit install proj1
  • subgit install proj1由SVN_URL取出匯出資訊
  • 由proj1.git複製SVN檔案到proj資料夾,proj1資料夾是帶有工作目錄的Git目錄
git clone proj1.git proj1

用git repack壓縮空間

第一次fetch時會花比較多時間,但只要花一次工夫就能把專案完整的修改歷程都複製到本地,日後都能快速操作。取回完畢後可以再用git repack把版本庫整理、壓縮一下:

d:\git-root\proj1>git repack -d
Counting objects: 8922, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (8643/8643), done.
Writing objects: 100% (8922/8922), done.
Total 8922 (delta 4025), reused 0 (delta 0)
Removing duplicate objects: 100% (256/256), done.

壓縮前版本庫裡有20,572個檔案,佔用磁碟空間453MB,repack後變成11,654個檔案,佔用空間為439MB。

開始工作

利用Git操作來更新SVN的步驟有下列幾項:

1. 建立分支

為了方便追蹤與管理,程式的修改最好不要直接改在master上,而應建立分支並於分支上開發,開發完成並提交後再合併回master。建立分支並切換到分支的操作命令是:

git checkout -b NEW_FEATURE

上列指令會建立分支NEW_FEATURE(-b參數)並切換到NEW_FEATURE(checkout子命令)。剛由SVN轉換到Git時會覺得為何Git不提供如svn般的switch命令來切換分支呢?其實Git的checkout操作是把目前的分支(master)簽出(檔案複製)為NEW_FEATURE,底層處理是加一個名為NEW_FEATURE的指標指向master分支的HEAD,和switch有些微差異。

2. 添加到Staging area與提交

開發過程中新增或修改了的檔案必須用git add將之加入staging area:

git add /路徑/變動了的檔案

修改的被記錄檔案可以用-u快速加入staging area:

git add -u

NEW_FEATURE開發完成且測試完畢,將變動提交到版本庫:

git ci -m "變動說明"

3. 合併到master

NEW_FEATURE新加的功能提交到版本庫後,我們必須將這些變動合併回master分支:

rem # 簽回master分支
git checkout master

rem # 將NEW_FEATURE合併到master
git merge NEW_FEATURE

合併順利的話用git commit提交,本地端的處理就告一段落,但若有衝突發生則必須先解決衝突再提交回master。

4. 將變動推回SVN

最後要把最新的修改推回SVN。先做一次svn同步操作:

git svn rebase

再把異動提交回SVN版本庫(SVN是儲放差異,因此用dcommit:diff commit或delta commit):

git svn dcommit

相關連結

##

您可能也會有興趣的類似文章

簡睿

服務於軟體業的資訊老兵。興趣廣泛,學習力佳,樂於分享所知所學。

您可能也會喜歡…

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *