日本熟妇hd丰满老熟妇,中文字幕一区二区三区在线不卡 ,亚洲成片在线观看,免费女同在线一区二区

將 SVN 倉庫遷移到 Git

本文介紹如何將SVN倉庫轉換為Git作為版本控制系統。

背景說明

SVN(Subversion)是一個不太主流的版本控制工具,與Git相比,其劣勢明顯:

  • SVN的集中式管理限制了廣泛參與,僅少數特權用戶能協同編輯,難以滿足開源社區的開放需求。

  • SVN的提交須經服務器,網絡依賴重、效率低,且缺失代碼審核機制,質量難以保證。

參考方案

Git已成為主流的版本控制系統,轉向Git前,建議您先明確遷移范圍,根據需求挑選最佳的遷移方案。

方案一:僅需要遷移SVN的最新數據

如果僅需要遷移SVN的最新數據,不需要遷移SVN的提交歷史記錄,那么遷移操作非常簡單。

只需要 svngit兩個工具即可完成遷移,操作如下。

  • 使用 svn checkout 命令從SVN倉庫檢出最新文件到本地工作區。

  • 在本地工作區執行 git init初始化,完成本地Git倉庫的創建。

  • 編輯 .git/info/exclude文件,在其中添加 .svn等條目以便忽略工作區中的SVN管理目錄。

  • 執行git add -Agit commit命令,創建Git提交。

  • 在遠程Git服務器上創建代碼倉庫,假設倉庫地址的示例地址為<URL>

  • 執行 git remote add origin <URL> 命令,將本地工作區和遠程倉庫地址相關聯。

  • 執行 git push -u origin HEAD 將本地Git倉庫的分支推送到遠程倉庫中。

該遷移方式和普通Git倉庫推送服務端一致,不再贅述。

方案二:需要遷移 SVN 的全部歷史

如果需要遷移SVN的歷史提交,或者需要遷移多個分支和標簽,則需要安裝和使用 git-svn 實現 SVN倉庫到Git倉庫的遷移。

image.png

作為Git的一條子命令,git-svn可以橋接遠端的SVN倉庫和本地的Git倉庫,允許用戶使用Git操作遠端的SVN倉庫。git-svn支持如下操作:

  • 使用 git svn clone 命令將遠程的SVN代碼倉庫克隆到本地Git倉庫。

  • 使用 Git 命令在本地工作區中創建提交。

  • 使用 git svn dcommit命令將本地的Git提交推送到SVN倉庫上,創建SVN提交。

  • 使用 git svn fetch命令持續從SVN倉庫同步提交到本地倉庫。

借助 git-svn,SVN倉庫的完整歷史將無損轉為Git倉庫,讓遷移與協作更加流暢。

針對方案二,遷移操作具體流程如下:

  1. 安裝 git-svn

    Git的內置子命令 git-svn和其他的子命令不同,不是編譯后的原生可執行程序,而是一個Perl腳本,在運行時依賴svn的perl模塊。

    1. 以Ubuntu操作系統為例,首先安裝Git和svn,示例如下:

       apt-get install git subversion
    2. 單獨安裝 git-svn和svn的perl模塊,示例如下:

       apt-get install git-svn libsvn-perl

      執行 git svn,如果輸出正常的幫助信息,則安裝成功。反之,可能會輸出如下的錯誤信息。

      git svn
      Can't locate SVN/Core.pm in @INC (you may need to install the SVN::Core module) (@INC contains: /opt/git/dev/share/perl5 /Library/Perl/5.30/darwin-thread-multi-2level ... ) at /opt/git/dev/share/perl5/Git/SVN/Utils.pm line 6.

      這可能是因為用戶手動編譯安裝的svn、git,在運行 git-svn時無法定位svn的perl模組。解決方案應是將git和svn安裝目錄中的perl模塊目錄添加到環境變量GITPERLLIB ,git-svn即可正確運行,示例如下:

      GITPERLLIB=/opt/git/dev/share/perl5:/usr/local/Cellar/subversion/1.14.2_1/lib/perl5/site_perl/5.30.3/darwin-thread-multi-2level
      export GITPERLLIB
      git svn
  2. 探測 SVN 倉庫布局

    SVN通過簡單目錄拷貝即可創建分支,靈活性極高,連不同版本或不完整的文件樹也能變身分支。但這種混合管理策略,讓自動化識別倉庫中的分支變得棘手,極具挑戰性。

    要從SVN倉庫的目錄結構布局推測其分支和標簽設置,以及主干分支和其他分支、標簽的映射方式,關鍵在于理解SVN的標準目錄結構及其含義。

    • SVN 倉庫標準目錄結構

      SVN 倉庫通常采用以下標準目錄結構:

      /項目根目錄
      ├── trunk
      ├── branches
      │   ├── feature-1
      │   ├── feature-2
      │   └── ...
      ├── tags
      │   ├── v1.0.0
      │   ├── v1.1.0
      │   └── ...
      • trunk:主干分支,存放項目的主開發線。

      • branches:存放各個功能分支或開發分支。

      • tags:存放各個版本的標簽,通常用于標記發布版本。

    • 查看 SVN 倉庫的根路徑

      使用svn info命令可以查看給定地址的SVN倉庫的根路徑和其他信息。

      svn info https://example.com/svn/repo/trunk

      以下是一個示例腳本,用于查看 SVN 倉庫的根路徑,并根據目錄結構猜測分支和標簽的設置。

      #!/bin/bash
      
      # 輸入 SVN 倉庫 URL:將 SVN_URL 變量設置為你要檢查的 SVN 倉庫 URL。
      SVN_URL="https://example.com/svn/repo"
      
      # 獲取 SVN 倉庫信息:使用 svn info 命令獲取倉庫信息,并存儲在 svn_info 變量中。
      svn_info=$(svn info $SVN_URL)
      
      # 提取根路徑:從 svn_info 中提取倉庫的根路徑。
      root_path=$(echo "$svn_info" | grep '^Repository Root:' | awk '{print $3}')
      
      # 輸出根路徑。
      echo "SVN 倉庫根路徑: $root_path"
      
      # 檢查 trunk 目錄:檢查 trunk 目錄是否存在,并輸出其路徑。
      trunk_url="$root_path/trunk"
      if svn info $trunk_url &> /dev/null; then
        echo "主干分支 (trunk) 存在于: $trunk_url"
      else
        echo "未找到主干分支 (trunk)"
      fi
      
      # 檢查 branches 目錄:檢查 branches 目錄是否存在,并輸出其路徑。
      branches_url="$root_path/branches"
      if svn info $branches_url &> /dev/null; then
        echo "分支目錄 (branches) 存在于: $branches_url"
      else
        echo "未找到分支目錄 (branches)"
      fi
      
      # 檢查 tags 目錄:檢查 tags 目錄是否存在,并輸出其路徑。
      tags_url="$root_path/tags"
      if svn info $tags_url &> /dev/null; then
        echo "標簽目錄 (tags) 存在于: $tags_url"
      else
        echo "未找到標簽目錄 (tags)"
      fi

      執行 svn ls命令查看倉庫的根路徑及目錄結構,示例命令及輸出如下:

      svn ls https://example.com/svn/repo/
      #  輸出說明
      #  trunk/:主干分支,存放項目的主開發線。
      trunk/
      #  branches/:存放各個功能分支或開發分支。
      branches/
      #  tags/:存放各個版本的標簽,通常用于標記發布版本。
      tags/

    在SVN轉換Git倉庫時,要通過參數將倉庫布局提供給 git-svn,以便將分支和標簽正確導出。

    其他的布局方式如下:

    • 無分支、無標簽的主干模式:SVN倉庫的根目錄即為項目主干。

    • 多項目模式:SVN倉庫的一級目錄作為項目名,每個項目有自己特定的倉庫布局。

  1. 建立 SVN 和 Git 之間的作者名稱映射

    SVN使用服務端ID作為提交者,而Git允許客戶端自定義提交者,含全名和郵箱。

    • git-svn轉換時,建議提供SVN到Git用戶的映射文件,每行記錄映射關系,示例如下:

      # 格式:SVN用戶名 = Git用戶名 <郵箱>
      loginname = Joe User <user@example.com>
    • 執行 svn log命令可以獲取SVN倉庫全部提交的用戶名列表。

      svn log -q https://example.com/svn/repo/

      從中提取SVN用戶名,請手動編輯生成如上所述的SVN到Git用戶的映射文件備用。

遷移 SVN 倉庫

初始化本地 Git 倉庫

創建一個本地工作區目錄,進入到目錄中,示例如下:

mkdir workdir
cd workdir

執行 git svn init命令將本地工作區初始化為一個Git倉庫。

  • 對于無分支的SVN倉庫,初始化命令示例如下:

    git svn init https://example.com/svn/repo
  • 對于標準布局的SVN倉庫,初始化命令示例如下:

    git svn init -s https://example.com/svn/repo
  • 對于非標準布局的SVN倉庫(例如目錄名大小寫與標準布局有差異),初始化命令示例如下:

    git svn init -t Trunk -b Branches -t Tags https://example.com/svn/repo

拉取遠程 SVN 倉庫同步

執行 git svn fetch命令與遠程SVN倉庫數據同步,將遠程倉庫獲取到本地并轉換為Git提交。如果有SVN/Git 作者映射文件,如文件authors.map,需在命令行中提供。

  • 同步全部歷史提交,命令示例如下:

    git svn fetch -A /path/of/authors.map
  • 同步某個范圍的提交,命令示例如下:

    git svn fetch -A /path/of/authors.map -r 0:100 

推送到遠程倉庫

在云效的服務端創建Git倉庫,用于保存轉換后的結果。

  1. 創建倉庫操作,請參見新建第一個代碼庫

  2. 在服務端頁面獲取Git庫地址。

    高的 (19).png

    說明

    請不要在新庫上創建任何分支、標簽以及文件,確保其為空倉庫,否則可能因為強制推送問題導致遷移失敗。

    示例Git倉庫地址:https://codeup.aliyun.com/$group/repo.git,快速添加遠程源使用 git remote add target命令,將上述地址設為新源,避免與git-svn源重名,示例如下:

    git remote add target https://codeup.aliyun.com/$group/repo.git

    遷移后,SVN倉庫變身Git倉庫,分支標簽一鍵轉換。遷移完成,SVN分支標簽即轉為Git跟蹤分支和標簽。推送時,SVN布局決定推送方式。

    1. 對于無分支標簽的SVN倉庫,倉庫的主干分支映射為 refs/remotes/git-svn,將其推送到目標 Git 倉庫的 master分支(或 main分支),示例如下:

      git push target refs/remotes/git-svn:refs/heads/master
    2. 對于標準布局的SVN倉庫,其分支和標簽混雜在一起,用如下命令重命名標簽,以便本地跟蹤分支和標簽有不同前綴,便于區分。

      git for-each-ref --format="%(objectname) %(refname:lstrip=4)" \
            "refs/remotes/origin/tags/*" |
        while read oid tag; do
            git update-ref "refs/tags/$tag" $oid &&
            git update-ref -d "refs/remotes/origin/tags/$tag"
        done

      然后執行如下命令將本地倉庫的分支和標簽推送到目標Git倉庫。

      git push target \
            --tags \
            refs/remotes/origin/trunk:refs/heads/master \
            "refs/remotes/origin/*:refs/heads/*"

相關文檔