目的と背景
snv管理されたプロジェクトで、個人としてgitを利用する方法です。
プロジェクト全体でのgit移行の話ではありません。
外部参照が無ければ、 git svn
,SubGit
などを使えば良いのですが、
外部参照のがあると上手く使えません。
特に、外部リポジトリの一部分を取り込んでいる様な場合は、
他の方法を取る必要があります。
TL;DR
- ローカルに、svn チェックアウトした後、別途 git 管理を行う。
- i.e. 同じファイルを、svn と git それぞれで管理する
- git の main ブランチが、svn の最新状態と一致するよう、メンテする。
- svn と git は、お互いの存在を知らず、運用により同期を取る。
手順
環境の作成
-
svnリポジトリをチェックアウトする。
- ビルド生成物などが無い状態が欲しいので、既にチェックアウト済みでも、別途チェックアウトをする1。
-
チェックアウトしたフォルダを、gitの空リポジトリとして、初期化。
- フォルダ内に、.svn と .git が並ぶ
-
フォルダ内にある、.svn 以外の全ファイルを、Git管理する。
- .svn を Git の無視ファイルに設定して、全ファイルを add してコミットすれば良い。
内容の同期
-
普段の作業は Git へ、まとまった,共有する変更は svn へコミットする。
-
svn の Update時には、同じ変更をgitにも行う
Updateの具体的な手順は、
- git を main ブランチへスイッチ
- svn update を実行。
- このとき、追加されたファイルを記録しておく
- svn update で追加されたファイルを、git へ追加
- 全ての変更を、git の main ブランチへコミット
- ファイルの削除も、コミットする。
追加ファイルのメンテが煩雑なため、スクリプトを使った方が良いでしょう。
Rubyスクリプト
# ローカルに変更が無いことを想定。
# リポジトリのパスを引数にする。
repo_dir = ARGV[0]
def GetLineStartWithPrefix( text, prefix )
result = []
text.each_line {|line|
normalized = line.chomp
if normalized.start_with?( prefix )
result.push( normalized[prefix.length,normalized.length] )
end
}
return result
end
def GitCurrentBranch( repo_dir )
msg = `git -C #{repo_dir} branch --contains`
return GetLineStartWithPrefix( msg, "* " ).first()
end
def GetLastChangeRev( repo_dir )
info = `svn info #{repo_dir}`
prefix = "Last Changed Rev: "
return GetLineStartWithPrefix( info, prefix ).first()
end
org_branch_name = GitCurrentBranch( repo_dir )
`git -C "#{repo_dir}" checkout master`
if $?.exitstatus != 0 then
puts( "swich failed" )
exit 0
end
puts( "Start SVN Update" )
svn_update_log = `svn update #{repo_dir} --force`
new_files = GetLineStartWithPrefix( svn_update_log, "A " );
new_files.each { |new_file|
`git -C "#{repo_dir}" add #{repo_dir}/../#{new_file}`
}
comment = "Rev" + GetLastChangeRev( repo_dir );
puts( "Start Git Commit" )
`git -C "#{repo_dir}" commit -a -m #{comment}`
`git -C "#{repo_dir}" checkout #{org_branch_name}`
sleep( 3 )
Note
この方法だと、svnのログをgitから見る事は出来ません。
また、svn で複数コミットとなっていても、git では、1つにまとまってしまいます。
- 自身の作業と他者の作業が明確に分離されるメリットともなりますが。
VisualStudio では、git と svn を同時には扱え無かった覚えがあります。
別途、svnやgitのクライアントソフトを入れると良いでしょう。
-
管理外ファイルの削除でも可 ↩