はじめに
Gitしか使ったことのない自分がSVNで運用されてい現場へ配属された時の備忘録になります。
「SVNとか今更覚えたくない...」という動機で始めたgit-svnの運用ですが結果的にSVNについてもそれなりに操作できるようになりました(まぁGitとそれほど違わないので...)
自分向けの内容になるのでわかりにく点があるかもしれませんがご了承ください。
今回の内容に関する私の前提知識としては
- Gitは使用歴3年ほど
- GUIクライアント(TortoiseGit)を使用しての一通りの操作
- コマンドでの簡単な(clone,commit, pull, push)操作
程度の知識です。
SVNについては前述のとおり今回始めて触れました。
環境
Windows 7 64bit
Git 2.15.1.windows.2
SVN 1.7.8
SVN自体は git-svn
には必要ないですが念のため。
リポジトリ構成
標準構成
そもそも標準的な構成とは?という話なのですが。
以下のような感じ(らしいです)
/root
|
├trunk/
| └src/
|
├branches/
| ├hoge/
| | └src/
| |
| └hogehoge/
| └src/
├tags/
| ├fuga/
| | └src/
| |
| └fugafuga/
| └src/
こんな感じで(プロジェクト毎?の)RepositoryのRoot下にtrunk,branches,tagsとありbranches,tags内でリビジョンなどが別れているのが標準の様です(ざっくり調べて把握しただけなので間違えてたらご指摘ください)
今回の構成
基本どんな構成でもイケルと思いますが参考までに自分が使用したSVNリポジトリ構成の概要を。
/root
|
├trunk/
| ├ProductX/
| | ├ProjectA
| | | └src/
| | ├ProjectB
| | | └src/
| |
| ├ProductY/
| | └src/
|
├branches/
| ├ProductX/
| | ├dev.1/
| | | └src/
| | ├dev.2/
| | | └src/
| | ├dev.3/
| | | └src/
| |
| └ProductY/
| | ├dev.4/
| | | └src/
| | ├dev.5/
| | | └src/
| | ├dev.6/
| | | └src/
...
上記リポジトリを以下のように管理するのが今回の目標。
//ProductXをGitで管理する
Remote
---------+----------
trunk | ProjectA
| ProjectB
---------+----------
branches | dev.1
| dev.2
| dev.3
---------+----------
git-svnコマンド
基本的に使うのは以下の4つくらい
-
git svn clone --prefix=svn/ -s [path] -T [trunk] -b [branch] -t [tag]
Checkout
を行う。内部ではinit
→fetch
を行っており今回のような例では使用しない。
--plefix=svn/
とするのがgit-svn
では通例らしい。 -
git svn init --prefix=svn/ [path] -T [trunk] -b [branch] -t [tag]
ローカルリポジトリを作成する。
標準構成でない場合はinit
後.git/config
を編集しfetch
する。 -
git svn fetch
init
後に行う。
remoteの情報を取得する。
-r [Revision]
でrevisionを指定してfetch
を行う。-r xxx:HEAD
などとすると指定revisonから最新を取得できる -
git snv rebase
git pull
的なやつ。dcommit
前に行う。 -
git svn dcommit
git push
的なやつ。ローカルのコミットをリモートへ反映させる。
実際に行った手順
最初はclone
を行っていましたが標準構成以外では使えないのでやめましょう。
標準構成でもfetch
ではエラーが出やすいっぽいので基本的にinit
→fetch
でfetch
は最低限必要なrevisionカラにした方がいいと思います。SVNリポジトリってだいたいlogの数が多いので。
-
git svn init --prefix=svn/ -T https://svnrepos.com/trunk/ProductX/ -b http://svnrepos.com/branches/ProductX/
rootのpathは指定せずtrunkとbranchのフルパスを直接指定します。
rootは自動で判断してくれます。 -
.git/config
をエディタで修正
[core]
repositoryformatversion = 0
filemode = false
bare = false
logallrefupdates = true
ignorecase = true
[svn-remote "svn"]
url = https://svnrepos.com/
fetch = trunk/ProductX:refs/remotes/svn/trunk
fetch = branches/ProductX:refs/remotes/svn/branches #追記
---------------------------------------------------------------------
- branches = branches/ProductX/*:refs/remotes/svn/* #↓に修正
+ branches = branches/ProductX/*:refs/remotes/svn/branches/*
---------------------------------------------------------------------
branches = trunk/ProductX/*:refs/remotes/svn/trunk/* #追記
3.git svn fetch -r HEAD
今回は過去のログは必要ないのでHEADのみを指定してリモートの情報を取得します。
よくerror: 128
が出ますがこれは解決できていません。(後述)
また、よくわかっていませんがrevisionを指定したときってどこのブランチから取ってきているんだろうか。指定revisionが存在しているbranchすべて?
この辺曖昧です...
あとはローカルブランチ切っていつもどおりのGitライフです。
問題点
error: 128
よくわからないですが最初のfetch時に100%出ます。
リモートブランチの削除が反映されない
error: 128
の理由の一つがこれに当たります。
最初にfetch
した時点からリモートのブランチが削除、または名前の変更があった時に存在しないブランチをを参照しにいきerror: 128
がでます。
増えた場合は正常に追加されるのですが、削除(変更)された場合にはerrorがでるのはなんとも気持ち悪い。
コメントにgit-svn
を使用した痕跡が残る
git svn dcommit
でリモートにローカルの変更を入れる際に自動で
git-svn-id: hogehoge~
というコメントが末尾に追加されてしまいます。
こっそり使いたい人だとこれではバレてしまいます。
参考にした記事一覧
https://doruby.jp/users/tips4tips/entries/git-svn___2_
https://tortoisesvn.net/docs/release/TortoiseSVN_ja/tsvn-repository.html
http://dqn.sakusakutto.jp/2012/10/svn-git-github-migration.html
http://d.hatena.ne.jp/idesaku/20090323/1237825080
http://sinsoku.hatenablog.com/entry/2014/02/26/231918
https://qiita.com/karumado/items/49b80805ff8dd2c7c17a
https://qiita.com/hidetarou2013@github/items/5473a37bfc5be8867777
最後に
何か追加情報があれば随時更新していきます。