LoginSignup
2
0

More than 3 years have passed since last update.

SubversionのリポジトリをGitリポジトリに変換したときの落とし穴

Posted at

はじめに

Subversion から Git に移行したあとに、どこを確認すれば移行が完了したと言えるのかについてメモを残しておきます。
どうやって Subversion リポジトリを Git リポジトリに変換するかに関しては数多の Qiita 記事が存在しますので割愛します。
あくまで、要件を満たすようにリポジトリの変換を行なった後に、本当にちゃんとできているのかを確認するという話です。
そのときに落とし穴があるよ、という話です。
語彙力がないので連続して同じような語尾を使ってしまいがちです。ごめんなさい。

背景

私の所属しているグループには Subversion で管理されているプロジェクトがありまして、最終更新日時が 2012 年とかなので、これがもはや化石と化しているわけです。
化石はとても貴重なので、移動させる場合には傷が付かないように気を付けないといけないんですね。

ディレクトリ同士の差分を取得する

さて一般に、いや私はド素人なので一般を語るのには早いのですが、Subversion のリポジトリを Git リポジトリに変換する際にはgit svnコマンドを叩きます。
その結果として、ディレクトリ構成と各ファイルの中身が一致していれば

傷が付かない

ように無事に移行が完了したと言えるのではないでしょうか。

つまり、Subversion からチェックアウトしたディレクトリdirSub/と、GitHub やら GitLab に push した後にそこから clone したディレクトリdirGit/との差分を取ればよいわけです。
差分を取るので、diffコマンドが使えます。
ファイル単位ではなく、ディレクトリ単位で差分が取りたいので、-rのオプションを使います。
また、ファイル一個一個の差分が明確に知りたいわけではないので、差分があったかどうかの結果だけを表示させる-qオプションも使います。

まとめると、以下のようなコマンドを叩けばいい感じに差分が取れます。

diff -rq dirSub/ dirGit/ > diff.txt

化石を移動させたとき損傷がなかったかの記録が大事なのでdiff.txtとして出力しています。

git svn コマンドの罠

このdiff.txtをそのまま表示すると、めちゃくちゃいっぱいファイルが表示されるかもしれません。
というのも、まずディレクトリ内のルートに.git/が生成されるので、これに関しては確実に差分として出力されるでしょう。
また、「.gitignoreというファイルがdirGit/にだけ含まれていますよ」という出力も見受けられるかもしれません。
git svnコマンドのオプションで、空ディレクトリを保持するための--preserve-empty-dirsというものがあります。
Git リポジトリでは、空ディレクトリの存在が許されないので、オプション無しだとディレクトリ構成が場合によっては維持できません。
そこで--preserve-empty-dirs=trueを施すと、Subversion リポジトリ上の空ディレクトリ内に空ファイル(デフォルトでは.gitignore)を付与して Git リポジトリに変換してくれます。

ここまでは、確かに差分なのかもしれませんが、予定調和としての差分かと思います。(まぁ私はド素人なので、diffを取ってから「あぁ、そういえばこういう差分は当然出てくるかぁ」と気付かされたわけですが。。)

私が罠だというのはこの後で、「hogehoge.txtdirSub/dirGit/で異なりますよ」という出力もわんさか出て来るかもしれないんですね。

これは Subversion の仕様でプロパティの自動追加という機能がある際に起こりうるようです。
以下のように、あらかじめ設定しておいた情報をテキスト内に埋め込む機能が Subversion にはあります。

dirSub/hogehoge.txt
#
# $Id: hogehoge.txt 123 2012-04-17 etc...$
#

(中略)

# end of $Id: hogehoge.txt 123 2012-04-17 etc...$

私は Subversion のことを微塵も理解していないのですが、このプロパティ情報が表示されるときとされないときがあるようです。
git svnコマンドで Git リポジトリに変換したあとは、以下のように、このプロパティ情報が落ちているようでした。

dirGit/hogehoge.txt
#
# $Id$
#

(中略)

# end of $Id$

これが原因で、diffを取ると内容的には一致していても

hogehoge.txtdirSub/dirGit/で異なりますよ」

と出力されてしまうわけですね。
なんという罠。

おわりに

大変申し訳ないのですが、別に「この罠を回避するために、こういう技がありますよ」という記事ではないです。
「罠があるのは分かったので、みなさん気をつけましょうね。」と訴えているだけです。
プロパティ情報を除いて差分を取れるようなスクリプトを頑張って書いても良いのですが、上長も別にそこまで厳密に求めてはいなかったようなので今回はやらないことになりました。

古の遺産をどこかに移す際にはみなさん気をつけましょう。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0