- お知らせ -
  • 当wikiのプログラムコードの表示を直してみました(ついでに長い行があると全体が下にぶっ飛ぶのも修正)。不具合があればBBSまでご連絡下さい。

git

はじめに Edit

git-svnを使ってgitをフロントエンドにしつつ、便利にSubversionのリポジトリを扱おう的記事。

まだかなり中途半端で試行錯誤中なので、 参考リンクを見てもらった方がいいかと思います。

絶賛試行錯誤中

メニュー Edit

cygwin git+TortoiseSVN編 Edit

動作確認環境(想定環境) Edit

  • クライアント:Windows XP SP3、Cygwin 1.7.x, git version 1.7.0.4
  • svn+sshでSubversionに接続(TotoiseSVNのTortoisePlinkとPutty,pageantを利用)
  • サーバー:svn 1.4.6 (r28521)古いなあ
  • あらかじめTotoiseSVNとPuttyとpageantの設定を行って subversionでつながるか確認しておく

まとめると、Windows + cygwin 1.7 + cygwin git + TortoisePlink(TortoiseSVN) + pageant
なのでかなり危篤な環境だと思う(=環境固有のところがまるで参考にならないと思われる)

Windowsでうまく行けば、coLinuxや仮想環境のUbuntuをクライアントとしてもやってみる予定。

共通の注意点 Edit

空ディレクトリの扱い Edit

Subversionでコミットしてある空ディレクトリはgit-svnでは自動で作られない模様です。(ネットでは作られるという話もあり、オプションによるのかも)
その際は、空のディレクトリに .gitignoreファイルを作り、追加コミットしてやればOK。

詳細は、../空のディレクトリが消えているんですけどを参照のこと。

SVN_SSH環境変数の設定 Edit

Windows環境だと、gitでsvnに接続する際に使うsshクライアントをSVN_SSH環境変数で見ているようですが、
パスの指定にはクオートしてが必要なようです。
でないと、clone時にパスが不正みたいなエラーが出ます。

cygwinの.bashrcなどに記述する場合は以下のような感じ。(TortoriseSVNのTortoisePlinkを使ってます)

export SVN_SSH="\"C:\\\\Program Files\\\\TortoiseSVN\\\\bin\\\\TortoisePlink.exe\""

コマンドプロンプトやターミナルのbashで試す場合は以下のような感じ。

export SVN_SSH="\"C:\\Program Files\\TortoiseSVN\\bin\\TortoisePlink.exe\""

【超重要】git svn infoで常にどこのリモートブランチを操作するのかを確認しておくこと Edit

「ブランチ切ってマージしてリモートに送信したのに、全然違うところにsvnコミットされてるー!」

なんてことが度々あります。

これは、gitで今どこのリモートに対して操作するか?というのを理解していない、
もしくは途中のコマンドを操作ミスしていたりする場合(例えば違うブランチをcheckoutしてたとか)が多いです。

なので、git branch -b, git checkoutした後やgit svn dcommitなどするときは必ず、git svn infoのURL欄を見て今操作しようとするsvnのリモートブランチがどこかを確認しておきましょう!

もしかしたら、URL欄が意図しないリモートのURLになっているかもしれません。

# リモートのtrunkに向けて作業したい例
$ git co remotes/svn/trunk   # リモートのtrunkに切り替え
$ git svn info               # リモートブランチがどこを向いているか確認
URL: svn+ssh://..(略)../trunk     # ちゃんとリモートtrunkになっていますね、OKです
 :

【捕捉】 git svn cloneしてきたときに、masterブランチのリモートがsvnのtrunkになっていない場合も多々あります!!

その際は、以下のように リモートのtrunkをlocal_trunkとしてローカルブランチ切って、
local_trunkをmasterの代わりに使えばいいと思います。

$ git checkout -b local_trunk remotes/svn/trunk
$ git svn info               # リモートブランチがどこを向いているか確認
URL: svn+ssh://..(略)../trunk     # ちゃんとリモートtrunkになっていますね、OKです
 :

※ もし「local_trunkとかsvnっぽくて名前ダセエから master ブランチをリモートtrunkに割り当てられないのかよ」という方は、
git-svnによる実プロジェクトでのチーム開発 を参考にして、
一旦、local_trunkとしてブランチ切る→元のmaster削除→masterに名前変更→git svn infoでリモートtrunkになってるか確認でよいかと

例えば上記の例だと、

$ git co -b local_trunk remotes/svn/trunk
$ git br -D master
$ git br -m master2 master
$ git co master

cloneするときの注意 Edit

Windowsの想定環境にて、
clone時のドメインの欄は Puttyで設定した設定名 を使えばいいと思います。

例えばこのように。

$ git svn clone -s --prefix svn/ svn+ssh://(puttyの設定名)/svn/repos/myproj/ ~/src/myproject-git

※svnリポジトリはローカルにあるファイルでも相対パスではなく、file:///c:/svn/my_repo/ のようにsvn用の絶対パスで指定しなくてはエラーがでる
模様 (E: 'trunk' is not a complete URL and a separate URL is not specifiedとかエラー出る)

開発の進め方 Edit

開発の進め方はいろいろあるかと思いますが、ここでは新機能やバグ修正のためにgitのトピックブランチを切り、修正をコミット→リモートとマージという指針で行って見ます
(この辺の開発体制や方針によって違うと思うのであくまで参考程度に)

mergeの部分がまだかなり怪しいので注意してください

※ぶっちゃけ、こちらのページが詳しいのでこちらも参照して下さい:git-svnによる実プロジェクトでのチーム開発
→TODO: リンク飛ばすのに頼らずこちらになるべく進め方を書く予定

まずは、リモートのtrunkをローカルのlocal_trunkに割り当てておきます。

$ git co -b local_trunk remotes/svn/trunk

svnのtrunkに行うような作業は、このローカルのlocal_trunkに対して行う、ということになります。
(gitで言えばmasterですね。「local_trunkじゃなくてgit流にmasterの方がいい」という場合は注意事項を参照のこと)

新しくコードを書く前に作業用のローカルブランチ(いわゆるトピックブランチ)を切っておきます。
(svnだと運用によってはブランチが切りにくかったと思いますが、git的には機能を追加する、バグフィックスするという単位でもできるだけバンバンとブランチを切っていくかと思います)

$ git checkout -b fix_bug_of_jamojisan

あとは、ファイルを変更したらコミットまで行います。
(具体的には、通常のgitの利用の仕方のように、git statusやgit diffファイルの変種状況を確認しつつ、git add (ファイル名)等しつつ、git commit してコミットする)

バグフィックス完了!(もしくは機能追加完了!)まで行ったら、今作ったブランチをlocal_trunkにマージします。

$ git checkout local_trunk
$ git merge fix_bug_of_jamojisan

あとは、local_trunkの内容をリモートにコミットします。

$ git svn info               # リモートブランチがどこを向いているか確認
URL: svn+ssh://..(略)../trunk     # ちゃんとリモートtrunkになっていますね、想定通りなのでOKです
 :
$ git svn dcommit    # リモートに投げる

(書いてる途中)

※うーんどうもおかしい ここで、git svn dcommit するとコミットされるのですが、 merge駄目したのだけコミットされますね。(ローカルブランチのログや内容はコミットされず、"Merge branch 'my branch'"とだけsvnのコミットログに残る状態) ブランチで作業する場合は、ローカルブランチではなくリモートブランチを切らないと行けない?
→たぶん原因わかりました…fast-forwardマージの場合は履歴がsvnにも残り、fast-forwardマージじゃないのブランチをコミットした場合は残らない模様(あとで詳しく書きます)

fast-forwardなmergeの場合(=”現在のブランチの先頭位置をマージするブランチの先頭に移動するだけ”の単純なmergeの場合)は、
あたかもブランチをきらずmasterにコミットされたような状態になり、平坦に全ての手元のコミットがSubversionのリポジトリにそのまま素直にコミットされ、コミットログもしっかり残るようです。

このfast-forwardなmergeは、例えばmasterから派生したブランチfix_Aをマージするときにmasterは変更されておらず、他に一度もマージされていない状態で、fix_Aをmasterにマージしたような場合におきます。

反面、fast-forwardでないmerge(=現在のブランチの先頭を移動するだけではマージしたことにできないような複雑(?)なマージの場合)
(書いている途中)

参考リンク Edit


No comment. Comments/git/git-svn?

Name:

Front page   Edit Freeze Diff Backup Upload Copy Rename Reload   New Pages Search Recent changes   Help   RSS of recent changes
Last-modified: 2010-08-25 Wed 20:25:18 JST (2588d)