Gitea: SVN から Git への移行

目次

環境情報

移行手順


SVN と Git はどちらも優れたバージョン管理ツールです。残念ながら、SVN から Git に移行するためのプロセス、コマンド、手順に関して誤解を招く記事が Web 上に多数存在します。したがって、この記事では Gitea を例として、SVN から Git に移行する詳細なプロセスを説明します。

この記事の前提条件:

  • Giteaのインストールが完了しました(Gitソフトウェアのインストールを含む)
  • Gitea では、初期構成が完了し、実行されています。
  • Gitea で、組織、チーム、ユーザー アカウント、およびその他の組織コラボレーション情報を必要に応じて構成します (オプション)
  • Gitea では、リポジトリが作成されています (ここでは名前はgsyspmです。リポジトリを初期化する必要はありません)。

環境情報

上記の git リポジトリが作成され、初期化されていない場合は、SVN のコミットと作成者ログを含めて、元の SVN リポジトリから Git に移行する必要があります。エクスポートする必要がある SVN 情報:

  • SVN仓根URL:http://20.1.1.11:7001/usvn/svn/sys_pm
  • SVN ウェアハウス内のトランクのルートに対する相対パス: pmis/01develop/02code/trunk
  • ルートを基準とした SVN ウェアハウス内のブランチのパス: pmis/01develop/02code/branches
  • SVN リポジトリにタグ情報がありません
  • 移行する必要がある SVN バージョン番号の範囲: 1 から HEAD

移行手順

次の手順では、 git svn コマンドを使用して SVN から Git への移行を完了します。

1. 任意の PC 上に移行用の一時ディレクトリを作成します (SVN および Gitea にアクセスできる): merge_svn_to_git/

2. ディレクトリを入力します。SVN 著者から Git 著者へのマッピング情報ファイルを保存するためのテキスト authors_map.txt を作成します。形式は次のとおりです。

ログイン名=JoeUser<[email protected]>

     

あるいは、次の方法で作成者マッピング ファイルを自動的に生成することもできます。

   ローカルの既存の SVN ディレクトリ (ディレクトリは SVN から最新のものにチェックアウトされています) を入力し、次のコマンドを使用して authors_map.txt ファイルを生成 (Bash で実行) し、生成された txt ファイルを merge_svn_to_git/ ディレクトリにコピーし ます 

svn log -r 1:HEAD --xml | grep "<author" | sort -u | awk -F '<author>' '{print $2}' | awk -F '</author>' '{print $1"="$1"<"$1"@yykj.com>" }'  > authors_map.txt


3. 次の 2 つの git svn コマンド (Bash で実行) を使用して、SVN ウェアハウスからローカルにエクスポートします。

#以SVN仓根URL对当前本地目录进行git初始化
git svn init http://20.1.1.11:7001/usvn/svn/sys_pm --prefix fromsvn/ --no-metadata --username=LOGIN_SVNUSER  --trunk=pmis/01develop/02code/trunk --branches=pmis/01develop/02code/branches 



#从SVN仓导出到本地git仓中(耗时可能很长甚至几天几夜)
git svn fetch  -r 1:HEAD --authors-file=authors_map.txt

オプションの説明:

  • --prefix は  、「.git/」および「.git/svn/」ディレクトリ内の「refs/remotes/$prefix/」のプレフィックス値を指定します (値の末尾にスラッシュがあります)。指定されていない場合、デフォルトは「origin /」です (リモート SVN ウェアハウスのエイリアスとしてほぼ理解されています。これが「近似」と呼ばれる理由は、これが標準の git リモート ウェアハウスの概念ではなく、このエイリアスは git Remote コマンドでは表示できないためです)
  • --no-metadata は  SVN メタデータ情報をエクスポートしません (エクスポート時に .svn ディレクトリはローカルに生成されません)。git から git に逆インポートして SVN メタデータ情報をエクスポートする必要がある場合、このオプションは使用できません。
  • --username は  ログイン SVN ユーザー名を指定します。指定しない場合、現在のログイン オペレーティング システム ユーザーがデフォルトの SVN ログイン名として使用されます。
  • --trunk --branches --tags   SVN の標準構造は、trunk/branch/Tags ディレクトリ名が「trunk/branches/tags」で、SVN ウェアハウスのルート ディレクトリに直接配置されます。オプションを - -stdlayout (または -s) に変更する必要があります。ここでの SVN は標準の SVN 構造ではないため (幹線ブランチのディレクトリ名は標準に準拠していますが、SVN ウェアハウスのルート ディレクトリに直接配置されていません)、SVN のルート ディレクトリからの相対パスを指定します。それぞれ --trunk と --branch を介して倉庫
  • -r は、 エクスポートされる SVN バージョン番号の開始範囲と終了範囲を指定します。
  • --authors-file は、   SVN 作成者から git 作成者へのマッピング ファイルを指定します。SVN に存在するコミット作成者の範囲がマッピング ファイルの範囲を超える場合、エラーが報告され、中止されます。

4. エクスポート後、タグとブランチ情報は .git/svn/ ディレクトリにあるので、これに基づいて git ローカル タグとブランチを作成し、次の手順で gitea のリモート エンドにプッシュする必要があります。つまり、タグとブランチには 3 種類の refs 情報があります。

  • SVN のリモート refs 情報 (エクスポート後、 .git/svn/refs/remotesディレクトリに保存)
  • git ローカル ウェアハウスの refs 情報 ( .git/refsディレクトリに保存)
  • git のリモート refs 情報 ( .git/refs/remotesディレクトリに保存)

次のコマンドを使用して、「SVNのリモート参照情報」を「gitローカルウェアハウスの参照情報」に変換し、「SVNのリモート参照情報」をクリーンアップして削除します: (Bashで実行)

#先for循环调整tags(其中“fromsvn”为前文指定的--prefix)
for t in $(git for-each-ref --format='%(refname:short)' refs/remotes/fromsvn/tags);
do
    tagname=${t/fromsvn\/tags\//}
    git tag ${tagname} $t && git branch -D -r $t;
done;

[注] ref は git 内のポインタで、40 バイトの SHA-1 ハッシュ値を指します。このコマンドでは、refs/remotes は各リモート ブランチを指すヘッド ポインターであり、refs/tags はローカル タグのリストです。

コマンドの説明:

  • git for-each-ref   git コマンドは、指定されたパターンに一致する git 内部参照 (「.git/」および「.git/svn/」ディレクトリ内の参照を含む) をリストし、指定された形式で出力します。タグの出力形式の場合: refs/remotes/ fromsvn /tags/XXX ( fromsvnは上で指定した --prefix です)。git svn 初期化コマンドによって生成された .git/config ファイルの内容を表示すると、SVN タグが git ローカル参照の名前にマップされていることがわかります。
  • ${ t / fromsvn\/tags\/ /}   Bash 構文。構造は ${ VAR / PATTERN /NEWSTRING} で、変数の値は定期的に照合されて置き換えられます。ここでの意味は、変数値の「fromsvn/tags/」文字列を削除することです。
  • git tag <タグ名> <オブジェクト> は、   git でローカルにタグを作成します。tagname は正規化された文字列です。<object> が指定されていない場合、タグはデフォルトで現在の HEAD バージョン番号で作成されます。デフォルト値はここでは使用されず、<object> によって次のように指定されます。 refs のハッシュ値
  • git Branch-D -r  リモート参照情報を削除します
#然后再for循环调整branch(其中“fromsvn”为前文指定的--prefix)
for b in $(git for-each-ref --format='%(refname:short)' refs/remotes/fromsvn);
do
    branchname=${b/fromsvn\//}
    git branch ${branchname,,} refs/remotes/$b && git branch -D -r $b;
done;

コマンドの説明: 

  • git for-each-ref   git コマンドは、指定されたパターンに一致する git 内部参照 (「.git/」および「.git/svn/」ディレクトリ内の参照を含む) をリストし、指定された形式で出力します。ブランチ出力形式の場合: refs/remotes/ fromsvn /XXX ( fromsvnは上で指定した --prefix です)。git svn 初期化コマンドによって生成された .git/config ファイルの内容を表示すると、SVN ブランチが git ローカル参照名にマップされていることがわかります。
  • ${ ブランチ名,, }   Bash 構文。構造は ${ VAR ,,} で、すべての変数値を小文字に変換することを意味します。
  • git Branch <ブランチ名> <開始点> は、   git 内にローカルにブランチを作成します。<start-point> が指定されていない場合、デフォルトで現在の HEAD バージョン番号を使用してブランチが作成されます。デフォルト値はここでは使用されず、<start-point> によって次のように指定されます。 refs のハッシュ値
  • git Branch-D -r  リモート参照情報を削除します

5. 無視ファイルを変換します (ここでは実行せず、実際の必要に応じて実行するかどうかを選択します)

git svn show-ignore > .gitignore
git add .gitignore
git commit -m 'Convert svn:ignore properties to .gitignore'


6. その他の調整。上記の処理が完了したら、ブランチやタグの項目が正しいか確認し、履歴で使用されていないブランチやタグの名前変更や削除が必要な場合は、gitコマンドを手動で実行してください。

7. 結果を表示して確認します (Bash で実行)
8. ここまでで、SVN から git へのローカル移行が完了しました。

git branch
git log
git tag

9. 次のステップでは、git local から gitea リモート ウェアハウスにプッシュします (Bash で実行)。

#增加git远端仓定义
git remote add origin_base http://20.200.54.51:3000/gsyspm/base_repos.git


#将本地仓所有分支推送至远端仓(若弹出输入用户密码,请输入gitea_admin用户和密码)
git push --all origin_base


#将本地仓所有tag信息推送至远端仓(若弹出输入用户密码,请输入gitea_admin用户和密码)
git push --tags origin_base

オプションの説明:

  • --all  すべてのローカル ブランチをリモート ウェアハウスにプッシュします (タグ情報はプッシュしません)。
  • --tags   git Push の --tag オプションは、ローカル ウェアハウスのすべてのタグ情報をリモート ウェアハウスにプッシュすることを意味します (ブランチ ブランチはプッシュしません)。

10. ブラウザを通じて gitea サーバーの結果を表示します。

おすすめ

転載: blog.csdn.net/zyplanke/article/details/124468631