項目如何從 SVN 遷移到 Git

#0 系列目錄#git

不少有點歷史的項目,都是用的 Subversion 做爲版本控制工具的,隨着項目須要,不少團隊就打算採用 Git 做爲替代工具了。好,如今問題來了:項目如何平滑的從 Subversion 遷移到 Gitgithub

這裏所謂的遷移是按照版本控制要求來遷移,包括:app

儘量完整的由誰提交的代碼、作出的代碼變動記錄,提交日誌等。svn

儘量完整的分支、標籤等。工具

由於畢竟是不一樣的版本控制工具,轉化過程不免會有瑕疵。佈局

#1 準備環境# 安裝用到的工具的軟件包,這裏以 Ubuntu 爲例:.net

$ sudo apt-get install subversion git
$ sudo apt-get install git-core libsvn-perl perl libterm-readkey-perl

#2 規範 Subversion# 確認項目的 Subversion 地址:版本控制

# 後面統一用 $PROJECT 表示項目的 Subversion 地址
# 這裏的示例項目名稱是 west
https://scms.example.com/svn/projects/west/

規範項目在 Subversion 的目錄結構:日誌

標準的 trunk、branches、tags 目錄佈局。code

branches 和 tags 目錄下的分支和標籤保持平級,例如:

tags/v1.0.0 能夠。

tags/1.x/v1.0.0 多了層目錄就不能夠。

若是不是平級,以 tags 爲例,先執行 svn mv 操做。

方式 1 - 遠程 svn mv

$ svn mv $PROJECT/tags/1.x/v1.0.0 $PROJECT/tags/v1.0.0

方式 2 - 本地 svn mv

$ svn co $PROJECT west_subversion
$ cd west_subversion
$ svn mv tags/1.x/v1.0.0 tags/v1.0.0

最後規範後的目錄示例以下:

west
├── trunk
│   ├── docs
│   ├── west
│   ├── setup.py
│   └── README.rst
├── branches
│   ├── hotfix_add_user_error
│   ├── hotfix_issuse_9527
│   ├── feature_unittest4app
│   └── feature_multi_add_user
└── tags
    ├── v1.0.0
    ├── v1.0.1
    ├── v2.0.0
    └── v2.1.0

#3 生成提交者 ID 和郵箱#

  • example.com表明組織的郵箱,好比:knownsec.com
  • 但若是我的郵箱不是統一的組織的話,就須要手工編輯 users.txt 了

svn log $PROJECT --xml | grep -P "^<author" | \sort -u | perl -pe 's/<author>(.*?)</author>/$1 = $1 <$1@example.com>/' > users.txt

#4 遷出項目代碼(git svn)#

git svn clone $PROJECT --authors-file=users.txt --no-metadata --localtime --stdlayout

--authors-file 是獲得的 git log 提交記錄映射好提交者的信息;

--no-metadata 是獲得的 git log 不帶上對應的 Subversion 信息了,更乾淨;

--localtime 是獲得的 git log 以本地時間爲準,建議用上;

--stdlayout 是先前準備的按規範目錄風格來遷出代碼;

#5 轉化成Git的倉庫格式(tags 和 branches)# 處理 tag:

git for-each-ref refs/remotes/tags | cut -d / -f 4- | grep -v @ | while read tagname; do git tag "$tagname" "tags/$tagname"; git branch -r -d "tags/$tagname"; done

處理 branch:

git for-each-ref refs/remotes | cut -d / -f 3- | grep -v @ | while read branchname; do git branch "$branchname" "refs/remotes/$branchname"; git branch -r -d "$branchname"; done

#6 一些清理工做# 因爲這個轉化會將及歷史上的 branches 和 tags 也都生成一個 Git 的分支和標籤,因此仍是得清理下你認爲不用的分支和標,可能包括:

Subversion 歷史上錯誤的 tags。

Subversion 歷史上臨時的 branches。

冗餘的 trunk 分支(其實跟轉化後的 Git master 分支同樣)。

#7 添加到遠程 Git 倉庫#

  • 好比:GitHub 上建立項目 west
  • 添加本地 Git 項目到剛建立的遠程 Git 倉庫
git remote add origin git@github.com:akun/west.git
git push origin --all
git push origin --tags

#8 完成遷移# 這樣,能夠直接在 Git 下來繼續你的項目了。

git clone git@github.com:akun/west.git

#9 遺留問題# 上述方式轉化其實還有瑕疵,好比:

Subversion 容許空目錄,轉化 Git 用 git svn,處理空目錄帶上 --preserve-empty-dirs 可能會報錯,不處理,可能項目的程序原先依賴空目錄的處理就得修改。

相似 svn:externals,svn:ignore,svn:merge 等屬性丟失

不過問題不大,能夠接受,Subversion 遷移 Git 算是基本平滑遷移。

相關文章
相關標籤/搜索