.gitignoreとは、Gitに「このファイルは追跡しなくてよい」と伝えるためのパターンを1行に1つずつ書くテキストファイルです。 書き方の要点は「スラッシュの位置で範囲が決まる」「下の行ほど優先される」「すでに追跡しているファイルには効かない」の3つに集約できます。

この記事では、記号ごとの書き方を「マッチするパス/しないパス」の早見表にまとめ、Git 2.43.0 で git check-ignore -v と git status を実際に動かした出力で裏づけます。「ディレクトリごと無視した中の1ファイルだけ残したい」「書いたのに効かない」という場面の直し方、言語別のコピペ用テンプレートまで1ページで確認できます。

.gitignoreのパターン早見表

下の表は、すべて手元のリポジトリで git check-ignore -v を実行して確かめた結果です(Git 2.43.0)。

書き方 意味 マッチする(無視される) マッチしない
debug.log スラッシュなし=どの階層でも debug.log、src/debug.log debug.txt
/debug.log 先頭スラッシュ=.gitignoreと同じ階層だけ debug.log src/debug.log
build/ 末尾スラッシュ=ディレクトリだけ(どの階層でも) build/out.js、docs/build/index.html build という名前のファイル
/build/ 直下のディレクトリだけ build/out.js docs/build/index.html
docs/build 途中にスラッシュ=.gitignoreからの相対パス docs/build/index.html build/out.js
*.log * はスラッシュ以外の0文字以上 debug.log、logs/app.log、src/logs/x.log debug.log.txt
logs/*.log 途中にスラッシュがあるので直下の logs だけ logs/app.log src/logs/x.log
**/logs 先頭の **/ はすべての階層 logs/app.log、src/logs/x.log src/logs.txt
src/**/*.tmp /**/ は0個以上のディレクトリ src/a/x.tmp、src/a/b/c/deep.tmp root.tmp
src/*.tmp * は階層をまたがない src/x.tmp src/a/x.tmp
src/** 末尾の /** は中身すべて src/main.js、src/a/main.js main.js
file?.txt ? はスラッシュ以外の1文字 file1.txt、fileA.txt file10.txt
file[0-9].txt [] は範囲内の1文字 file1.txt fileA.txt、file10.txt
file[!0-9].txt [!...] は範囲外の1文字 fileA.txt file1.txt
!important.log ! は無視の取り消し(上の行より後に書く) (important.log が追跡対象に戻る) 親ディレクトリごと無視されている場合は戻らない
\#memo.txt 行頭の # はコメント。文字として使うときは \ を付ける #memo.txt —
\!keep.txt 行頭の ! を文字として使うとき !keep.txt —

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「.gitignoreの書き方一覧 パターン早見表と効かないときの確認手順」

まず押さえる3つのルール

表の内容は、次の3つのルールから導けます。 丸暗記しなくても、この3つを覚えておけば自分でパターンを組み立てられます。

ルール 内容 例
1. スラッシュの位置で範囲が決まる 先頭か途中にスラッシュがあれば「.gitignoreのある場所からの相対パス」。スラッシュがなければ(末尾だけなら)「どの階層でも」 /TODO は直下だけ、TODO は docs/TODO も対象
2. 下の行ほど優先される 同じファイルに複数の行がマッチしたら、最後にマッチした行で決まる *.log の後に !important.log
3. 追跡済みのファイルには効かない .gitignore は「まだ追跡していないファイルを追跡しないままにする」ためのもの git rm --cached で追跡を外す

Git の公式ドキュメント(gitignore のページ)でも、パターンの形式として同じ内容が説明されています。今回このページを開いて、先頭・途中のスラッシュの扱い、** の3つの使い方、! の制約を確認しました。

確認に使うコマンドは2つ

パターンが思ったとおりに効いているかは、git check-ignore -v と git status で確かめられます。

# どのファイルの何行目のパターンで無視されているかを表示
git check-ignore -v <パス>

# 無視されているファイルも含めて一覧
git status --short --ignored

git check-ignore -v の出力は「ファイル名:行番号:パターン(タブ)調べたパス」の形です。

$ git check-ignore -v debug.log logs/app.log src/logs/x.log
.gitignore:1:*.log  debug.log
.gitignore:1:*.log  logs/app.log
.gitignore:1:*.log  src/logs/x.log

どのパターンにもマッチしないパスは何も表示されず、終了コードが 1 になります。

記号ごとの書き方と実行結果

ここからは、次のファイル構成で試した結果を記号ごとに見ていきます。

.
├── debug.log
├── root.tmp
├── TODO
├── file1.txt / file2.txt / file10.txt / fileA.txt
├── build/out.js
├── docs/build/index.html
├── docs/TODO
├── logs/app.log
└── src/
    ├── debug.log
    ├── main.js
    ├── logs/x.log
    └── a/
        ├── main.js
        ├── x.tmp
        └── b/c/deep.tmp

先頭のスラッシュ:直下だけに絞る

先頭にスラッシュを付けると、.gitignore と同じ階層のものだけが対象になります。

# .gitignore の中身: /debug.log
$ git check-ignore -v debug.log src/debug.log
.gitignore:1:/debug.log debug.log

# .gitignore の中身: debug.log
$ git check-ignore -v debug.log src/debug.log
.gitignore:1:debug.log  debug.log
.gitignore:1:debug.log  src/debug.log

スラッシュなしの debug.log は src/debug.log にもマッチしました。「直下の TODO だけ無視して、docs/TODO は残したい」ときは /TODO と書きます。

末尾のスラッシュ:ディレクトリだけを対象にする

末尾にスラッシュを付けると、ディレクトリだけにマッチします。 末尾のスラッシュは「範囲を絞るスラッシュ」には数えないので、build/ はどの階層の build ディレクトリにも効きます。

# .gitignore の中身: build/
$ git check-ignore -v build/out.js docs/build/index.html
.gitignore:1:build/ build/out.js
.gitignore:1:build/ docs/build/index.html

# .gitignore の中身: /build/
$ git check-ignore -v build/out.js docs/build/index.html
.gitignore:1:/build/    build/out.js
書き方 直下の build ディレクトリ docs/build ディレクトリ build という名前のファイル
build 無視 無視 無視
build/ 無視 無視 対象外
/build/ 無視 対象外 対象外
docs/build 対象外 無視 対象外

ビルド成果物のように「リポジトリ直下の1か所」と決まっているものは /build/ と書くと、ソースの中にある同名フォルダ(src/tools/build/ など)を巻き込まずに済みます。

アスタリスク1つ:スラッシュ以外の0文字以上

アスタリスク1つは「スラッシュを含まない任意の文字列」です。 階層はまたぎません。

# .gitignore の中身: logs/*.log
$ git check-ignore -v logs/app.log src/logs/x.log
.gitignore:1:logs/*.log logs/app.log

# .gitignore の中身: src/*.tmp
$ git check-ignore -v src/a/b/c/deep.tmp src/a/x.tmp
(何も表示されない。終了コード 1)

logs/*.log は途中にスラッシュがあるので、ルール1により直下の logs/ だけが対象です。src/logs/x.log にはマッチしませんでした。src/*.tmp も src/a/x.tmp には届きません。

アスタリスク2つ:階層をまたぐ

二重アスタリスクは、スラッシュと組み合わせたときだけ「階層をまたぐ」特別な意味を持ちます。 使い方は3通りです。

書き方 意味 例
**/名前 すべての階層の「名前」 **/logs → logs/、src/logs/
名前/** 「名前」の中身すべて(深さは問わない) src/** → src/main.js、src/a/main.js
a/**/b a と b の間に0個以上のディレクトリ src/**/main.js → src/main.js、src/a/main.js
# .gitignore の中身: **/logs/*.log
$ git check-ignore -v logs/app.log src/logs/x.log
.gitignore:1:**/logs/*.log  logs/app.log
.gitignore:1:**/logs/*.log  src/logs/x.log

# .gitignore の中身: src/**/*.tmp
$ git check-ignore -v src/a/b/c/deep.tmp src/a/x.tmp root.tmp
.gitignore:1:src/**/*.tmp   src/a/b/c/deep.tmp
.gitignore:1:src/**/*.tmp   src/a/x.tmp

# .gitignore の中身: src/**/main.js
$ git check-ignore -v src/main.js src/a/main.js
.gitignore:1:src/**/main.js src/main.js
.gitignore:1:src/**/main.js src/a/main.js

src/**/main.js が src/main.js(間のディレクトリが0個)にもマッチしている点がポイントです。なお、**/logs は logs と同じ結果になります。先頭の **/ が役立つのは、**/logs/*.log のように途中にスラッシュがあるパターンを全階層に広げたいときです。

疑問符と角かっこ:1文字だけを指定する

# .gitignore の中身: file?.txt
$ git check-ignore -v file1.txt file2.txt file10.txt fileA.txt
.gitignore:1:file?.txt  file1.txt
.gitignore:1:file?.txt  file2.txt
.gitignore:1:file?.txt  fileA.txt

# .gitignore の中身: file[0-9].txt
$ git check-ignore -v file1.txt file10.txt fileA.txt
.gitignore:1:file[0-9].txt  file1.txt

# .gitignore の中身: file[!0-9].txt
$ git check-ignore -v file1.txt fileA.txt
.gitignore:1:file[!0-9].txt fileA.txt

疑問符は「ちょうど1文字」なので、file10.txt にはマッチしません。 角かっこは *.py[cod](.pyc・.pyo・.pyd をまとめて指定)や [Ll]ibrary/(大文字・小文字の両方)のように、テンプレートでよく使われます。

コメントとエスケープ

書きたいもの 書き方
コメント 行頭に #
# で始まるファイル名 \#memo.txt
! で始まるファイル名 \!keep.txt
末尾に空白があるファイル名 空白の前に \
区切りの空行 そのまま空行(何にもマッチしない)
# .gitignore の中身: #memo.txt   ← コメント扱いになる
$ git check-ignore -v '#memo.txt'
(何も表示されない。終了コード 1)

# .gitignore の中身: \#memo.txt
$ git check-ignore -v '#memo.txt'
.gitignore:1:\#memo.txt #memo.txt

行末の空白は取り除かれてから解釈されます。secret.txt のように末尾へ空白が入っていても、手元では secret.txt として効きました。また、コメントは行頭にだけ書けます。*.log # ログ のように行の途中へ書くと、全体が1つのパターンとして扱われます。

感嘆符で「これだけは残す」を書く

感嘆符で始まる行は「無視を取り消す」という意味です。 上の行で無視したものの一部を、追跡対象に戻せます。

*.log
!important.log
$ git check-ignore -v debug.log important.log
.gitignore:1:*.log  debug.log
.gitignore:2:!important.log important.log

$ git status --short
?? .gitignore
?? important.log

git status に important.log が出ているので、追跡対象に戻っています。ここで1つ覚えておきたいのが、git check-ignore -v は「最後にマッチした行」を表示するので、取り消しの行にマッチした場合も出力があるという点です。表示されたパターンの先頭が ! なら「無視されていない」と読みます。

順番を入れ替えると結果が変わる

!important.log
*.log
$ git check-ignore -v important.log
.gitignore:2:*.log  important.log

取り消しを先に書くと、後の *.log が勝って無視されます。「広く無視 → 一部を戻す」の順で書くのが基本形です。

ディレクトリ内の1ファイルだけ残す書き方

よくあるのが「data/ の中身は無視したいが、空のディレクトリを保つための .gitkeep だけは残したい」という場面です。

うまくいかない例(ディレクトリごと無視している)

data/
!data/.gitkeep
$ git check-ignore -v data/.gitkeep data/a.csv
.gitignore:1:data/  data/.gitkeep
.gitignore:1:data/  data/a.csv

$ git status --short -uall
?? .gitignore

.gitkeep も 1 行目の data/ で無視されたままです。公式ドキュメントにも「親ディレクトリが除外されている場合、その中のファイルを再び含めることはできない」と書かれています。Git は無視したディレクトリの中身を一覧しないため、中のファイルに対するパターンが評価されないのです。

正しい書き方(中身を無視して、1つだけ戻す)

data/*
!data/.gitkeep
$ git check-ignore -v data/.gitkeep data/a.csv
.gitignore:2:!data/.gitkeep data/.gitkeep
.gitignore:1:data/* data/a.csv

$ git status --short -uall
?? .gitignore
?? data/.gitkeep

data/(ディレクトリそのもの)ではなく data/*(ディレクトリの中身)を無視するのがポイントです。ディレクトリ自体は無視されていないので、Git が中を見て 2 行目の取り消しを評価できます。

書き方 無視の対象 中のファイルを ! で戻せるか
data/ ディレクトリそのもの 戻せない
data/* ディレクトリ直下の各ファイル・各サブディレクトリ 戻せる
data/** ディレクトリの中身すべて(深さを問わない) 途中のディレクトリを先に戻せば戻せる

深い階層の1ファイルだけ残す

残したいファイルが data/sub/deep/keep.txt のように深い場所にあるときは、途中のディレクトリを1段ずつ「戻す → 中身を無視」と繰り返します。

うまくいかない例

data/*
!data/sub/deep/keep.txt

data/* によって data/sub ディレクトリが無視されるので、その中の keep.txt は戻りません(手元の git status には何も出ませんでした)。

正しい書き方

data/*
!data/sub/
data/sub/*
!data/sub/deep/
data/sub/deep/*
!data/sub/deep/keep.txt
$ git status --short -uall | grep data
?? data/sub/deep/keep.txt

$ git check-ignore -v data/sub/deep/keep.txt data/sub/deep/z.txt data/sub/other.txt
.gitignore:6:!data/sub/deep/keep.txt    data/sub/deep/keep.txt
.gitignore:5:data/sub/deep/*    data/sub/deep/z.txt
.gitignore:3:data/sub/* data/sub/other.txt

行数は増えますが、「戻す・無視する」を交互に書くと覚えておけば迷いません。階層が深くなる場合は、次の節のようにそのディレクトリの中に .gitignore を置くほうが短く書けます。

サブディレクトリに.gitignoreを置く

.gitignore はリポジトリのどの階層にも置けます。パターンは、その .gitignore がある場所を基準に解釈され、下の階層のファイルほど優先されます。

# sub/.gitignore
cache/
!*.log
$ git check-ignore -v sub/cache/a.bin sub/keep.log
sub/.gitignore:1:cache/ sub/cache/a.bin
sub/.gitignore:2:!*.log sub/keep.log

リポジトリ直下の .gitignore で *.log を無視していても、sub/ の中だけは .log を追跡する、という指定ができました。「ある階層だけルールを変えたい」ときに便利です。

.gitignoreが効かないときの確認手順

効かないときは、次の順に確かめると原因にたどり着けます。

flowchart TD
    A[.gitignoreに書いたのに git status に出る] --> B{git ls-files でそのパスが出る?}
    B -- 出る --> C[追跡済み → git rm --cached で追跡を外す]
    B -- 出ない --> D{git check-ignore -v で行が出る?}
    D -- 出ない --> E[パターンが合っていない → スラッシュ位置・文字コードを確認]
    D -- 先頭が感嘆符の行が出る --> F[後ろの行で取り消されている → 順番を見直す]
    D -- 出る --> G[無視されている → git status --ignored で確認]
症状 確認コマンド 原因 直し方
変更が M で出続ける git ls-files -ci --exclude-standard すでに追跡している git rm --cached <パス>
! で戻したのに出てこない git check-ignore -v <パス> 親ディレクトリごと無視している dir/ を dir/* に書き換える
直下以外も無視されてしまう git check-ignore -v <パス> スラッシュなしのパターン 先頭にスラッシュを付ける
サブディレクトリに効かない git check-ignore -v <パス> 途中にスラッシュがある **/ を先頭に付ける
どの行にもマッチしない file .gitignore ファイルが UTF-16 で保存されている UTF-8 で保存し直す
一部の人だけ効かない git config core.excludesFile グローバル設定に頼っている リポジトリの .gitignore に書く

追跡済みのファイルはgit rm --cachedで外す

いちばん多いのがこのケースです。.env をコミットした後で .gitignore に追加しても、変更は検出され続けます。

$ echo '.env' > .gitignore
$ echo 'KEY=2' >> .env
$ git status --short
 M .env
?? .gitignore

$ git check-ignore -v .env
(何も表示されない。終了コード 1)

git check-ignore は、追跡済みのファイルについては何も表示しません。 パターン自体が合っているかを確かめたいときは --no-index を付けます。

$ git check-ignore -v --no-index .env
.gitignore:1:.env   .env

パターンは合っているので、原因は「追跡済み」だとわかります。追跡済みなのに無視パターンにもマッチしているファイルは、次のコマンドで一覧できます。

$ git ls-files -ci --exclude-standard
.env

追跡を外すには git rm --cached を使います。--cached を付けると、作業ツリーのファイルは残したまま、Git の管理(インデックス)からだけ外せます。

$ git rm --cached .env
rm '.env'

$ git status --short
D  .env
?? .gitignore

$ ls -a
.  ..  .env  .git  .gitignore  app.js

.env は手元に残っています。このあと .gitignore と一緒にコミットすれば完了です。

git add .gitignore
git commit -m "stop tracking .env"

コミット後は git status に何も出なくなり、git check-ignore -v .env でも .gitignore:1:.env と表示されるようになりました。

コマンド 作業ツリーのファイル Git の追跡
git rm --cached <パス> 残る 外れる
git rm <パス> 削除される 外れる
git rm -r --cached <ディレクトリ> 残る ディレクトリごと外れる

知っておきたい点が2つあります。

  • 過去のコミットには内容が残ります。 パスワードや API キーを含むファイルだった場合は、追跡を外すだけでなく、その値を新しいものに入れ替えておくと安心です。
  • ほかの人が pull すると、その人の作業ツリーからはファイルが削除されます。 設定ファイルの場合は、ひな形(.env.example など)を用意して共有しておくと、作り直しがスムーズです。

まとめて追跡を外す

node_modules/ や大量のログをコミットしてしまった場合は、一度すべてをインデックスから外して追加し直すと、.gitignore の内容がまとめて反映されます。

$ git ls-files -ci --exclude-standard
node_modules/x/i.js
old.log

$ git rm -r --cached -q .
$ git add .
$ git status --short
M  .gitignore
D  node_modules/x/i.js
D  old.log

実行前に、未コミットの変更がないことを git status で確かめておくと、差分が読みやすくなります。

文字コードと改行コードを確認する

Windows の PowerShell 5.1 で echo "secret.txt" > .gitignore のように作ると、ファイルが UTF-16 で保存されることがあります。UTF-16 の .gitignore を用意して試したところ、パターンは効きませんでした。

$ file .gitignore
.gitignore: Unicode text, UTF-16, little-endian text, with CRLF line terminators

$ git check-ignore -v secret.txt
(何も表示されない。終了コード 1)

エディタで「UTF-8」を選んで保存し直すと解決します。なお、改行コードが CRLF の UTF-8 ファイルは、手元の Git 2.43.0 ではそのまま効きました(PowerShell 上での作成そのものは未実行で、UTF-16 のファイルを Linux 上で再現して確認しています)。

無視しているファイルを追加したいとき

無視対象のファイルを git add すると、Git がメッセージで知らせてくれます。

$ git add x.log
The following paths are ignored by one of your .gitignore files:
x.log
hint: Use -f if you really want to add them.
hint: Turn this message off by running
hint: "git config advice.addIgnoredFile false"

1回だけ例外的に追加したいなら git add -f x.log が使えます。ただ、毎回 -f が必要になるので、継続して追跡したいファイルは ! で取り消しを書いておくほうが、チーム全員に意図が伝わります。

無視されているファイルを一覧する

$ git status --short --ignored
!! .DS_Store
!! .env
!! memo.local.txt
!! node_modules/
!! old.log

!! が無視されているファイルです。「必要なファイルまで無視していないか」を見直すときに役立ちます。無視ファイルをまとめて削除したい場合は、git clean -ndX で対象を確認できます(-n は表示だけで、削除は行いません)。

個人用の無視設定:.git/info/excludeとグローバル設定

無視パターンを書ける場所は3つあり、「誰に適用したいか」で使い分けます。

置き場所 適用範囲 共有されるか 向いているもの
リポジトリ内の .gitignore そのリポジトリ される(コミットする) ビルド成果物、依存パッケージ、.env など全員に共通のもの
.git/info/exclude そのリポジトリの自分の環境だけ されない 自分だけが作るメモや検証用ファイル
グローバル設定(core.excludesFile) 自分の全リポジトリ されない OS やエディタが作るファイル(.DS_Store など)

公式ドキュメントによると、優先順位は高い順に「コマンドラインで渡したパターン → .gitignore(下の階層ほど優先)→ .git/info/exclude → core.excludesFile」です。

.git/info/exclude:このリポジトリで自分だけ

書き方は .gitignore と同じです。リポジトリを作ると、コメントだけが入ったファイルが最初から用意されています。

$ echo 'memo.local.txt' >> .git/info/exclude
$ git check-ignore -v memo.local.txt
.git/info/exclude:7:memo.local.txt  memo.local.txt

.git/ の中はコミットされないので、ほかの人には影響しません。

グローバル設定:自分のすべてのリポジトリ

何も設定しなくても、~/.config/git/ignore に書いたパターンは全リポジトリで有効になります(core.excludesFile の既定値。環境変数 XDG_CONFIG_HOME を設定している場合は $XDG_CONFIG_HOME/git/ignore)。

$ mkdir -p ~/.config/git
$ echo '.DS_Store' > ~/.config/git/ignore
$ git check-ignore -v .DS_Store
/home/taro/.config/git/ignore:1:.DS_Store   .DS_Store

別の場所に置きたい場合は、設定でパスを指定します。

$ git config --global core.excludesFile '~/.gitignore_global'
$ git check-ignore -v .DS_Store
/home/taro/.gitignore_global:1:.DS_Store    .DS_Store

(パスの表示は環境に合わせて置き換えています。)

グローバル設定は自分の環境にしか効きません。 リポジトリを動かすうえで全員に必要な無視(node_modules/ や dist/)は、リポジトリの .gitignore に書きましょう。

追跡済みファイルの変更を手元だけ見ないようにする

「設定ファイルは共有したいが、自分の環境用に書き換えた分はコミットしたくない」という場合は、.gitignore ではなく git update-index --skip-worktree が使えます。

$ git update-index --skip-worktree app.js
$ echo x >> app.js
$ git status --short
(app.js は表示されない)

$ git ls-files -v | grep '^S'
S app.js

$ git update-index --no-skip-worktree app.js   # 元に戻す

これは自分の環境だけの設定です。設定したことを忘れやすいので、git ls-files -v | grep '^S' で確認できることも一緒に覚えておくと安心です。

コピペ用テンプレート

以下のテンプレートは、それぞれサンプルのパスを作って git check-ignore と git status で想定どおりに振り分けられることを確かめています(確かめたのはパターンの振り分けで、各ツールで実際にビルドしたわけではありません)。自分の構成に合わせて、不要な行を削って使ってください。

Node.js

# 依存パッケージ
node_modules/

# ビルド成果物
dist/
build/
.next/
out/
coverage/

# ログ
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*

# 環境変数(ひな形の .env.example は残す)
.env
.env.*
!.env.example

# キャッシュ
.cache/
.eslintcache
*.tsbuildinfo

確認結果:node_modules/a/i.js、dist/x.js、.env、.env.local、npm-debug.log.1、tsconfig.tsbuildinfo は無視され、.env.example、package-lock.json、src/app.ts は追跡対象として残りました。package-lock.json などのロックファイルは、依存バージョンをそろえるためにコミットするのが一般的です。

Python

# バイトコードとキャッシュ
__pycache__/
*.py[cod]

# 仮想環境
.venv/
venv/

# パッケージング
build/
dist/
*.egg-info/

# テストと型チェックのキャッシュ
.pytest_cache/
.mypy_cache/
.ruff_cache/
.coverage
htmlcov/

# Jupyter
.ipynb_checkpoints/

# 環境変数
.env

確認結果:src/__pycache__/a.cpython-311.pyc、a.pyo、.venv/bin/python、mypkg.egg-info/PKG-INFO、.env は無視され、app.py と requirements.txt は残りました。

Java(Maven・Gradle)

# コンパイル結果
*.class

# Maven
target/

# Gradle
.gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/

# パッケージ(Gradle ラッパーの jar は残す)
*.jar
*.war
!gradle/wrapper/gradle-wrapper.jar

# IDE
.idea/
*.iml
.classpath
.project
.settings/
.vscode/

# ログ
*.log
hs_err_pid*

確認結果:target/classes/A.class、build/libs/app.jar、lib/x.jar、app.iml は無視され、gradle/wrapper/gradle-wrapper.jar、src/main/java/App.java、src/main/java/build/Tool.java は残りました。build/ はスラッシュなしのパターンなので全階層に効きますが、!**/src/main/**/build/ の行で、ソースの中にある build パッケージを追跡対象に戻しています。

Unity

# Unity が自動生成するフォルダ(リポジトリ直下のものだけ)
/[Ll]ibrary/
/[Tt]emp/
/[Oo]bj/
/[Bb]uild/
/[Bb]uilds/
/[Ll]ogs/
/[Uu]ser[Ss]ettings/
/[Mm]emoryCaptures/

# IDE が生成するファイル
.vs/
.idea/
*.csproj
*.sln
*.suo
*.user
*.userprefs
*.pidb
*.booproj

# ビルド成果物
*.apk
*.aab
*.unitypackage

# クラッシュレポート
sysinfo.txt

確認結果:Library/a.asset、Temp/x、UserSettings/x.asset、Game.sln、Assembly-CSharp.csproj は無視され、Assets/Scripts/Player.cs、Assets/Scripts/Player.cs.meta、ProjectSettings/ProjectSettings.asset、Assets/Build/tool.cs は残りました。

  • 先頭にスラッシュを付けているので、Assets/Build/ のような同名フォルダは巻き込みません。
  • .meta ファイルは無視しません。 アセットの参照情報が入っているため、アセット本体と一緒にコミットします。
  • このテンプレートは Unity プロジェクトのルート(Assets/ と同じ階層)に置く前提です。Unity エディタでの動作確認は未実行です。

macOS・Windows・エディタ(グローバル設定向け)

# macOS
.DS_Store
.AppleDouble
.LSOverride
._*
.Spotlight-V100
.Trashes

# Windows
Thumbs.db
Thumbs.db:encryptable
ehthumbs.db
[Dd]esktop.ini
$RECYCLE.BIN/
*.lnk

# エディタ
.idea/
.vscode/
*.swp
*~

確認結果:.DS_Store、sub/.DS_Store、Thumbs.db、desktop.ini、._a、a.txt~、$RECYCLE.BIN/x は無視され、a.txt は残りました(Linux 上でファイル名を作って確認。macOS・Windows の実機では未実行です)。

OS やエディタが作るファイルは人によって違うので、~/.config/git/ignore に入れておくと、どのリポジトリでも自動的に効きます。 .vscode/ をチームで共有している場合は、その行を外してください。

テンプレートを置く場所の目安

無視したいもの 置き場所
言語・フレームワークが生成するもの(node_modules/、target/、__pycache__/) リポジトリの .gitignore
秘密情報を含む設定(.env) リポジトリの .gitignore
OS が作るファイル(.DS_Store、Thumbs.db) グローバル設定(チームで合意があればリポジトリにも)
自分だけの作業メモ・検証用スクリプト .git/info/exclude

書き方のチェックリスト

  • [ ] .gitignore は UTF-8 で保存している
  • [ ] 直下だけを対象にしたいパターンは、先頭にスラッシュを付けている
  • [ ] ディレクトリを指定する行は、末尾にスラッシュを付けている
  • [ ] 取り消し(!)は、対応する無視の行より後に書いている
  • [ ] 中のファイルを残したいディレクトリは、dir/ ではなく dir/* で無視している
  • [ ] コミット済みのファイルは git rm --cached で追跡を外した
  • [ ] git status --short --ignored で、必要なファイルまで無視していないか確かめた
  • [ ] 秘密情報を含むファイルは、最初のコミットより前に .gitignore へ書いた

よくある質問

Q. .gitignore 自体はコミットするのですか? A. はい、コミットして共有します。全員が同じルールで作業できるようになります。自分だけに適用したいパターンは、.git/info/exclude かグローバル設定に書きます。

Q. 空のディレクトリを Git で管理できますか? A. Git はファイルを追跡する仕組みなので、空のディレクトリだけをコミットすることはできません。.gitkeep という名前の空ファイル(名前は慣習で、Git の機能ではありません)を置き、dir/* と !dir/.gitkeep を組み合わせると、ディレクトリだけを残せます。

Q. build と build/ と /build/ はどれを使えばよいですか? A. リポジトリ直下の1か所だけなら /build/、どの階層の build ディレクトリも対象にしたいなら build/ です。build と書くと同名のファイルにもマッチするので、ディレクトリを指すときは末尾のスラッシュを付けておくと意図が明確になります。

Q. git check-ignore -v で行が表示されたのに、git status に出てきます。 A. 表示されたパターンの先頭が ! なら、それは「無視を取り消した行にマッチした」という意味で、ファイルは無視されていません。順番を入れ替えるか、取り消しの行を見直してください。

Q. .gitignore を書き換えたのに、すぐ反映されません。 A. .gitignore は保存した時点で有効になります。反映されないように見えるときは、対象がすでに追跡済みであることがほとんどです。git ls-files -ci --exclude-standard で確認し、git rm --cached で追跡を外します。

まとめ

  • スラッシュの位置で範囲が決まる:先頭・途中にあれば .gitignore からの相対パス、なければ全階層。
  • 末尾スラッシュはディレクトリ専用、アスタリスク1つは階層をまたがず、二重アスタリスクで階層をまたぐ。
  • 下の行ほど優先されるので、「広く無視 → 感嘆符で一部を戻す」の順に書く。
  • ディレクトリ内の1ファイルを残すときは dir/* と !dir/keep。dir/ で無視すると中のファイルは戻せない。
  • 効かないときは git check-ignore -v と git ls-files -ci --exclude-standard で、パターンの問題か追跡済みかを切り分ける。
  • 追跡済みのファイルは git rm --cached で、手元のファイルを残したまま追跡を外す。
  • 全員共通は .gitignore、自分だけは .git/info/exclude、OS・エディタ由来はグローバル設定に書き分ける。

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「.gitignoreの書き方一覧 パターン早見表と効かないときの確認手順」

株式会社RJCでは、Gitの使い方やリポジトリの整え方を仲間と学び合っています。こうした知識を共有しながら、日々技術を磨いています。

株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。

WE ARE HIRING

RJCで一緒に開発しながら、
成長を楽しみませんか?

RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!

  • 127日年間休日
  • 12時間平均残業時間
  • 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!

ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

RJCで一緒に開発しながら、 成長を楽しみませんか?