[Git] 空ディレクトリをチェックインする
アプリケーションのログを出力するディレクトリのように、「中身が空っぽのディレクトリをGitの管理に含めたい。ただし、そのディレクトリの中にファイルが生成されても、そのファイルはGitの管理に含めたくない。」という場合のやり方です。
ググると、割と不正確な情報がたくさん引っかかるので...
方法
以下、プロジェクトトップ階層の、logsという名前のディレクトリを例に使います。
-
logsディレクトリ配下に、ダミーファイル「.gitkeep」もしくは「.keep」を作成します。ファイルの中身は無くてよいです。
$ mkdir logs/ $ touch logs/.gitkeep
ダミーファイルの名前について
ダミーファイルの名前は、Gitの決まりごというわけではなく、実際には何でもよいです。後述の.gitignoreファイルで適切に設定すれば、問題ありません。
ただし、慣習としては、ドット付きで隠しファイル扱いにした「.gitkeep」や「.keep」というファイル名がよく使われます。
特別な理由がない限り、これらの名前を使ったほうが、わかりやすくてよいでしょう。 -
.gitignoreに、以下のように記載します(ダミーファイル名として「.gitkeep」を採用した場合):
.gitignore# Keep empty logs/ directory. /logs/* !/logs/.gitkeep
設定の意味とポイントは、次のとおりです:
-
/logs/*
:トップ階層のlogsディレクトリの中身をすべて、一旦ignoreする
(結果的に、logsディレクトリも、Gitにチェックインしないことになる(仕組みと考え方参照))-
ディレクトリ名の先頭に
/
をつける- 無いと、「階層問わず、とにかく名前がlogsのディレクトリをignore」になってしまう
-
/logs/のあとにワイルドカード
*
をつける- 無いと、「logsディレクトリをignore」になってしまう[1]
If there is a separator at the end of the pattern then the pattern will only match directories, otherwise the pattern can match both files and directories.
- ignoreしたいのは「logsディレクトリ配下のファイルなんでも」
- 無いと、「logsディレクトリをignore」になってしまう[1]
-
-
!/logs/.gitkeep
:ファイル「logs/.gitkeep」のみチェックインを許可-
/logs/*
の行の直後に書く- .gitignoreファイルの末尾に
.gitkeep
と書く(「階層問わずどこかの.gitkeepを許可」の意味)よりも、近くに・効果の範囲を限定的に書いたほうが、何をしたいのかわかりやすい
- .gitignoreファイルの末尾に
-
-
仕組みと考え方
Gitはファイルのみを管理します。ディレクトリ単体のチェックインはできません。
ディレクトリについては、コミットされたファイルのパスを再現する際に、途中のディレクトリが無ければ、作られる...というようなイメージになります(典型的にはgit clone
時など)。
そこで、空ディレクトリlogsのみをGit管理したい場合は、
- 仕方なくダミーのファイルを使って、「logsディレクトリがパスにあるファイル」を含めたコミットを作る
- ただし、logsディレクトリ配下の他のファイルはGitの管理に入らないようにする
というようにします。これで(ダミーのファイル以外は)空のlogsディレクトリが得られることになります。
Discussion