Git
372
どのような問題がありますか?

投稿日

更新日

Organization

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

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

空のディレクトリを保持する目的で使用する .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 という名前のファイルを置いて、示していました。これは、(おそらく)empty ファイルをコミットした後で、プロジェクトルートの .gitignore に「ディレクトリ構成は維持したいけれど、ファイルはバージョン管理したくない」ディレクトリを追加したのかなと思います。

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

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

こちらの Pull Request で .gitkeep を使う手法に変更されました!

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

ユーザー登録して、Qiitaをもっと便利に使ってみませんか。
  1. あなたにマッチした記事をお届けします
    ユーザーやタグをフォローすることで、あなたが興味を持つ技術分野の情報をまとめてキャッチアップできます
  2. 便利な情報をあとで効率的に読み返せます
    気に入った記事を「ストック」することで、あとからすぐに検索できます
ユーザー登録ログイン
ndxbn
サーバサイドをやってるひと。
dwango
Inspiring people, connecting humanity with technology.
この記事は以下の記事からリンクされています

コメント

cakephpの話のところで、ファイル名がemptyなのか.gitkeepなのかの違いが重要で、おそらく後者はgitそのものの機能なのだろうと誤読してしまいました。

どっちも、ただのファイルと慣習にすぎなく、
cakePHPがやらかしたことは、「コミット済のものを消さずにgitignoreに含めたこと」であってファイル名がemptyなのか.gitkeepなのかは関係ないと理解したのですが、あっていますでしょうか。

1

@hikaruna

どっちも、ただのファイルと慣習にすぎなく、
cakePHPがやらかしたことは、「コミット済のものを消さずにgitignoreに含めたこと」であってファイル名がemptyなのか.gitkeepなのかは関係ないと理解したのですが、あっていますでしょうか。

あってると思います

1
どのような問題がありますか?
あなたもコメントしてみませんか :)
ユーザー登録
すでにアカウントを持っている方はログイン
372
どのような問題がありますか?
ユーザー登録して、Qiitaをもっと便利に使ってみませんか

この機能を利用するにはログインする必要があります。ログインするとさらに下記の機能が使えます。

  1. ユーザーやタグのフォロー機能であなたにマッチした記事をお届け
  2. ストック機能で便利な情報を後から効率的に読み返せる
ユーザー登録ログイン
ストックするカテゴリー