空のディレクトリを維持するための、 .gitkeep と .gitignore の使い分け

空のディレクトリをコミットに含めたいときは、2つのやり方があります。.gitkeep を使う方法 と、 .gitignore をおいておく方法(例えばPHPのフレームワーク Larave で用いられている方法)です。

空のディレクトリを保持する目的で使用する .gitignore は、たいていの場合、以下のような内容になっています。

.gitignore
*
!.gitignore

使い分けの基準

.gitkeep.gitignore は、「空のディレクトリにファイルが追加されたときに、そのファイルを Git での管理対象に含めたいか?」という基準で、使い分けられます。
含めたい場合は .gitkeep 、含めたくない場合は .gitignore を使います。

.gitkeep を使う基準と例

.gitkeepは、「デフォルトではファイルが存在しないけれど、ファイルが追加されたら、そのファイルを Git での管理対象にしたい」場合 に使います。

例えば、lumen の databse/migration ディレクトリなどは、良い例です。
このディレクトリは、データベースの初期化をするスクリプトをおいておくために使われるディレクトリなので、「フレームワーク開発者的には、 デフォルトでおいておくファイルは特にない。しかし、 ユーザが 作ったファイルは Git でバージョン管理する対象にしたい 」というユースケースが容易に想定できるので、 .gitkeep が使われています。

.gitignore を使う基準と例

.gitignore は、「デフォルトではファイルが存在しないし、そこに作られたファイルもバージョン管理したくない」場合 に使います。
例えば、「ログの出力先」やキャッシュ置き場などです。ログファイルやキャッシュファイルは、 バージョン管理する必要がありません。むしろ、したくないでしょう。

そもそも空のディレクトリをコミットに含めるべきではない例

コンパイル言語では、コンパイルで出力されるファイルを、「プロジェクトルートの .gitignore に拡張子を指定して書かれている」ことが多いと思います。例えばC++Java がそうです。その結果、コンパイル結果の出力先ディレクトリは空になるので、 Git の管理対象から外れます。
これは、その言語のユーザに 「コンパイル結果の出力先ディレクトリの名前」が一般的に共通認識として知れ渡っており、ディレクトリ構成として明示的に維持しておく必要性がない ため、このアプローチで良いと思います。

空のディレクトリのバージョン管理方法の良くない例

コミットに含めるべきなのに含められていない例

コンパイル結果の出力先ディレクトリは、ディレクトリ自体をバージョン管理の対象に含めなくて良い、と言いました。しかし、 TypeScript は別です。

TypeScript の、コンパイル結果の出力先のディレクトリは、バージョン管理の対象になっていないことが多いようです。例えば、ionic の dist ディレクトリなどがそうです。

拡張子 .js は、ヘルパースクリプトを書いたりしたときや、 gulp.js などに使用されるので、他のコンパイル言語と違って、 拡張子を用いて .gitignore できません
さらに、出力されるディレクトリをしていするにしても「一般的な共通認識がない」ためにディレクトリを .gitignore に追加することが好ましくありません。ディレクトリ自体をバージョン管理の対象から外してしまった場合、プロジェクトのディレクトリ構造がわからなくなってしまいます。わざわざディレクトリ構造を調べるためだけに、 package.jsongulp.js に処理を追加するのは馬鹿げている、と私は思います。

このような場合に、「 空のディレクトリを保持する目的で使用する .gitignore 」が便利です。

独自路線を行こうとしてミスった、CakePHP

これは、あとからプロジェクトルートの .gitignore を調整したパターンです。

CakePHP では、そのディレクトリがデフォルトで空であることを、empty という名前のファイルを置いて、示しています。これは、(おそらく)emtpy ファイルをコミットした後で、プロジェクトルートの .gitignore に「ディレクトリ構成は維持したいけれど、ファイルはバージョン管理したくない」ディレクトリを追加したのかなと思います。

「今現在の .gitignore のルールでは、バージョン管理の対象にならないディレクトリが、なぜ含まれているのだろう?」と疑問に思う人も少なくないでしょう。

結果的に、整合性が保てていない様に見えるので、私はこの方法はやめたほうがいいんじゃないかなと思います。

何にもファイルの変更をしていないのに、キャッシュの再生成をしたら、差分が生まれる例
2017_04_17_15_56_45.png

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.