入門git

入門git

入門git

読みました。git はだいたい一年くらい前からなんとなく使っていますが、一人プロジェクトなので push とか pull とか関係ないし branch とか別に使わんし、と非常にヌルい使いかたをしていて、ちょっと正統的な使い方を知っておかないとなぁと思っていたので丁度いい教科書でした。知らない機能がたくさんありました。bisect とかうまくはまればとても便利そうです。

またオフィスでは Subversion が使われているので、git-svn での協調する使い方も構築しています。1年前も挑戦していましたが、文字コードの設定でつまづいて(上流リポジトリに破壊的なコミットを送ってしまって DB を手作業で修復するはめに)放置していたので再挑戦です。実のところ git-svn のところは本書での新しい情報というのはあまりなくて、うちの環境での問題は他から情報を集めてなんとかしたって感じですけど、リモートブランチの概念とかgitの基礎的な考え方のところが補強できたのでスムースにできたというところもありそうです。今度はバージョン管理そのものはうまくいっていて、あとはチケット管理(Trac)とかレビューシステム(reviewboard)とかとの協調に少し手を入れて全部使えるようにしたら社内的に公開できます。

ちなみにコミットログの文字コードの問題について。Subversion でコミットログに利用している文字コードEUC-JP なので、git 側でもそろえてあげないと化けたメッセージを送ってしまいます。git に利用するエンコーディングを設定するには以下のようにします。

$ git config --global i18n.commitencoding euc-jp
$ git config --global i18n.logoutputencoding euc-jp

i18n.logoutputencoding は表示の時のエンコーディングで、本当は不要な気もしますが、まあ一応つけてます。あとオフィスでは全部同じ設定でいいと思って --global にしてますが、リポジトリ毎に設定したい場合はなしですね。

[追記]もうひとつ文字コード絡みでひっかかってたことがあって回避方法がわかったので記しておきます。
git svn clone した時に Subversionディレクトリの属性を変更したリビジョンのところで invalid UTF-8 string とか言われて止まってしまうので、-r で飛ばしてその次の履歴から取得させていました。今日 svn log の結果や Trac 上での表示を眺めていて、どうもエラーになるメッセージ部分は実際にはコミットログではなくて svn が動的に生成しているメッセージっぽいなということに気がついて以下のようにしたら通りました。

$ LANG=C git svn clone -s --prefix svn/ <svn-repository>

環境変数 LANG が ja_JP.EUC-JP で実行していたので、svnEUC でメッセージを吐いていて、それを git が UTF-8 として読もうとして不正な文字列だと言っていたと。i18n.commitencoding は euc-jp にしていてもこの部分はだめでした(git のバージョンは 1.6.4.1)。LANG も設定されているんだからそれくらい読んで欲しいような気もしますが……。

あと、入門git で知ったこととして、GitHub が最近は http での clone にも対応してくれてるってことがありました。git:// をプロキシ越えさせようとして失敗していたのでこれは嬉しい情報でした。[/追記]

[追記2]だんだん書籍の話からずれていくけど、正確さのためにもうちょっと捕捉します。
実は上のように git svn clone するとその時点での最新のコミットがブランチに対するものだと、master はそのリモートの svn のブランチの複製になってしまいます。このまま git svn dcommit すると、trunk に対してコミットしているつもりがブランチにコミットしてしまうことになります。
なので master をリモートの trunk に対応させておきたいなら、clone した後 trunk の最後の更新まで履歴を巻き戻してあげておかなくてはいけませんでした。

$ LANG=C git svn clone -s --prefix snv/ <svn-repository>
$ cd <repos>
$ git reset --hard svn/trunk

svn/trunk のところは、--prefix svn/ をつけて clone しているので、svn の trunk に対応するリモートブランチ名が svn/trunk だからです。こうしておけばあとは git svn rebase しても trunk の更新だけが取り込まれます。

それにしても本格的に運用する前に気がついて良かった。入門gitにはここまでは書かれていなかったのでひっかかる人結構いるんじゃないかしらん。[/追記2]