svn 提交到远程仓库_聊聊如何从SVN迁移源码到Git仓库
背景介紹
這里就不再贅述關(guān)于SVN與Git的區(qū)別以及為什么要遷移源碼到Git了,畢竟Git是當(dāng)前的主流DVCS了,而且已經(jīng)公認(rèn)地非常好用,如果你還在使用SVN的話該考慮換了,是時(shí)候遷移那些遺留代碼了,有興趣可以參閱 Why Git 和 Perforce to Git 了解更多。
通常來(lái)說(shuō),在項(xiàng)目開發(fā)過(guò)程中,難免會(huì)遇到一些老項(xiàng)目代碼正被SVN管理著,但基于當(dāng)下諸多原因,或是擴(kuò)展開發(fā),或是戰(zhàn)略轉(zhuǎn)移,或是為了更好地開發(fā)體驗(yàn),需要將這些在維護(hù)的遺留項(xiàng)目源碼遷移為Git管理。
那如何有效地遷移源碼?并且如何保留提交記錄、分支記錄以及開發(fā)成員等信息呢?筆者前一段時(shí)間就經(jīng)歷了這樣的遷移工作,還是有必要分享一下,也算是一種總結(jié)了。
準(zhǔn)備工作
遷移SVN源碼到Git倉(cāng)庫(kù)的方法肯定不是暴力地將代碼Copy再Paste到Git倉(cāng)庫(kù),也不是直接在項(xiàng)目下git init初始化倉(cāng)庫(kù)的,而是應(yīng)該使用git svn命令操作實(shí)現(xiàn)遷移工作。那git-svn命令如何使用?有哪些注意事項(xiàng)呢?
首先,在正式開始遷移項(xiàng)目之前,需要做一些準(zhǔn)備工作:
準(zhǔn)備一臺(tái)安裝有最新Git環(huán)境的磁盤容量足的電腦
經(jīng)獲知Git倉(cāng)庫(kù)的遠(yuǎn)程地址,無(wú)論是自己創(chuàng)建還是團(tuán)隊(duì)提供
確保對(duì)Git遠(yuǎn)程倉(cāng)庫(kù)有讀寫權(quán)限,無(wú)論通過(guò)用戶名密碼還是SSH訪問(wèn)都行
準(zhǔn)備一份開發(fā)者的SVN用戶名到Git全名+郵件的映射關(guān)系列表文件authors.txt,格式為:
loginname = Username
1
loginname=Username
由于SVN對(duì)每次提交只記錄開發(fā)者的用戶名,而Git存儲(chǔ)其全名和郵件地址,這意味著需要對(duì)開發(fā)者信息進(jìn)行映射轉(zhuǎn)換,在準(zhǔn)備authors.txt文件時(shí),可以到團(tuán)隊(duì)系統(tǒng)數(shù)據(jù)庫(kù)直接查詢開發(fā)者登錄名、用戶名和郵件地址并拼接成指定的格式,或者可下載Atlassian的工具包 svn-migration-scripts.jar? (本地下載),通過(guò)命令拉取SVN倉(cāng)庫(kù)的用戶并生成對(duì)應(yīng)的開發(fā)者信息映射文件,需要Java運(yùn)行時(shí)環(huán)境支持:
java -jar svn-migration-scripts.jar authors https://svn.example.com > authors.txt
1
java-jarsvn-migration-scripts.jarauthorshttps://svn.example.com>authors.txt
轉(zhuǎn)換倉(cāng)庫(kù)
準(zhǔn)備工作完成后可以開始實(shí)施轉(zhuǎn)移倉(cāng)庫(kù)了,應(yīng)該注意的是,在轉(zhuǎn)移SVN項(xiàng)目時(shí)需要根據(jù)是否是標(biāo)準(zhǔn)的SVN文件布局來(lái)確定命令行的參數(shù)。(注:以下所有示意圖均來(lái)自Atlassian)
標(biāo)準(zhǔn)的SVN文件布局
如果SVN倉(cāng)庫(kù)使用標(biāo)準(zhǔn)的了/trunk,/branches和/tags的目錄結(jié)構(gòu),就可在運(yùn)行命令時(shí)加上參數(shù)--stdlayout。
# Windows 下一般需要執(zhí)行如下命令,否則會(huì)報(bào)告路徑超長(zhǎng)問(wèn)題
# 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 下一般需要執(zhí)行如下命令,否則會(huì)報(bào)告路徑超長(zhǎng)問(wèn)題
# Windows 下需要手工安裝Perl
gitconfig--globalcore.longpathstrue
gitsvnclone--stdlayout--authors-file=authors.txt/
gitsvnclone--stdlayout--authors-file=authors.txthttps://svn.waterstrong.com/demodemo
非標(biāo)準(zhǔn)的的 SVN 文件布局
如果SVN倉(cāng)庫(kù)是非標(biāo)準(zhǔn)的目錄布局,那就需要分別顯示指定參數(shù) --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:在之前的命令中已經(jīng)提到需要添加參數(shù)--authors-file=讀取開發(fā)者信息映射文件,文件內(nèi)容格式為loginname = Username ,但如果在文件中不存SVN某個(gè)用戶名的對(duì)應(yīng)關(guān)系,那么git svn操作會(huì)被自動(dòng)中止,因此,必須在authors.txt文件中添加丟失的用戶對(duì)應(yīng)關(guān)系,然后重新運(yùn)行g(shù)it svn命令即可。配置其git config時(shí)的key為svn.authorsfile。
--authors-prog:但如果希望在使用authors.txt文件時(shí),即使某個(gè)SVN用戶名對(duì)應(yīng)關(guān)系不存在,命令也可以執(zhí)行成功并自動(dòng)使用默認(rèn)值,可以使用該參數(shù)—authors-prog= 。配置其git config時(shí)的key為svn.authorsProg,另外,可以在Tutorials - Synchronize 中找到關(guān)于authors文件的更多使用信息。
大倉(cāng)庫(kù)的轉(zhuǎn)換策略
特別注意的是,當(dāng)SVN倉(cāng)庫(kù)非常非常大時(shí),據(jù)官方統(tǒng)計(jì)數(shù)據(jù),若轉(zhuǎn)換擁有33000個(gè)提交的400MB大小的倉(cāng)庫(kù)需要花12個(gè)小時(shí)來(lái)完成轉(zhuǎn)換。因此,在這種情況下,可以選擇找一臺(tái)機(jī)器,運(yùn)行命令后就不管了直到完成轉(zhuǎn)換為止,或者是選擇放棄保存非常老的提交歷史記錄,這樣可以加速轉(zhuǎn)換過(guò)程,如果轉(zhuǎn)換時(shí)只保留部分提交歷史的話可以使用以下命令:
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
清理倉(cāng)庫(kù)
至此,SVN到Git的轉(zhuǎn)換工作接近尾聲,如果只是關(guān)注 trunk 和 master 主分支,那么可以不用在意清理倉(cāng)庫(kù)這一部分的內(nèi)容了,可以直接跳過(guò)進(jìn)入下一節(jié),如果需要清理并將分支和標(biāo)簽進(jìn)行本地化,則可以關(guān)注一下本節(jié)內(nèi)容。
對(duì)于SVN的分支和標(biāo)簽,轉(zhuǎn)換操作是不會(huì)將其導(dǎo)入到新的Git倉(cāng)庫(kù)中,而且在Git分支中也找不到SVN的分支branch,也找不到對(duì)應(yīng)的標(biāo)簽tag,不過(guò)可以使用命令git branch -r可以查看到所有SVN的分支和標(biāo)簽,這是因?yàn)樵谑褂胓it svn clone命令時(shí)會(huì)將SVN的分支和標(biāo)簽導(dǎo)入為Git的遠(yuǎn)程分支和標(biāo)簽,如下示意圖所示。
該策略主要是為SVN與Git雙向同步服務(wù)的,但通常SVN單向轉(zhuǎn)換到Git后都會(huì)直接使用Git了,并且會(huì)禁止SVN提交了,所以還是會(huì)對(duì)分支和標(biāo)簽內(nèi)容進(jìn)行清理以轉(zhuǎn)換為Git的分支和標(biāo)簽。可以使用Atlassian提供的腳本工具快速實(shí)現(xiàn)對(duì)倉(cāng)庫(kù)分支和標(biāo)簽的清理工作:
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分支和標(biāo)簽轉(zhuǎn)換Git的本地分支和標(biāo)簽后結(jié)構(gòu)如下圖所示:
收尾工作
完成以上步驟后,遷移工作基本完成,接下來(lái)需要根據(jù)項(xiàng)目代碼性質(zhì)、團(tuán)隊(duì)約定等情況做一些收尾工作,需要具體情況具體分析。這里會(huì)以一個(gè)Gradle構(gòu)建的Java項(xiàng)目(IDE使用IntelliJ)為例介紹從SVN遷移到Git后的收尾工作:
查看Git遠(yuǎn)程地址是否已經(jīng)配置了,如果還沒(méi)有配置,可以使用命令git remote命令配置origin,比較常用的兩組命令為:
git remote add origin xxx # 添加新的遠(yuǎn)程地址
git remote set-url origin xxx # 修改origin的遠(yuǎn)程地址
1
2
3
gitremoteaddoriginxxx# 添加新的遠(yuǎn)程地址
gitremoteset-urloriginxxx# 修改origin的遠(yuǎn)程地址
使用命令git update-index配置構(gòu)建工具的執(zhí)行權(quán)限,如果有其他執(zhí)行腳本也需要配置相應(yīng)權(quán)限信息:
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文件,根據(jù)不同的項(xiàng)目寫入要忽略的文件,如Java項(xiàng)目ignore文件會(huì)包括:
/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,并根據(jù)團(tuán)隊(duì)內(nèi)部的約定設(shè)置相應(yīng)的權(quán)限,通常會(huì)有一個(gè)檢查清單,比如:
設(shè)置分支模型
添加分支權(quán)限
限定PR合并權(quán)限
配置SVN提交通知
變更CI拉取代碼地址
……
結(jié)語(yǔ)
總得來(lái)說(shuō),從SVN遷移源碼到Git倉(cāng)庫(kù)包括:準(zhǔn)備工作、轉(zhuǎn)換倉(cāng)庫(kù)、清理倉(cāng)庫(kù)以及收尾工作,其中清理倉(cāng)庫(kù)部分可以跳過(guò),其他部分是需要完成的,還必須注意SVN文件布局以及正確地使用authors文件,同時(shí),要考慮在遇到大倉(cāng)庫(kù)時(shí)應(yīng)根據(jù)實(shí)際情況采用相對(duì)適合的遷移策略,最后,應(yīng)遵循團(tuán)隊(duì)的約定,對(duì)照檢查清單完成所有收尾工作。
常見問(wèn)題
如果在macOS Big Sur (11.1)系統(tǒng)上執(zhí)行,可能報(bào)告如下錯(cuò)誤信息:
$ 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
參考鏈接
總結(jié)
以上是生活随笔為你收集整理的svn 提交到远程仓库_聊聊如何从SVN迁移源码到Git仓库的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 用螺纹钢打锄头油淬火还是水淬火好呢用什么
- 下一篇: iqn怎么查 linux_程序员必备:4