.gitignore
既存のリポジトリをいくつか見て回っていると、よく .gitignore という名前のテキストファイルを目にします。簡単にいうと、これはリポジトリに載せないファイルの名簿です。
.gitignore のはたらき
.gitignore が持つ効果については実例を見た方が分かりやすいかも知れません。まず、リポジトリに .gitignore という名前(最初にピリオドをつける)の空のテキストファイルを作成し、そこに "secret.md" とだけ書いて変更をコミットしてしまいましょう。
さらに secret.md という名前の空のテキストファイルを作成して編集します。
すると、変更を保存していつまで待っても『ステージされている変更』に secret.md の表示が出ず、コミットができなくなりました。エクスプローラータブでファイルの一覧を見直してみると、どうも secret.md だけファイル名の表示が暗くなっています。
これは先ほど作った .gitignore の効力です。リポジトリに .gitignore というファイルが含まれていると、Git はそこに名前が書かれたファイルをすべてコミットから除外します。"secret.md" と書かれたファイル .gitignore をリポジトリに追加したことで、secret.md は作業ディレクトリの中に存在するにも拘らずリポジトリには含まれなくなったのです。
ちなみに、.gitignore はただファイル名を列挙するだけでなく、ディレクトリ名を書いてそこに含まれるファイルを丸ごと除外したり、同じ種類の(たとえば共通の拡張子を持つ)ファイルをいっぺんに除外したりすることもできます。
.gitignore の使い道
一般に、リポジトリには必要最小限のファイルを載せるべきとされています。リポジトリそのものにキツい容量制限があるわけではないですが、明らかに必要なファイルだけが入ったリポジトリの方が整然としていて見通しがよくて開発がスムーズに進む、といえばなんとなく納得できるかと思います。.gitignore は「作業ディレクトリに存在するがリポジトリには載せたくないファイル」を除去するために重宝されています。
共同開発で .gitignore がどう活用されているかについては実例を見た方が早いかも知れません。GitHub 上の traQ フロントエンドリポジトリのルートに置かれている .gitignore を見てみましょう。以下はその最初の数行です。
.DS_Store
node_modules
/dist
# local env files
.env.local
#
から始まる行はコメントなので無視してください。そのほかの 4 行は .gitignore をそれぞれ異なる方法で用いています。実は、.gitignore の代表的な使い方はここにあるもので凡そ網羅されています。それぞれ見ていきましょう。
.DS_Store の除外
.DS_Store とは、Mac 内の任意の場所に新規作成したディレクトリ内での操作に関する情報を保存するためにその中に自動で生成されるファイルです。Finder 上では完全に隠蔽されていて、Shift
+ Command
+ .
によって隠しファイル表示モードにしても表示されません。
ところが .DS_Store が隠蔽されるのは Mac の Finder だけです。リポジトリに含まれれば Gitea や GitHub 上でも普通に表示されるし、Windows にクローンしても顕についてきます。開発に必要なファイルではないのでリポジトリからは除外しておきたいところです。
というわけで .gitignore に .DS_Store と書かれています。第 1 行がこのファイルであることからも、.DS_Store がよく .gitignore に書かれるお邪魔ファイルの筆頭であることが伺えます。
モジュールの除外
ここからは Web 開発の多少込み入った話になります。2 行目の node_modules は Node.js を用いた開発において パッケージがインポートされるディレクトリ です。
Web 分野に限らず、開発とは必ずしも全てを独力でなんとかする類のものではなく、先人が作ったプログラムのまとまり「パッケージ」をお借りしてシステムに組み込みながら進めていくことが一般的です。そのために Web 上からパッケージをインポートして管理するパッケージマネージャと呼ばれるソフトウェアがプログラミング言語ごとに存在します。ちなみに、パッケージマネージャは Git 同様に代表的な CLI ソフトウェアの一種です。
パッケージマネージャの基本的な役割は「依存関係リストファイルに記されたパッケージをインポートする」ことです。依存関係リストファイルとは必要なパッケージを決まった形式の箇条書きで記したテキストファイルのことです。
Node.js を用いた開発では npm(Node Package Manager)というパッケージマネージャが存在して、以下のようにコマンドを打てば「package.json に記されたパッケージをダウンロードして node_modules ディレクトリに追加」してくれます。
npm install # Node パッケージのインストール
つまり、npm とリポジトリの中の package.json さえあれば各環境で必要なパッケージをインポートして揃えることができます。とすれば、その保存先である node_modules ディレクトリは必ずしもリポジトリに含める必要はないということになります。
外部モジュールのとても雑な例え話
リュック 1 つと青春 18 きっぷで東海道線沿線を旅したくなったとします。貴重品など代えが利かないものは持参する必要がありますが、当然リュックは軽い方が嬉しいので、歯ブラシやシャンプー、タオル、食べ物など現地調達可能なものはなるべく現地調達することにして、必要なものと一緒に調達したいもののメモだけをリュックに入れておくことにします。
- リュック -> リポジトリ
- 貴重品 -> オリジナルのソースコード
- 現地調達可能なもの -> 外部パッケージ
- 現地 -> システムが動く環境
- 現地調達するもののメモ -> 依存関係リストファイル
対応させるならこんな感じでしょうか。外部パッケージは システムが動く環境で / パッケージマネージャが / 依存関係リストファイルをもとに調達してくれる ものなので リポジトリに含める必要がない という要点をおさえるために旅にたとえてみました。また行きたい。
というわけで .gitignore に node_modules と書かれています。node_modules はディレクトリ名なので、ここに含まれるパッケージを一薙ぎに除外してしまおうという寸法です。
生成物の除外
3 行目の dist とは ビルド成果物を保存するディレクトリ です。リポジトリ の章で「Web フロントエンドは HTML + CSS + JavaScript で出来ている」ことに軽く触れましたが、ビルドされた HTML + CSS + JavaScript のシステムが収められる場所がこの dist です。ビルドという作業については Web エンジニアになろう講習会 で実践できるでしょう。
同一のリポジトリを異なる場所にクローンしても、それぞれでビルドすれば同じものが出来上がります。各環境でビルドすればよいので、ビルドの結果はリポジトリに含めておく必要がありません。このほかにも、リポジトリから復元可能なデータや一時的にしか使わないデータの形式や保存場所は .gitignore に追加してリポジトリに含めないことが一般的です。
環境変数設定ファイルの除外
6 行目の .env.local は 環境変数を書いておくファイル です。
開発したシステムをずっと動かしておきたい場合、自分の PC で動かしておくわけにもいかないので、NeoShowcase などの外部の環境に デプロイ(移設)することになります。システムに対し環境ごとに異なる値を与えたい場合、それらは 環境変数 として与えます。NeoShowcase にも登録したアプリケーションそれぞれに環境変数を設定できる UI が存在します。
開発中のシステムが参照する環境変数は作業ディレクトリの内部に .env のような分かりやすい名前がついたファイルを用意して書いておくと便利なことが多いです。その上で、本番環境に予め設定してある環境変数と競合を生じないよう、.gitignore に .env を加えてリポジトリからは除外しておく運用が一般的です。
ちなみに、紛らわしくも運用によっては .env が『環境に依存しない定数』を書く場所として用いられリポジトリに含まれることがあるので、本来の .env の役割である『環境依存』というニュアンスを強めて .env.local という名前が用いられることもよくあるみたいです。
.gitignore のテンプレート
リポジトリの作成時に Gitea 側で .gitignore のテンプレートを含めるよう設定することもできます。作りたいシステムで使用する言語・フレームワークごとに豊富なテンプレートが用意されています。
環境変数と機密情報の秘匿
traP Gitea 上のリポジトリは部員に対してのみ公開されますが、GitHub などのホスティングサービスを使う場合は Web 上に公開された Git リポジトリで開発を進めていくことも珍しくありません。それどころか、GitHub の無料会員は数年前までプライベートリポジトリを作ることが出来ませんでした。
実行中のシステムが必要とする情報のうち、API トークン(パスワード)など外部に悪用されないように秘匿しておきたい文字列もよく環境変数として扱われます。実際に環境に依存するか否かはさておき、.gitignore の恩恵でリポジトリに含まれなくなった .env はこうした機密情報を置いておくにはうってつけの場所です。
ただし、一度コミットされたファイルをあとで .gitignore に追加してもリポジトリからは除外されない ことに注意が必要です。たとえば、
- 空の secret.md を作業ディレクトリに追加してコミット
- secret.md と書いた .gitignore を追加してコミット
- secret.md に秘密にしたい情報を書き込む
この場合、secret.md は手順 1 によってすでにリポジトリに含まれているので、3 で行った変更もコミット可能になっています。一旦「secret.md の削除」という変更をコミットして初めて .gitignore の記述が効力を発するようになります。
リポジトリには基本的に全てのコミットの履歴が残ります。それ以前に、一度インターネットに流出した情報を完全に消すのは非常に難しいことです。.gitignore のはたらきをよく理解した上で、公開リポジトリへのコミットはぜひ慎重にお願いします。まずはプライベートリポジトリで色々な操作に慣れておくとよいでしょう。