svn 提交到远程仓库_聊聊如何从SVN迁移源码到Git仓库
背景介紹
這里就不再贅述關于SVN與Git的區別以及為什么要遷移源碼到Git了,畢竟Git是當前的主流DVCS了,而且已經公認地非常好用,如果你還在使用SVN的話該考慮換了,是時候遷移那些遺留代碼了,有興趣可以參閱 Why Git 和 Perforce to Git 了解更多。
通常來說,在項目開發過程中,難免會遇到一些老項目代碼正被SVN管理著,但基于當下諸多原因,或是擴展開發,或是戰略轉移,或是為了更好地開發體驗,需要將這些在維護的遺留項目源碼遷移為Git管理。
那如何有效地遷移源碼?并且如何保留提交記錄、分支記錄以及開發成員等信息呢?筆者前一段時間就經歷了這樣的遷移工作,還是有必要分享一下,也算是一種總結了。
準備工作
遷移SVN源碼到Git倉庫的方法肯定不是暴力地將代碼Copy再Paste到Git倉庫,也不是直接在項目下git init初始化倉庫的,而是應該使用git svn命令操作實現遷移工作。那git-svn命令如何使用?有哪些注意事項呢?
首先,在正式開始遷移項目之前,需要做一些準備工作:
準備一臺安裝有最新Git環境的磁盤容量足的電腦
經獲知Git倉庫的遠程地址,無論是自己創建還是團隊提供
確保對Git遠程倉庫有讀寫權限,無論通過用戶名密碼還是SSH訪問都行
準備一份開發者的SVN用戶名到Git全名+郵件的映射關系列表文件authors.txt,格式為:
loginname = Username
1
loginname=Username
由于SVN對每次提交只記錄開發者的用戶名,而Git存儲其全名和郵件地址,這意味著需要對開發者信息進行映射轉換,在準備authors.txt文件時,可以到團隊系統數據庫直接查詢開發者登錄名、用戶名和郵件地址并拼接成指定的格式,或者可下載Atlassian的工具包 svn-migration-scripts.jar? (本地下載),通過命令拉取SVN倉庫的用戶并生成對應的開發者信息映射文件,需要Java運行時環境支持:
java -jar svn-migration-scripts.jar authors https://svn.example.com > authors.txt
1
java-jarsvn-migration-scripts.jarauthorshttps://svn.example.com>authors.txt
轉換倉庫
準備工作完成后可以開始實施轉移倉庫了,應該注意的是,在轉移SVN項目時需要根據是否是標準的SVN文件布局來確定命令行的參數。(注:以下所有示意圖均來自Atlassian)
標準的SVN文件布局
如果SVN倉庫使用標準的了/trunk,/branches和/tags的目錄結構,就可在運行命令時加上參數--stdlayout。
# Windows 下一般需要執行如下命令,否則會報告路徑超長問題
# Windows 下需要手工安裝Perl
git config --global core.longpaths true
git svn clone --stdlayout --authors-file=authors.txt /
git svn clone --stdlayout --authors-file=authors.txt https://svn.waterstrong.com/demo demo
1
2
3
4
5
6
7
# Windows 下一般需要執行如下命令,否則會報告路徑超長問題
# Windows 下需要手工安裝Perl
gitconfig--globalcore.longpathstrue
gitsvnclone--stdlayout--authors-file=authors.txt/
gitsvnclone--stdlayout--authors-file=authors.txthttps://svn.waterstrong.com/demodemo
非標準的的 SVN 文件布局
如果SVN倉庫是非標準的目錄布局,那就需要分別顯示指定參數 --trunk, --branches, --tags。
git svn clone --trunk=/trunk --branches=/branches --branches=/bugfixes --tags=/tags --authors-file=authors.txt /
1
gitsvnclone--trunk=/trunk--branches=/branches--branches=/bugfixes--tags=/tags--authors-file=authors.txt/
Authors 文件的使用
--authors-file:在之前的命令中已經提到需要添加參數--authors-file=讀取開發者信息映射文件,文件內容格式為loginname = Username ,但如果在文件中不存SVN某個用戶名的對應關系,那么git svn操作會被自動中止,因此,必須在authors.txt文件中添加丟失的用戶對應關系,然后重新運行git svn命令即可。配置其git config時的key為svn.authorsfile。
--authors-prog:但如果希望在使用authors.txt文件時,即使某個SVN用戶名對應關系不存在,命令也可以執行成功并自動使用默認值,可以使用該參數—authors-prog= 。配置其git config時的key為svn.authorsProg,另外,可以在Tutorials - Synchronize 中找到關于authors文件的更多使用信息。
大倉庫的轉換策略
特別注意的是,當SVN倉庫非常非常大時,據官方統計數據,若轉換擁有33000個提交的400MB大小的倉庫需要花12個小時來完成轉換。因此,在這種情況下,可以選擇找一臺機器,運行命令后就不管了直到完成轉換為止,或者是選擇放棄保存非常老的提交歷史記錄,這樣可以加速轉換過程,如果轉換時只保留部分提交歷史的話可以使用以下命令:
git svn clone -r${REVNUMBER}:HEAD --stdlayout --authors-file=authors.txt /
git svn clone -r19698:HEAD --stdlayout --authors-file=authors.txt https://svn.waterstrong.com/demo demo
1
2
3
gitsvnclone-r${REVNUMBER}:HEAD--stdlayout--authors-file=authors.txt/
gitsvnclone-r19698:HEAD--stdlayout--authors-file=authors.txthttps://svn.waterstrong.com/demodemo
清理倉庫
至此,SVN到Git的轉換工作接近尾聲,如果只是關注 trunk 和 master 主分支,那么可以不用在意清理倉庫這一部分的內容了,可以直接跳過進入下一節,如果需要清理并將分支和標簽進行本地化,則可以關注一下本節內容。
對于SVN的分支和標簽,轉換操作是不會將其導入到新的Git倉庫中,而且在Git分支中也找不到SVN的分支branch,也找不到對應的標簽tag,不過可以使用命令git branch -r可以查看到所有SVN的分支和標簽,這是因為在使用git svn clone命令時會將SVN的分支和標簽導入為Git的遠程分支和標簽,如下示意圖所示。
該策略主要是為SVN與Git雙向同步服務的,但通常SVN單向轉換到Git后都會直接使用Git了,并且會禁止SVN提交了,所以還是會對分支和標簽內容進行清理以轉換為Git的分支和標簽。可以使用Atlassian提供的腳本工具快速實現對倉庫分支和標簽的清理工作:
java -Dfile.encoding=utf-8 -jar svn-migration-scripts.jar clean-git --force
1
java-Dfile.encoding=utf-8-jarsvn-migration-scripts.jarclean-git--force
將SVN分支和標簽轉換Git的本地分支和標簽后結構如下圖所示:
收尾工作
完成以上步驟后,遷移工作基本完成,接下來需要根據項目代碼性質、團隊約定等情況做一些收尾工作,需要具體情況具體分析。這里會以一個Gradle構建的Java項目(IDE使用IntelliJ)為例介紹從SVN遷移到Git后的收尾工作:
查看Git遠程地址是否已經配置了,如果還沒有配置,可以使用命令git remote命令配置origin,比較常用的兩組命令為:
git remote add origin xxx # 添加新的遠程地址
git remote set-url origin xxx # 修改origin的遠程地址
1
2
3
gitremoteaddoriginxxx# 添加新的遠程地址
gitremoteset-urloriginxxx# 修改origin的遠程地址
使用命令git update-index配置構建工具的執行權限,如果有其他執行腳本也需要配置相應權限信息:
git update-index --chmod=+x gradlew
git update-index --chmod=+x gradlew.bat
git update-index --chmod=+x xxx.sh
1
2
3
4
5
gitupdate-index--chmod=+xgradlew
gitupdate-index--chmod=+xgradlew.bat
gitupdate-index--chmod=+xxxx.sh
添加.gitignore文件,根據不同的項目寫入要忽略的文件,如Java項目ignore文件會包括:
/out
/build
/.idea
.gradle
.DS_Store
*.iml
*.ipr
*.iws
1
2
3
4
5
6
7
8
/out
/build
/.idea
.gradle
.DS_Store
*.iml
*.ipr
*.iws
更新IDE的vcs配置為Git而非Svn,在build.gradle文件修改vcs配置:
idea.project.vcs = "Git"
1
idea.project.vcs="Git"
最后上傳到Repo,并根據團隊內部的約定設置相應的權限,通常會有一個檢查清單,比如:
設置分支模型
添加分支權限
限定PR合并權限
配置SVN提交通知
變更CI拉取代碼地址
……
結語
總得來說,從SVN遷移源碼到Git倉庫包括:準備工作、轉換倉庫、清理倉庫以及收尾工作,其中清理倉庫部分可以跳過,其他部分是需要完成的,還必須注意SVN文件布局以及正確地使用authors文件,同時,要考慮在遇到大倉庫時應根據實際情況采用相對適合的遷移策略,最后,應遵循團隊的約定,對照檢查清單完成所有收尾工作。
常見問題
如果在macOS Big Sur (11.1)系統上執行,可能報告如下錯誤信息:
$ git svn
Can't locate SVN/Core.pm in @INC (you may need to install the SVN::Core module) (@INC contains: /usr/local/Cellar/git/2.29.2/share/perl5 /Applications/Xcode.app/Contents/Developer/Library/Perl/5.28/darwin-thread-multi-2level /Library/Developer/CommandLineTools/Library/Perl/5.28/darwin-thread-multi-2level /Library/Perl/5.28/darwin-thread-multi-2level /Library/Perl/5.28 /Network/Library/Perl/5.28/darwin-thread-multi-2level /Network/Library/Perl/5.28 /Library/Perl/Updates/5.28.2 /System/Library/Perl/5.28/darwin-thread-multi-2level /System/Library/Perl/5.28 /System/Library/Perl/Extras/5.28/darwin-thread-multi-2level /System/Library/Perl/Extras/5.28) at /usr/local/Cellar/git/2.29.2/share/perl5/Git/SVN/Utils.pm line 6.
BEGIN failed--compilation aborted at /usr/local/Cellar/git/2.29.2/share/perl5/Git/SVN/Utils.pm line 6.
Compilation failed in require at /usr/local/Cellar/git/2.29.2/share/perl5/Git/SVN.pm line 25.
BEGIN failed--compilation aborted at /usr/local/Cellar/git/2.29.2/share/perl5/Git/SVN.pm line 32.
Compilation failed in require at /usr/local/Cellar/git/2.29.2/libexec/git-core/git-svn line 23.
BEGIN failed--compilation aborted at /usr/local/Cellar/git/2.29.2/libexec/git-core/git-svn line 23.
1
2
3
4
5
6
7
$gitsvn
Can'tlocateSVN/Core.pmin@INC(youmayneedtoinstalltheSVN::Coremodule)(@INCcontains:/usr/local/Cellar/git/2.29.2/share/perl5/Applications/Xcode.app/Contents/Developer/Library/Perl/5.28/darwin-thread-multi-2level/Library/Developer/CommandLineTools/Library/Perl/5.28/darwin-thread-multi-2level/Library/Perl/5.28/darwin-thread-multi-2level/Library/Perl/5.28/Network/Library/Perl/5.28/darwin-thread-multi-2level/Network/Library/Perl/5.28/Library/Perl/Updates/5.28.2/System/Library/Perl/5.28/darwin-thread-multi-2level/System/Library/Perl/5.28/System/Library/Perl/Extras/5.28/darwin-thread-multi-2level/System/Library/Perl/Extras/5.28)at/usr/local/Cellar/git/2.29.2/share/perl5/Git/SVN/Utils.pmline6.
BEGINfailed--compilationabortedat/usr/local/Cellar/git/2.29.2/share/perl5/Git/SVN/Utils.pmline6.
Compilationfailedinrequireat/usr/local/Cellar/git/2.29.2/share/perl5/Git/SVN.pmline25.
BEGINfailed--compilationabortedat/usr/local/Cellar/git/2.29.2/share/perl5/Git/SVN.pmline32.
Compilationfailedinrequireat/usr/local/Cellar/git/2.29.2/libexec/git-core/git-svnline23.
BEGINfailed--compilationabortedat/usr/local/Cellar/git/2.29.2/libexec/git-core/git-svnline23.
解決方法為:
fix the same issue by changing the first line in
/usr/local/Cellar/git/2.29.2/libexec/git-core/git-svn to #!/usr/local/bin/perl
1
2
3
fixthesameissuebychangingthefirstlinein
/usr/local/Cellar/git/2.29.2/libexec/git-core/git-svnto#!/usr/local/bin/perl
參考鏈接
總結
以上是生活随笔為你收集整理的svn 提交到远程仓库_聊聊如何从SVN迁移源码到Git仓库的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 用螺纹钢打锄头油淬火还是水淬火好呢用什么
- 下一篇: iqn怎么查 linux_程序员必备:4