【メモ】.gitignore活用術:ディレクトリ構造を保持しながらファイルを除外する

GitHubを使用していて、こんなことは無いでしょうか。

プロジェクト内にディレクトリがあり、その中には解析対象の大きなファイル(mp3mp4など)があるので、gitの管理対象外にしたい。

Whisperを使用していて、音声解析のもとになるmp3ファイルディレクトリに保管しているので、そのような場合になります。このような場合には.gitignoreを使用することになるのでそのまま書けばいいのですが、cloneした際にこのようなディレクトリ構成は再現されません。(空のディレクトリはそもそも対象にならない仕様のようです)

こんなときにはセットアップするためのshファイルを書いていたのですが、その方法は果たして正しいのか?という疑問を持ったので、このメモを作成しました。この方法のほうが少し楽かなというレベルです。

行いたいこと

プログラムのあるカレントディレクトリにAudioというサブディレクトリがあり、その中にはmp3が配置されている。 mp3ファイルGitの管理対象外にしたいが、ディレクトリ構成はそのままにしたい。

.gitignoreの設定と挙動

.gitignoreファイルを編集することで、管理対象外にするファイルや拡張子、ディレクトリの設定は簡単にできます。

以下のように追記すれば、Audioディレクト内および、Audioディレクトリのサブディレクトに含まれるmp3ファイルすべてが管理対象外になります。

特定の拡張子のみを除外する場合

Audio/*.mp3           # Audioディレクトリ直下のmp3ファイルのみ除外
Audio/**/*.mp3        # サブディレクトリを含むすべてのmp3ファイルを除外

もちろん以下のようにすれば、すべての種類のファイルを対象外にすることができます。

ディレクトリ内のすべてのファイルを除外

Audio/**/*           # Audioディレクトリ内のすべてのファイルを除外(サブディレクトリ含む)

この設定を行って除外を行った場合、Audioディレクトリが空になるとClone時にAudioディレクトリは作成されない状態になります。

Gitの空ディレクトリの取り扱い

解決策

基本的にはディレクトリの内部が空にならないようにするというのがポイントになってきます。以下の様な手法があります。どちらもファイル名が異なるだけで管理対象のファイルを作成する方法です。

  • .gitkeepを使用する
  • README.mdを使用する

.gitkeepを使用する場合

構成を保持したいディレクトリに.gitkeepを作成し、.gitignoreに以下を追記します。

.gitkeepを作成する例

$ touch Audio/.gitkeep

ディレクトリ内のファイルは管理対象外ですが、例外に.gitkeepを設定することで、Audio/.gitkeepが管理対象となり、 空のディレクトリではなくなるので、Clone時にディレクトリ構成が保持されます。

.gitignoreへの追記

Audio/**/*
!Audio/.gitkeep

ディレクトリの構成の説明が不要であれば、この方法でよいと思います。

README.mdを使用する場合

構成を保持したいディレクトリにREADME.mdを作成し、.gitignoreに以下を追記します。README.mdファイルを作成したら編集してディレクトリの説明を記述しておきましょう。

README.mdを作成する例

$ touch Audio/README.md

ディレクトリ内のファイルは管理対象外ですが、例外にREADME.mdを設定することで、Audio/README.mdが管理対象となり、空のディレクトリではなくなるので、Clone時にディレクトリ構成が保持されます。

.gitignoreへの追記

Audio/**/*
!Audio/README.md

ディレクトリの構成の説明があったほうがいい場合には、この方法でよいと思います。 個人的にはこちらの方法を取っています。

おわりに

ディレクトリ構造を維持しながら、特定のファイルのみをバージョン管理の管理対象外にできるようになりました。

この方法の利点としては

  • 大容量ファイルを除外しつつ、ディレクトリ構造を維持できる
  • クローン時に手動でディレクトリを作成する必要がない
  • README.mdを使えばディレクトリの用途も説明できる

音声ファイルや動画ファイルを扱うプロジェクトでは特に有用な方法ですし、セットアップ用のスクリプトを作成する代わりにもなりそうです。

/* -----codeの行番号----- */