Git
Subversion

Gitで管理していたコードをコミットログを引き継ぎつつSubversionに移行する

GitからSubversionに移行する際のメモです。(※SubversionからGitに移行する手順ではないです。)

事前準備

  • 予め、svn上にプロジェクトの構成を作っておく(rev1になるはず)。
  • gitリポジトリ上は変更がない状態にしておく
  • gitリポジトリが存在するディレクトリをマルっとコピーしておくと、ミスったときに多分安心です。

今回はmasterブランチで作業するものとします。

手順

手元のgitリポジトリの場所に移動

cd path/to/gitrepo

git svn initで初期化。このとき、trunkまで指定しておく。また、認証情報があれば、--usernameも指定。

git svn init --username "SVNユーザ名" "svn://svnhost/repos/project/trunk"

最新の変更を取得。

git svn fetch

(確認) 変更を取得したことで、SVNのリモートブランチが作成されているか確認。

# remotes/git-svnブランチが作成されていること
git branch --all

# masterとremotes/git-svnのコミットが**繋がっていない**状態であること
git log --all --graph

ここの時点でgit svn dcommitすると、以下のようなエラーが出るはず。

Unable to determine upstream SVN information from HEAD history.

状況とエラー内容から察するに、masterブランチ上にsvnに関する情報(remotes/git-svnが指し示すコミット)がないため、何をcommitするのか判断できないのだと思う。

そのため、remotes/git-svnにmasterの内容を付け足した形にする。
(作業はmasterブランチとして行われるので、元々のコミットが失われる可能性がある。)

git rebase --onto git-svn --root master

(確認) git-svnにmasterの内容が繋がっている状態であること。

git log --graph

問題がなければ Subversion へコミット。

git svn dcommit 

(確認) git-svnとmasterが同じコミットを指している状態になっていること。

git log --graph

(確認) svnのログも良い感じになってること

git svn log

以上です。お疲れ様でした。

トラブルシューティング

SubversionのURLを間違えたので、git svn init をなかったことにしたい

多分他にやり方がありそうですが、すぐに見つからなかったので、私は以下の3つのコマンドを流して仕切り直しを何度かやってました。

自己責任で。

rm -f .git/refs/remotes/git-svn
rm -rf .git/svn
vi .git/config
# [svn-remote "svn"] の列とその項目(url,fetch)を削除

これで再度 git svn init が通るようになります。

git rebaseの操作を間違えて変な結果になったので前のmasterの状態に戻したい

前のmasterのコミットIDがわかればgit reset --hard コミットIDで無理やり戻せます。

コミットIDがわからない場合は、git reflogで直近のmasterへのコミットを探してreset。

reflogで分からない場合はご愁傷様です。