SVNからGitへのリポジトリ移行手順。WSL2は諦めてCentOS7で実施した記録。

git
スポンサーリンク

git-svnを使って、SVNからGitへの移行を行ったときの手順です。

最初はWSL2のUbuntuでやろうとしたのですが、うまく行かんかったので、途中でCentOS7での実施に切り替えております。

ご覧になられる場合は目次からスキップするなどしてください。

 

環境

  • SVNではブランチがtrunkのみで、branchやtagが無い
  • Gitのリモートリポジトリは、gitlab
  • 作業端末:WSL2 Ubuntu
    • 途中からCentOS7での実施に切り替えてます

 

準備(WSL2 Ubuntuで実施)

必要パッケージの準備

git

元々入っていたので割愛。

git-svn

以下のコマンドでインストールする。

$ sudo apt-get update -y

$ sudo apt install git-svn

 

パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています
状態情報を読み取っています... 完了
以下の追加パッケージがインストールされます:
libterm-readkey-perl libyaml-libyaml-perl libyaml-perl
提案パッケージ:
git-doc libyaml-shell-perl
以下のパッケージが新たにインストールされます:
git-svn libterm-readkey-perl libyaml-libyaml-perl libyaml-perl
アップグレード: 0 個、新規インストール: 4 個、削除: 0 個、保留: 0 個。
192 kB のアーカイブを取得する必要があります。
この操作後に追加で 1,466 kB のディスク容量が消費されます。
続行しますか? [Y/n] Y

↑Yで返答。

 

gitにリポジトリを作成する。

gitlabのGUI画面上でリポジトリを作成する。

 

ユーザーリストを作成する。

ユーザーリストは、svnのユーザー名とgitのメアドの対応表。

ここでは、members.txt という名前のテキストファイルで作成する。

svn のhoge ユーザーが、gitだとhoge@gmail.com だった場合、ユーザーリストテキストファイルの1行を使って以下のように記入する。

hoge = hoge<hoge@gmail.com>

別のユーザーで、fuga くんが居た場合も別の行に追記する。

hoge = hoge<hoge@gmail.com>
fuga = fuga<fuga@gmail.com>

リモートsvnリポジトリから、ローカルgitリポジトリを作成する

git svn clone --trunk=/svnリポジトリルートからのディレクトリ/trunk --branches=/svnリポジトリルートからのディレクトリ/branches --tags=/svnリポジトリルートからのディレクトリ/tags --authors-file=members.txt --no-metadata --username=svnでのユーザー名 http://svnのアドレス/svnリポジトリまでのディレクトリ/svnのリポジトリ ローカルに作成されるワーキングディレクトリ名(任意)

オプションの意味:

–branches=
–tags=

これらが存在しない場合は、指定しなくていい。

–authors-file=
ユーザーリストのファイルを指定する。

–no-metadata
svn由来のコメントを移行対象に入れない。

実行するとエラー。Error from SVN, (175009): ネットワークデータが不正です: The XML response contains invalid XML: XML が不正です: no element found (行 1)

 

コマンドを実行すると

Error from SVN, (175009): ネットワークデータが不正です: The XML response contains invalid XML: XML が不正です: no element found (行 1)

 

ってなエラーが出力された。

過去にmacのCatalinaで実施した際も遭遇したことがあったので、その時と同じ対応で、

–log-window-size=4000

オプションを追加してみた。

 

が、事象再発してしまう。

色々調べると、

 

stack overflowに情報があった。ここを見ると、
KDEのsvn2git ツールを使ったほうがいいよ、と。

Qiitaかどっかでもsvn2git の使用を推奨していた。

しかし、svn2gitのREADME見たが、面倒そうだったからとりあえずgit-svn利用するやり方のまま、環境変えてやってみる。

ここからは、WSL2ではなく↓

以下、CentOS7で実施。

CentOS7でもgit-svnをインストールする。

 

# yum install git-svn

 

W: Ignoring error from SVN, path probably does not exist: (175002): RA 層のリクエストが失敗しました:

CentOS7で、

git svn clone を実施するも、以下のエラーを出力し、失敗した。

 

W: Ignoring error from SVN, path probably does not exist: (175002): RA 層のリクエストが失敗しました: REPORT (URL: '/dav/hoge/!svn/bc/1893'): 200 OK (http://192.168.123.123)
W: Do not be alarmed at the above message git-svn is just searching aggressively for old history.
This may take a while on large repositories

 

実は、この原因は簡単で、SVNでtrunkやbranch、tagといったバージョン管理をやっていないことが問題なのです。
根本はtrunkがないことですね。

https://morinohito.site/it/git/git-svn-error

 

あれ?ワシのsvnの環境だと、/trunk だけはあるんだけどな。/branchとか/tabはねぇけど。

コマンドを変えてみる。

git svn clone -s -prefix=svn/ -trunk=/ http://192.168.123.123/hoge/hoge/trunk

上記コマンド実行後、即座に、一行だけ標準出力に表示されたメッセージ。

Unknown option: p

なんぞこれ。

 

さらにコマンドを変え↓

最終的に成功した git svn clone コマンド

 

git svn clone -s --prefix=svn/ --trunk=/ --log-window-size=4000 --authors-file=members.txt --no-metadata --username=kuzuriman http://192.168.123.123/hoge/hoge/trunk hoge_git

だが、ワークツリーのフォルダ内を見ても、ファイルが.git/ 以外に無い。

git branch

で確認した。どうやらHEADが外れている模様。

git branch -a

で確認すると、
svn/trunk

のみ存在していたので、チェックアウトする。

 

git checkout svn/trunk

 

$ ls

ワーキングディレクトリにファイル群が出現した。

 

svn のフォルダと、今、git svn clone したフォルダ、中身が同じか、確認。

diff -qr trunk hoge-git

すると、存在しないファイルがいくつかあった。
調べてみると、全て空のディレクトリだった。
空のディレクトリの中に空のディレクトリがあった場合も作成されない模様

対処として、すべてsvnからディレクトリを手動でコピーしてきた。

$ cp -R trunk/~ hoge-git/~
$ cp -R trunk/~ hoge-git/~
$ cp -R trunk/~ hoge-git/~

タグ情報をgitの形式に変換する。(下記コマンドそのままコピペでOK)

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

ブランチ情報をgitの形式に変換する。(下記コマンドそのままコピペでOK)

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

無視ファイル情報(svn:ignore)をgitの形式(.gitignore)に変換する。 無視ファイル設定してない場合は実施せんでいい。

git svn create-ignore --id=trunk
git add .gitignore
git commit --author="hoge <hoge@gmail.com>" -m "svn:ignore was converted into .gitignore"

 

repositoryのリネームを実施する。

リポジトリが「svn/trunk」なので、「main」に変更する。

gitのワーキングディレクトリのトップに移動する(.git/ ディレクトリがあるところね)

cd hoge/

リネームコマンド実施。

今開いているブランチをリネームする場合は、単純に新しいブランチ名を指定するだけです。

git branch -m <新しいブランチ名>

 

gitのローカルのブランチ名を変更したい - Qiita
ローカルのブランチ名を変更する方法です。Pull Requestのissue番号を間違っていたときなどに活躍します。git branch -m <古いブランチ名> <新しいブランチ名>今開いてい…

 

$ git branch -a
* svn/trunk

$ git branch -m main
$ git branch -a
* main

カワタネ。

余計なブランチ消す → できずに諦めた。

 

$ git branch -a
* main
remotes/svn/trunk

 

$ git branch -d remotes/svn/trunk
error: ブランチ 'remotes/svn/trunk' は見つかりません。

ほう。。。

まいーか。この余計なブランチを、git の remote に pushしなければいいだけか。

放置する。

Gitのリモートにリポジトリをpushする

 

git remote add origin https://git.hoge.com/hoge/hoge.git
git push -u origin main

 

 

コメント