.gitignoreの書き方|特定のファイルを除外する方法と反映されないとき

Gitでファイルを除外する

Gitに入れたくないファイルを除外したいのに書き方が分からない、.gitignoreに書いたのに除外されない、と困っていませんか。.gitignoreにファイル名やフォルダを書いて除外する方法と、すでにGitが追跡しているファイルをgit rm --cachedで外す手順が分かります。

書いたのに除外されない場合は、先に「.gitignoreが反映されない(除外されない)とき」を見てください。

目次

.gitignoreとは

.gitignoreは、Gitに追跡させたくないファイルを指定するファイルです。1行に1つずつパターン(ファイル名やフォルダ名、ワイルドカード)を書きます。

ただし、.gitignoreが効くのは、まだGitが追跡していないファイルだけです。一度git addやコミットをして、Gitが追跡しているファイルは、あとから.gitignoreに書いても除外されません(Gitの公式ドキュメント「gitignore」)。

.gitignoreを置く場所

ふつうはリポジトリのいちばん上のフォルダ(.gitフォルダがあるフォルダ)に置きます。サブフォルダに置くこともでき、パターンはその.gitignoreがあるフォルダから見た場所として扱われます。

.gitignoreはリポジトリに入れてほかの人と共有するためのファイルです。自分だけが除外したいものは、次の場所に書きます。

  • このリポジトリだけで自分だけ除外したいもの:.git/info/exclude
  • どのリポジトリでも除外したいもの(エディタの一時ファイルなど):core.excludesFileで指定するファイル。指定しない場合は~/.config/git/ignore(環境変数XDG_CONFIG_HOMEがあればその下のgit/ignore)

同じファイルに当たるパターンが何か所かに書かれているときは、コマンドラインで指定したもの、.gitignore、.git/info/exclude、core.excludesFileの順に優先されます。同じファイルの中では、後に書いたパターンが優先されます。

すべてのリポジトリで除外する(グローバルの除外ファイル)

mkdir -p ~/.config/git
echo ".DS_Store" >> ~/.config/git/ignore

core.excludesFileを指定していなければ、~/.config/git/ignoreがすべてのリポジトリで使われます。.DS_Storeは、github/gitignoreのGlobal/macOS.gitignoreにも載っている例です。別のファイルを使いたいときは、core.excludesFileでそのファイルを指定します。

git config --global core.excludesFile ~/.gitignore_global

特定のファイルを除外する書き方

# .gitignore
hoge.txt

スラッシュを付けないと、.gitignoreがあるフォルダの下のどの階層にあるhoge.txtも除外されます。その.gitignoreと同じフォルダにあるhoge.txtだけを除外したいときは、先頭にスラッシュを付けます。

# .gitignore
/hoge.txt

#で始まる行はコメントになり、空の行は何にも当たりません。

フォルダごと除外する書き方

# .gitignore
bar/

最後にスラッシュを付けると、フォルダだけに当たります。bar/はbarフォルダとその中のファイルをすべて除外し、barという名前のファイルは除外しません。

ワイルドカードでまとめて除外する書き方

# .gitignore
# 拡張子が .log のファイルをすべて除外
*.log

# どの階層にある tmp フォルダも除外
**/tmp/

# build フォルダの中をすべて除外
build/**
  • *は、スラッシュ以外の文字なら何にでも当たります。
  • ?は、スラッシュ以外の1文字に当たります。
  • 先頭の**/は、どの階層にあっても当たります。**/tmp/は、tmp/と書いても同じです。
  • 最後の/**は、そのフォルダの中のすべてに当たります。
  • a/**/bは、a/b・a/x/b・a/x/y/bのように、間にフォルダがいくつあっても当たります。

一部のファイルだけ除外しない書き方

# .gitignore
# .log はすべて除外するが、keep.log だけは残す
*.log
!keep.log

先頭に!を付けると、それより前のパターンで除外されたファイルを、もう一度追跡の対象に戻せます。

ただし、親のフォルダごと除外している場合は、その中のファイルを!で戻すことはできません。フォルダの中の一部だけを残したいときは、フォルダではなく中身を除外します。

# .gitignore
# foo フォルダの中は除外するが、foo/bar フォルダだけは残す
/foo/*
!/foo/bar

.gitignoreが反映されない(除外されない)とき

まず考えられるのは、そのファイルがすでにGitに追跡されていることです。.gitignoreは、すでに追跡しているファイルには効きません。追跡をやめるには、git rm --cachedでファイルをインデックス(次のコミットに入れるものの一覧)から外してから、コミットします。

1. 追跡されているか確かめる

git ls-files hoge.txt

ファイル名が表示されたら、そのファイルはGitに追跡されています。

2. git rm –cachedで追跡をやめる(手元のファイルは消えない)

git rm --cached hoge.txt

--cachedを付けると、インデックスからだけ外し、手元のファイルはそのまま残ります。--cachedを付けないと手元のファイルも消えるので、付け忘れに気をつけてください。

フォルダの中をまとめて外すときは-rを付けます。まず-nを付けて試すと、実際には外さずに、外れるファイルの一覧だけを表示します。

git rm -r -n --cached bar/
git rm -r --cached bar/

3. .gitignoreに書いて、コミットする

# .gitignore に足す行
hoge.txt

.gitignoreにこの行を足して保存してから、.gitignoreと追跡をやめたファイルをまとめてコミットします。

git add .gitignore
git commit -m "hoge.txtを追跡しない"

このコミットのあとは、hoge.txtを変えてもgit statusに出てこなくなります。

チームで使っているリポジトリでは、追跡をやめたコミットをpushすると、ほかの人がpullしたときに、その人の手元からそのファイルが消えることがあります。設定ファイルなど手元に必要なファイルなら、pushする前にほかの人に知らせて、控えを取っておいてもらってください。

git rm --cachedは、これからのコミットからファイルを外すだけです。それより前のコミットには、ファイルが残っています。.envなどにパスワードやAPIキーを書いてコミットしていた場合は、そのキーやパスワードを無効にして、作り直してください。GitHub Docsの「リポジトリからの機微なデータの削除」でも、まずシークレットを失効させるか作り直すように書かれています。

除外されているか確かめる

git check-ignore -v hoge.txt

除外されているときは、当たったパターンと、そのパターンが書かれたファイル・行番号が表示されます。何も表示されないときは、そのファイルは除外されていません。

!で始まるパターンに当たったときも、そのパターンが表示されます。そのときは、そのファイルは除外されていない、という意味です。

すでに追跡しているファイルは、git check-ignoreの結果には出ません。何も出ないときは、上の「追跡されているか確かめる」も試してください。

除外されているファイルをまとめて見たいときは、git statusに--ignoredを付けます。

git status --ignored

よく使う.gitignoreの例

# 環境ごとの設定・秘密の情報
.env

# 依存パッケージ
node_modules/

# ビルドの成果物
dist/
build/

# ログ
*.log

どれも、GitHubが公開している.gitignoreのテンプレート集「github/gitignore」(Node.gitignore・Python.gitignore)に載っている書き方です。どれを除外するかは、使っている言語やツールによって変わります。チームで使うリポジトリでは、何を除外するかをほかの人とそろえてください。

参考

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

社内エンジニアとして、SREとセキュリティの仕事をしています。サーバーの構築や運用、クラウド環境の設計にも関わってきました。趣味はゲームと漫画・アニメ。

コメント

コメントする

目次