subversion から git への移行方法

Subversionリポジトリをgitに移行する際の手順です

本エントリはhttp://pyopyopyo.hatenablog.com/entry/2019/09/03/170000 に加筆したものです

手順1:subversion側の状況を確認する

svnリポジトリの構造には2つのパターンがあります

  • パターン1:trunk/tags/branches を作成している場合
  • パターン2 : 作成してない場合

subversion側のリポジトリがどちらの構成になっているか確認します

SVNでcheckout済みの作業ディレクトリにて,svn リポジトリのURLやパスを確認します

$ cd SVNの作業
$ svn info
パターン1 : trunk/tags/branches を作成している場合
  • URL: svn+ssh:///サーバ名/hogehoge/src/trunk
  • Relative URL: ^/src/trunk

SVNリポジトリは サーバ上の hogehogeディレクトリにあり,
SVNリポジトリの直下には src というディレクトリ,その下に trunkというディレクトリがあることがわかります

src ディレクトリの中身を確認します

$ svn list ^/src/
branches/
tags/
trunk/

trunk, branches, tags というディレクトリがあり,このリポジトリSVNの標準的な構成になっています.本エントリでは,この場合を「パターン1」とします.

パターン2 : trunk/tags/branches を作成していない場合
  • URL: svn+ssh:///サーバ名/hogehoge/src
  • Relative URL: ^/src/

trunk, branches, tags というディレクトリが存在していません.本エントリでは,この場合は「パターン2」として以下説明します

手順2:git側の準備

git のサブコマンド git-svn を使います.インストールされてない環境も多いので,予め確認&追加インストールしておきます.

まず試しに起動してみます.インストール済みならヘルプが表示されます.

未インストールの場合は 以下のようなエラーメッセージが出ます

$ git svn 
git: 'svn' is not a git command. See 'git --help'.

この場合は追加インストールします.debian とか ubuntu なら

$ sudo apt install git-svn

でOK

手順3: svn からgitへの変換

subversionリポジトリから,git の作業ディレクトリを作ります

パターン1 : trunk/tags/branches を作成している場合
$ git svn clone --stdlayout  --prefix=svn/ [svn-repo] [git-dir]
パターン2 : trunk/tags/branches を作成している場合
$ git svn clone  --prefix=svn/ [svn-repo] [git-dir]

[svn-repo]は,上記の svn infoで調べたURLです.
上記の例に従えば svn+ssh:///サーバ名/hogehoge/src/ になります

[git-dir]は出力先ディレクトリ名です. ここに作業デレクトリが作成されます

オプションの意味は以下の通りです

  • パターン1の場合は --stdlayout をつける
  • svn由来のブランチで有ることを示すため "--prefix=svn/" をつける.これで git の remote-tracking ref が refs/remotes/svn/ となります.

確認

ログやブランチの状況を確認します

$ git branch -a
$ git log

tarコマンドにファイルの一覧を渡す方法

ファイルのバックアップ等で,特定のパターンに合致するファイルだけを tar アーカイブに含める際によく使う方法を Tipsとしてまとめました

ポイント

  • tar コマンドの--files-from=FILE (省略形は -T FILE )を使う
  • stdin からファイル一覧を与える場合は tar コマンドに--files-from=- (省略形は -T - )を付ける
  • あとは find などと組み合わせればOK
  • ファイル名にスペースが含まれる場合などは find -print0 | tar cf hogehoge.tar -T - --null などと工夫すれば良い

tar の --files-from=FILE (-T FILE)オプションについて

tar コマンドにファイル名の一覧を渡すには "--files-from=FILE" または "-T FILE" オプションを使う

"--files-from=-" や "-T -" を指定すれば stdin (標準入力)からファイル名の一覧を受け取ることも出来る

ファイル名の区切り文字はデフォルトでは LF

"--null"オプションを使うと NULキャラクタを区切り文字とすることができる

利用例 (findの出力を tarコマンドに渡す)

$ find /path/to -type f  -print0 | tar cf hogehoge.tar -T - --null

findコマンドで抽出したファイルだけを tar コマンドに渡してアーカイブする

ファイル名に全角文字や,空白文字が含まれている場合でも,

  • findに -print0 オプションを付ける
  • tarに --null オプションを付ける

だけでOK

利用例 (テキストファイルからファイル一覧を読み込む)

$ find /path/to  -type f > list.txt
$ tar cf hogehoge.tar --files-from=list.txt

パイプ処理が苦手な人は,一度テキストファイルにファイル一覧を出力,それを --files-from でtarコマンドに渡せばOK


利用例 (特定のパターンに合致するファイルは除外して tar アーカイブを作成する)

$ find /path/to  -type f > list.txt
$ grep -v ".o$"  list.txt > filtered.txt
$ tar cf hogehoge.tar --files-from=filtered.txt

grepコマンドでリストを加工すれば,たとえば拡張子が .o のファイルは除外したtarアーカイブが作成できる

利用例 (特定のパターンに合致するファイルだけの tar アーカイブを作成する)

ソースコードアーカイブ,例えば拡張子が .c または .cpp のファイルだけを tarアーカイブに含める場合は

$ find -name "*.c" -o -name "*.cpp" -print0 | tar cf hogehoge.tar -T - --null 

と書くことができる

$ find -name "*.c"

で拡張子が .c のみ

$ find -name "*.c" -o -name "*.cpp"

で拡張子が .c のみ,または(or条件だから "-o" ) 拡張子が .cpp のファイルをまとめて抽出している