2014年9月8日月曜日

Git subtreeによるライブラリ管理について

前回は Git subtree merge について説明しましたが、今回はそれに深い関係がある Git subtree コマンドについての説明です。

まず基本的なこととして、 Git subtree は Git subtree merge と同じものではありません。 subtree merge はマージ戦略として subtree を指定したマージにすぎませんが、 Git subtree は明確に外部ライブラリの取り込みと submodule の代替を目的として設計された機能です。 Git 1.7.11 以降であれば、 Git subtree を使用するのが望ましいでしょう。

なぜなら、 Git subtree には、 Git subtree merge にはない、下記のような機能があるからです。

  • 取り込んだライブラリ側の歴史を"潰し"(squash)てコンパクトな歴史にできる。
  • 自分のプロジェクトでライブラリ側に変更を加えた場合、それをライブラリ側(上流)のリポジトリにプッシュしたり、プルリクエストしたりできる。
  • ライブラリの取り込みの初期化のためのコマンドが用意されており、3コマンドぐらい要するところを1コマンドで直観的に実施できる。
あとは、比較的小さな利点ですが、下記の特徴があります。

  • Squash したライブラリの歴史には、途中経過のすべては保存していないので、無駄なディスク容量を食わない。(ハッシュだけ記録している)
  • Squash の有無に関わらず、 Git subtree を実施したリポジトリは、 Git subtree に対応していないバージョンの Git でも扱える。たとえば Git subtree 担当者以外は、中央リポジトリや、他のプロジェクトメンバーの Git のバージョンが古くても運用できる。(ただ、 Git subtree に関係するコマンドが打てないだけ)


Git subtree の使い方については、 Atlassian Blog の下記エントリがもっともよくまとまっています。

しかし、原文が英語の日本語翻訳版なので、あらためて噛み砕いて違った角度から説明してみようと思います。


2014年9月7日日曜日

JISの最近接偶数への丸め(JIS Z8401-1999)について

今日はちょっと専門的な話ですが、数値の丸め処理についての記事です。

数値の丸めといいますと、12.34を小数点以下第1位まで丸めて12.3にするような操作で、四捨五入がおなじみですが、実はJISに規定があり、四捨五入は最善の方法とはされていません

JISの決まりでは、偶数丸めといわれる、あまりなじみのない丸め方法を使うことになっています。

偶数丸めは、有効桁の一つ下の、丸めたい桁以下が50000…であるときの挙動以外は、四捨五入と同じです。有効桁より下が50000…であった場合は、その上の桁が偶数であれば切り上げられ、奇数であれば切り下げられます。

たとえば、小数点以下を丸める場合、以下のようになります。

1.5 -> 2
2.5 -> 2
3.5 -> 4
4.5 -> 4
5.5 -> 6

JISの規格では、この偶数丸めを「規則A」、おなじみの四捨五入を「規則B」としており、「規則Aが一般的には望ましい。」としています。なぜなら、「一連の測定値をこの方法で処理すると丸めによる誤差が最小になるという特別な利点がある。」だそうです。

なるほど、と納得しかけますが、何か腑に落ちません。確かに、四捨五入は大きな数値へかたよる方向への丸めですが、偶数に丸めるなどという恣意的な手段が本当に最適なのでしょうか


2014年5月10日土曜日

Gitでsubtree mergeによるライブラリ管理

※ これから新規に外部ライブラリの管理をする場合は、 Git のバージョンが1.7.11以降である必要がありますが、 Git subtree のほうがお勧めです。

背景


Git では外部ライブラリ(これまた Git で管理されている)を取り込む仕組みとして、 submodule が用意されています。たんなるソースのスナップショットをコピーして置いておくのに比べると、外部ライブラリのバージョンアップに追随できるという利点があります。しかし、 submodule は運用上の問題をいくつか抱えています。

1. git clone した直後に git submodule update をしなくてはならない
 リポジトリをクローンしてすぐにコードをいじり始めたくても、余計なひと手間が必要になります。
 GUI クライアントの中には、この作業を忘れないように通知してくれるものもあります。

2. 外部ライブラリの URL が固定化してしまう
 .gitmodules には submodule の URL が埋め込まれており、ライブラリ側の URL の変更があると追随できなくなります。(正確には、追随するために一つコミットが必要になります。) Web に公開されているオープンソースライブラリの多くは URL を頻繁に変えたりはしませんが、内作のライブラリでは構成変更での取回しの悪さは意外と煩わしいものです。

3. とにかく、なんか仕組みがややこしい
 submodule の目的は外部ライブラリの更新をトレースすることであって、プロジェクト本体のソースをいじる人の多くにとっては関心のないものです。このためにユーザー全員に新しい仕組みの使い方を意識してもらうのはオーバーヘッドが大きすぎる気がします。


ちなみに、 Subversion にも svn:externals プロパティという仕組みがありましたが、 Git submoduleと同じような問題があり、使うのがためらわれました。

他の分散型 VCS もいろいろ探索しましたが、結局のところ、 Git の subtree merge ほど素直にやりたいことができる仕組みはありませんでした。


2014年5月2日金曜日

Git for Windowsにてgit diffで日本語が文字化けしないようにする方法のメモ

背景


ソースのコメントは普段は英語でしか書かないし、日本語で書くときはgitkで差分を見ているのでそれほど気にしていなかったのですが、どうしてもコマンドラインで完結させたいという人がいたので方法を探してみました。

まず前提として、UTF-8で書かれた日本語は基本的に化けません。
2011年ごろまでのGit for Windowsは、ファイル名に日本語を使うとひどいことになりましたが、今はファイル名も含めてすべてUTF-8になっていると思います。

ここでの問題は、Shift_JISやJIS(ISO-2022-JP)やEUCな内容のファイルです。昔からメンテナンスしているコードやHTMLには残っている場合があるでしょう。本当に残しておく必要がなければgit filter-branchで全履歴の文字コードをUTF-8へ変換してしまう手がお勧めですが、それはまた別の話。

対策

Shift_JIS用

git config --global alias.dis '! f() { git diff $@ | iconv -f shift_jis;};f'

というコマンドを一度打っておき、"git dis"と打つとSJISが化けない版のdiffが出る。
"git diff"は引き続き化け続ける。

JIS(ISO-2022-JP)用

git config --global alias.dij '! f() { git diff $@ | iconv -f ISO-2022-JP;};f'

EUC-JP用

git config --global alias.die '! f() { git diff $@ | iconv -f EUCJP;};f'

なお、iconv.exeがパスの通る場所に必要です。Git for Windows (MSYSGit) 1.8.4には同梱されていたような気がしますが、私の環境にはどこかから持ってきたやつが生きているだけかもしれません。コマンドを適切に書き換えてやればnkfでもOKのようです。

ただし、diffへの色付け(追加行が緑、削除行が赤など)は失われてしまいます。


所感


一応上記の対策で一定の効果は見られますが、文字コード関連の問題は、やりたいことの本質に関係ないわりに時間を取られるという点で、昔からちっとも進歩した気がしません。すべてがUTF-8になれば幸せになれるかもしれませんが、それにはまだまだ時間がかかりそうです。

2014年3月27日木曜日

Gitについて

何年か見ない間に Maglog がサービス終了してしまったらしいので、開発ブログを移転します。

まずはテストということで、書き溜めていたGitについての記事を投稿してみます。