その他
    ホーム 技術発信 DoRuby git-svnによる実プロジェクトでのチーム開発

    git-svnによる実プロジェクトでのチーム開発

    この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

    こんにちは、SHIMADAです。Gitネタはたろちゃんに先を越されてしまいましたが、自分の環境でも、実際のプロジェクトでGitを実用的に使える状況になってきたので、そのへんについて書こうと思います。

     前提

    前提条件として、

    1. プロジェクトのためのsvnリポジトリがサーバーに用意されていること

    2. リポジトリが

    PROJECT_NAME/
     `- trunk/
     `- branches/
     `- tags/
    

    というSubversionの標準的なディレクトリ構成となっていること

    3. ローカルに最新のgitがインストールされていること

    が条件となります。

    前者が揃っていないという人は、まずSubversionを導入できるように社内での推進をがんばってください。

    申請書とUSBメモリがないとコミットできないんだよ……、という人は、残念ながらあきらめてください。

    (あれはネタだと信じていますが……)

    後者が揃っていない人は、がんばってググってインストールして下さい。

     下ごしらえ

    さて、条件が揃ったところで、下ごしらえです。

    まずローカルで、gitの設定をしましょう。

    $ git config --global user.name "your name"
    $ git config --global user.email account@example.com
    $ git config --global color.ui auto
    $ git config --global alias.co checkout
    $ git config --global alias.ci commit
    $ git config --global alias.st status
    $ git config --global alias.br branch
    

    git config だと カレントワーキングツリーの .git/config に書き込まれます。

    • global オプションをつけると、 ~/.gitconfig に書き込まれます。

    このへんは適宜使い分けてください。

    あと、 ~/.gitconfig をエディタで開いて直接編集してもいいと思います。

     リポジトリのClone

    次に、プロジェクトのリポジトリからローカルのgitリポジトリにcloneしてきます。

    git svn clone -s --prefix svn/ [svnリポジトリのURL] [作成したいGitリポジトリのPATH]
    

    svnリポジトリのURLは、/trunk をつけないプロジェクトのルートまでを書くのが注意点です。

    git svn の -s オプションが、自動的に trunk と branch を見分けて git のリポジトリにとりこんでくれます。

    名前がないと説明に不便なので、リポジトリの名前を仮に決めておきたいと思います。プロジェクトのリポジトリURLhttps://example.com/svn/repos/myproj/ローカルのリポジトリPATH/home/me/src/myproj-git/

    この場合、上記のコマンドはこうなります。

    $ git svn clone -s --prefix svn/ https://example.com/svn/repos/myproj/ ~/src/myproj-git
    

    これで、 myproj のgitリポジトリが myproj-git/ に作成されました。

    内容を見てみましょう。

    $ cd ~/src/myproj-git
    $ find .
    $ git br -a
    $ git svn info
    

    find すると、ローカルのファイルシステムになにがあるか一覧できます。

    うまくいっていれば、チェックアウトされたワークツリーと、.git/ 以下のローカルリポジトリが見えるはずです。

    git br -a は、リポジトリに含まれるブランチを一覧できます。

    git clone に –prefix svn/ をつけたので、リモートブランチは remotes/svn/hogehoge という風に見えているはずです。

    git svn info で、カレントのローカルブランチがsvn上のどのブランチに対応しているかが分かります。

    clone直後はローカルブランチはmasterのはずです。これが、svn/trunkに対応していない場合は、masterを作り直してみてください。

    手順は、

    1. リモートのtrunkに対応したブランチを仮の名前で作成してそこに移動する
    2. 現在のmasterブランチを削除
    3. 仮の名前をmasterにリネーム

    です。具体的なコマンドは、下記のようになります。

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

    (この項目の情報源はこちら

    全部ローカルでの作業なので、上流のsvnリポジトリには一切影響が出ません。

    うまくいかなくても怖がらずに、何度でも繰り返して試せるので安心してやってみてください。

     作業用ブランチの作成

    さて、これでプロジェクトのsvnリポジトリの完全なクローンが、手元にgitリポジトリとして作成されました。

    もし、自分の割り当てられているタスクにsvnのブランチが割り当てられているなら、まずそちらに移動しましょう。

    仮にブランチ名が ver02 だったとすると、手順はこうなります。

    $ git co -b ver02 remotes/svn/ver02
    

    このコマンドでやったことは、

    https://example.com/svn/repos/myproj/branches/ver02 にあるブランチを元にしたローカルブランチ ver02 を作成してワーキングツリーにチェックアウト

    です。

    git svn dcommit は、デフォルトの動作としてローカルブランチと同じ名前のリモートブランチにコミットしに行きます。

    ブランチ名 ver02 を合わせるのは、自分の分かりやすさと同時にgit-svnのためでもあります。

     開発環境の準備

    つぎにやることは開発開発の整備です。

    まず、必要なgemやライブラリをそろえた後、チェックアウトしたワークツリーで開発ができる状態になるまでコードや設定ファイルを修正することになるでしょう。

    Railsならdatabase.ymlやenvironment.rbの修正などです。

    いろいろ環境を設定して、script/serverが動くようになったら、ワークツリーがどうなっているか確認してみましょう。

    $ git st
    

    いろいろ表示が出てきたと思います。

    既存の変更したファイルは

    # Changed but not updated:
    

    というセクションに、新しく作成したファイルは

    # Untracked files:
    

    というセクションに表示されます。

     開発

    開発をはじめましょう。

    新しいコードを書き始める前に、まずブランチをきってそちらに移ります。

    $ git co -b new_feature
    

    すると、

    M  ファイル名
    

    というなにか見慣れた表示が出てくると思います。

    これは、git st で

    # Changed but not updated:
    

    に表示されていたファイルです。

    ワーキングツリー上では変更されているけど、リポジトリにはまだ反映されていないという状態です。

    そのまま開発を続けて、一段落ついたらコミットします。

    まず git st してみましょう。

    # Changed but not updated:
    # Untracked files:
    

    両方のセクションに、自分がコードを書いたファイルが表示されています。

    まず、Untracked files: の中にある、コミットすべきファイルをgitに教えてあげましょう。

    $ git add ファイル名
    

    次に、

    $ git diff
    

    として、自分の作業を思い返しながら変更点を見返していきます。

    ここで思わぬ見落としや、作業の抜け、ミススペルなどを見つけることができます。

    この「作業の振り返り」はなかなかあなどれないものがありますので、忘れずにやっておきましょう。

    間違いを見つけたらすぐに diff を抜けてエディタを起動し、直してまた git diff に戻ります。

    出てきたファイルごとに、これで大丈夫という状態になったら、

    $ git add ファイル名
    

    します。addされたファイルは、

    # Changes to be committed:
    

    というセクションに表示されます。また、addすると次から git diff には現れません。

    git diff して確認 → OKならgit addというサイクルでひとつづつ片付けていくのがおすすめです。

    あと、environment.rb など、リポジトリに変更をコミットしたくないファイルもありますね。

    これは、git addをしないで

    # Changed but not updated:
    

    に置いたままの状態にします。

    ここが、svnなどの普通のバージョン管理システムと違うgitの大きなメリットのひとつです。

    すべての必要なファイルを git add したら、ローカルの new_feature ブランチにコミットしましょう。

    $ git ci -m 'コミットメッセージ'
    

    ここで記入するコミットメッセージは、特別なことをしない限りsvnのりビジョンログにそのまま送信されますから、

    開発チームのルールに沿ったメッセージを書くようにしてください。

     作業ブランチからのマージと上流へのコミット

    new_featureの作業が一通り終わってうまく動いているようなら、ver02ブランチに作業内容をフィードバックしましょう。

    $ git co ver02
    $ git merge new_feature
    

    マージが終わったら、ver02 に new_feature で行った作業が反映されているはずです。

    テストも通って、チームのコミット基準に達しているようなら、リモートのsvnリポジトリにコミットしましょう。

    まず、

    # Changed but not updated:
    

    にあるファイルをワーキングツリーから片付けないといけません。

    $ git stash
    

    これで、stashと呼ばれるリポジトリ内の格納場所に、これらのファイルの変更が保存されました。

    もう一度 git st してみると、ワーキングツリーがきれいになっていることが分かります。

    さっきの消えてしまった変更はどこに行ったのか?

    $ git stash list
    

    これで表示される場所にあります。元に戻したい場合は、

    $ git stash pop
    

    でいつでも戻りますから安心です。

    では改めて、コミット作業に戻りましょう。

    $ git stash
    $ git svn fetch
    $ git svn rebase
    

    まず、fetch/rebaseでリモートリポジトリの最新の状態を持ってきます。

    ここでコンフリクトなどが起きていたらリポートされますので、 >>>>> ====== <<<<< のようないつものマーカーをみつけて衝突を解消してください。

    衝突したファイルは、git上では unmerged な状態になっていますので、解消したら git add して、解消したことをgitに教えてやります。

    衝突がすべて解決したら、あらためてコミットします。

    $ git svn dcommit
    

    これでうまくいけば、svnリポジトリに今回の作業 new_feature が反映されているはずです。

    trac/redmineやほかのsvnクライアントツールなどで、無事反映されているか確認してみて下さい。

    うまくいったようなら、また開発に戻るために、さきほどstashに片付けた変更を手元に戻しておきましょう。

    $ git stash pop
    

    もし、dcommit しようとしてエラーメッセージが出てしまっても大丈夫です。

    作業内容はすべて git の new_feature ブランチに残っていますし、リモートのsvnリポジトリには迷惑がかかっていません。

    深呼吸して落ち着いて、エラーメッセージを読んで、ググって、試して…体で git を覚えて行って下さい。

    have a nice git hacking!