スマホアプリ開発でgit-new-workdirがとても便利だった

まとめ

  • ビルドに時間がかかる環境下では、ビルドのキャッシュが重要
  • ブランチを切り替えると、ブランチ間の差分だけキャッシュが聞かなくなる
  • 別ブランチでちょっとした修正を行おうとすると、移動と戻りとで二回ビルドし直しが起きる
  • リポジトリを複数cloneすると、管理が面倒
  • git-new-workdirなら、.gitを共用しつつ、別々のフォルダで作業できる
  • そのため、ビルドのキャッシュを最大限活用できる
  • スマホアプリじゃなくても便利

ビルドのキャッシュ

Objective-cやJava、C++でスマホアプリを作成する場合、
どの言語もコンパイルが必要になります。
このコンパイルにかかる時間は、アプリの規模が大きくなるにつれて長くなっていきます。

ただし、多くの場合はキャッシュ機能が有効になっており、
変更したファイルのみがコンパイルされるため、
フルビルドをしなければ気にならないはずです。

gitのチェックアウトによるファイル変更問題

gitの場合、ブランチを切り替えると関連するファイルに対して全部変更が走ります。
これにより、ブランチ間の差分が全てビルド対象になってしまいます。

当然と言えば当然ですが、例えばちょっとした変更を別ブランチで行い多場合、
別ブランチに切り替えて一回、作業後戻ってきて一回と、二回ビルドが必要になります。
ブランチ間の差次第ですが、5分で終わる作業のために30分のフルビルド2回…
なんてこともあり、時間が勿体ないです。

かといって、リポジトリを二つ別々のフォルダにcloneすると、
別々にリポジトリ更新したり、容量圧迫、間違えてコミットしたときにcherry-pickできない等々
いろいろと問題が起きます。

こういった場合、git-new-workdirを使うことで、 だいぶ楽に解決することができます。

git-new-workdirとは

これは同じ.gitを使って、複数のディレクトリにリポジトリをcloneできる機能になります。
これにより、二つの別々のフォルダにそれぞれgit cloneしたのと同じ状態を維持しつつ、
片方で作成したコミットや、ローカルブランチ、git stashなどをもう片方で参照することができます。

また、gitのワーキングディレクトリやステージングエリアは共用されないため、
コミットしていない変更が別のディレクトリに影響をあたることはありません。 

インストール

git/contrib/workdir/git-new-workdirに入っていたので、
export PATH=/usr/local/share/git-core/contrib/workdir/:$PATH でパスを通しました。

使い方

git-new-workdir repository_folder new_workdir branch_name(オプション)です。
後述するように、gitのcloneは行わず、元のディレクトリへのシンボリックリンクを張るだけなので、
ほぼcheckout時間しかかかりません。

新しくできたworkdirは、普通にgit cloneしたときと同じように扱えます。

注意点

同じブランチを同時に変更すると、予期せぬ結果になるので注意が必要です。
なお、片方からもう片方が何をチェックアウトしているかはわからないため、
main/subといった使い方や、develop/releaseといった風に分けたり、
必要な時だけ作るといった方が事故らないと思います。

また、新しいディレクトリの.gitには、HEADとindex、logの3つのみが新たに作られ、
残りは全て元の.gitの該当ディレクトリへのシンボリックリンクになっています。
そのため、高速に新しいworkdirを作れますが、
元のリポジトリを消すとworkdirの方もおかしくなると思われます。