頑張らないために頑張る

ゆるく頑張ります

.gitignoreファイルの効果的な作成方法と運用

Posted at — Jan 14, 2025

はじめに

Gitでプロジェクトを管理する際、すべてのファイルをバージョン管理する必要はありません。むしろ、適切に管理対象を選別することで、効率的で安全なプロジェクト運用が可能になります。本記事では、.gitignoreファイルの基礎から実践的な運用方法まで、GitHub公式テンプレートを活用しながら詳しく解説します。

.gitignoreファイルの基本

.gitignoreとは

.gitignoreファイルは、Gitのバージョン管理から除外したいファイルやフォルダを指定するための設定ファイルです。テキスト形式で記述され、指定されたパターンに一致するファイルは自動的に無視されます。

なぜ.gitignoreが必要か

Gitでプロジェクトを管理していると、「このファイルは管理したくないな…」と思うことがありますよね。そんなときに活躍するのが.gitignoreファイルです。では具体的に、なぜこのファイルが必要なのでしょうか?

リポジトリをスッキリと保つため

「リポジトリの容量が大きくなりすぎて、クローンに時間がかかる…」なんて経験ありませんか?

機密情報を守るため

「あっ!APIキーをうっかりコミットしちゃった!」…こんなヒヤッとする経験は誰にでもあるはず。

開発をスムーズに進めるため

「自分の環境では動くのに、チームメンバーの環境だと動かない…」というトラブル、よくありますよね。

具体例を見てみましょう

普段の開発で遭遇する、こんな場面で.gitignoreが活躍します。

# 例えば、こんなファイルは管理したくないですよね
/node_modules      # npmパッケージ(数百MBになることも!)
.env              # 環境変数(APIキーなどの機密情報)
.vscode/          # VSCodeの設定(人によって違う)
*.log             # ログファイル(その場限りの情報)
dist/             # ビルド成果物(自動生成できる)

これらのファイルを.gitignoreで除外することで、リポジトリは必要なソースコードだけをスッキリと管理でき、チーム開発もスムーズに進められます。つまり、.gitignoreは「不要なものを適切に除外する」ことで、プロジェクトの管理を効率的にしてくれる、とても便利な道具なんです。

.gitignoreファイルの書き方

基本的な記法

# コメント行
file.txt        # 特定のファイルを無視
*.log          # 特定の拡張子を持つすべてのファイルを無視
build/         # フォルダ全体を無視
/node_modules  # ルートフォルダの特定フォルダを無視
**/*.tmp      # すべてのフォルダ下の特定パターンを無視
!important.log # 無視リストから除外(管理対象として追加)

パターンマッチングのルール

言語・フレームワーク別テンプレート

GitHubの公式テンプレートは、開発環境ごとに必要となる.gitignoreを集めたリポジトリです。このテンプレートをそのまま利用すれば、困ることはほぼないと思います。

Node.js プロジェクト

# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage
*.lcov

# nyc test coverage
.nyc_output

# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# Snowpack dependency directory (https://snowpack.dev/)
web_modules/

# TypeScript cache
*.tsbuildinfo

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional stylelint cache
.stylelintcache

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variable files
.env
.env.*
!.env.example

# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache

# Next.js build output
.next
out

# Nuxt.js build / generate output
.nuxt
dist

# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public

# vuepress build output
.vuepress/dist

# vuepress v2.x temp and cache directory
.temp
.cache

# Sveltekit cache directory
.svelte-kit/

# vitepress build output
**/.vitepress/dist

# vitepress cache directory
**/.vitepress/cache

# Docusaurus cache and generated files
.docusaurus

# Serverless directories
.serverless/

# FuseBox cache
.fusebox/

# DynamoDB Local files
.dynamodb/

# Firebase cache directory
.firebase/

# TernJS port file
.tern-port

# Stores VSCode versions used for testing VSCode extensions
.vscode-test

# yarn v3
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions

# Vite logs files
vite.config.js.timestamp-*
vite.config.ts.timestamp-*

Python プロジェクト

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[codz]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
#  Usually these files are written by a python script from a template
#  before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py.cover
.hypothesis/
.pytest_cache/
cover/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
.pybuilder/
target/

# Jupyter Notebook
.ipynb_checkpoints

# IPython
profile_default/
ipython_config.py

# pyenv
#   For a library or package, you might want to ignore these files since the code is
#   intended to run in multiple environments; otherwise, check them in:
# .python-version

# pipenv
#   According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
#   However, in case of collaboration, if having platform-specific dependencies or dependencies
#   having no cross-platform support, pipenv may install dependencies that don't work, or not
#   install all needed dependencies.
#Pipfile.lock

# UV
#   Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
#   This is especially recommended for binary packages to ensure reproducibility, and is more
#   commonly ignored for libraries.
#uv.lock

# poetry
#   Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
#   This is especially recommended for binary packages to ensure reproducibility, and is more
#   commonly ignored for libraries.
#   https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
#poetry.toml

# pdm
#   Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#   pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
#   https://pdm-project.org/en/latest/usage/project/#working-with-version-control
#pdm.lock
#pdm.toml
.pdm-python
.pdm-build/

# pixi
#   Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
#pixi.lock
#   Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
#   in the .venv directory. It is recommended not to include this directory in version control.
.pixi

# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/

# Celery stuff
celerybeat-schedule
celerybeat.pid

# SageMath parsed files
*.sage.py

# Environments
.env
.envrc
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
.dmypy.json
dmypy.json

# Pyre type checker
.pyre/

# pytype static type analyzer
.pytype/

# Cython debug symbols
cython_debug/

# PyCharm
#  JetBrains specific template is maintained in a separate JetBrains.gitignore that can
#  be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
#  and can be added to the global gitignore or merged into this file.  For a more nuclear
#  option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/

# Abstra
# Abstra is an AI-powered process automation framework.
# Ignore directories containing user credentials, local state, and settings.
# Learn more at https://abstra.io/docs
.abstra/

# Visual Studio Code
#  Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore 
#  that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
#  and can be added to the global gitignore or merged into this file. However, if you prefer, 
#  you could uncomment the following to ignore the entire vscode folder
# .vscode/

# Ruff stuff:
.ruff_cache/

# PyPI configuration file
.pypirc

# Marimo
marimo/_static/
marimo/_lsp/
__marimo__/

# Streamlit
.streamlit/secrets.toml

Java プロジェクト

# Compiled class file
*.class

# Log file
*.log

# BlueJ files
*.ctxt

# Mobile Tools for Java (J2ME)
.mtj.tmp/

# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar

# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
replay_pid*

プロジェクト運用のベストプラクティス

効果的なテンプレートの活用

汎用的なパターン

*.tmpファイルなど、多くのプロジェクトで共通して.gitignoreの対象と見なしてよい拡張子はまとめておくと、コピペ元として便利かもしれません。

# 一時ファイル・バックアップファイル
*.tmp
*.temp
*.bak
*.backup
*.swp
*.swo
*~

# ログファイル
*.log
logs/
log/

# 圧縮ファイル(通常は除外)
*.zip
*.tar.gz
*.rar
*.7z

# 証明書・キーファイル
*.pem
*.key
*.crt
*.p12
*.pfx

# データベースファイル
*.sqlite
*.sqlite3
*.db

ただ、基本的には先述したテンプレートに記載されているケースがほとんどであるため、「テンプレートを利用しつつ、不足分は都度追加する」という考え方で問題ないかと思います。

チーム開発での注意点

グローバル.gitignoreの活用

グローバル.gitignoreとは

個人の開発環境に依存するファイル(エディタの設定ファイルやOS固有のファイルなど)は、プロジェクトごとの.gitignoreではなく、グローバル設定で管理するのがおすすめです。

「毎回新しいプロジェクトで、同じパターンを.gitignoreに追加するのは面倒…」と感じたことはありませんか?グローバル.gitignoreを設定することで、個人の環境に関わるファイルを一括で管理できます。

グローバル.gitignoreの設定方法

# グローバル.gitignoreファイルを作成・編集
$ nano ~/.gitignore_global

# Gitにグローバル設定を登録
$ git config --global core.excludesfile ~/.gitignore_global

グローバル.gitignoreの内容例

# OS生成ファイル
.DS_Store          # macOS
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db        # Windows
Thumbs.db
Desktop.ini
$RECYCLE.BIN/

# エディタ関連
*.swp              # Vim
*.swo
*~
.vscode/           # Visual Studio Code(個人設定)
.idea/             # IntelliJ IDEA(個人設定)

# その他の個人環境ファイル
.direnv
.envrc

プロジェクト用とグローバル用の使い分け

プロジェクト用(.gitignore)に含めるもの: - プロジェクト固有のビルド成果物 - フレームワーク・言語固有のファイル - チーム全体で除外すべきファイル

グローバル用(~/.gitignore_global)に含めるもの: - OS固有のファイル - 個人のエディタ設定 - 個人の開発環境に依存するファイル

パフォーマンスを考慮した運用

大容量ファイル・フォルダの事前除外

「リポジトリが重くなってしまってから.gitignoreを設定したけど、もう手遅れ…」というケースを防ぐための予防策です。

プロジェクト開始時のチェックリスト

# プロジェクト開始時に実行
$ echo "node_modules/" >> .gitignore
$ echo ".env" >> .gitignore
$ echo "dist/" >> .gitignore

# 最初のコミット前に確認
$ git status
$ git add .gitignore
$ git commit -m "初期設定: .gitignoreを追加"

既に追加してしまった大容量ファイルの対処

# 大容量ファイルの特定
$ git ls-files | xargs ls -la | sort -nrk5 | head -10

# 履歴からも完全に削除(注意:破壊的操作)
$ git filter-branch --force --index-filter \
  'git rm --cached --ignore-unmatch path/to/large-file' \
  --prune-empty --tag-name-filter cat -- --all

git-filter-branchは微調整が効くコマンドではあるものの、その分実行するには複雑で知識が必要であり、実行速度も少々遅くなってしまいます。そこで、より安全で簡単な方法として、BFG Repo-Cleanerを利用することが挙げられます。

ちなみに、git filter-branchよりもサードパーティ製のgit filter-repoの使用が推奨されているようです。

定期的なメンテナンス習慣

開発が進むにつれて、新しいツールやライブラリが追加され、除外すべきファイルも変化します。定期的なメンテナンスで、.gitignoreを最新の状態に保ちましょう。

月次メンテナンスの例

# 現在無視されているファイルの確認
$ git status --ignored

# 無視されているファイルを実際に削除
$ git clean -fXd

# 新しく除外すべきパターンがないかチェック
$ git status | grep -E "\.(log|tmp|cache)$"

チーム内での.gitignore更新フロー

# .gitignoreの更新をチームに提案
$ git checkout -b update-gitignore
$ echo "新しいパターン" >> .gitignore
$ git add .gitignore
$ git commit -m "chore: 新しいビルドツールの出力ファイルを除外対象に追加"
$ git push origin update-gitignore

よくある問題と対処法

「.gitignoreを設定したのに、ファイルが除外されない!」というケース

.gitignoreにちゃんとパターンを追加したはずなのに、git statusで確認すると、まだそのファイルが表示されてしまう…」という経験はありませんか?このケースでは、.gitignoreにパターン追加する前、すでにそのファイルが管理対象となってしまっています。

原因:

解決方法:

# キャッシュをクリアして.gitignoreを再適用
$ git rm -r --cached .
$ git add .
$ git commit -m "清掃: .gitignoreの再適用"

# 特定のファイルだけキャッシュをクリア
$ git rm --cached path/to/file.log

具体例:

# 以下のような状況
$ git status
Changes to be committed:
  modified:   logs/debug.log

# .gitignoreに追加しても変更なし
$ echo "*.log" >> .gitignore
$ git status  # debug.logが依然として表示される

# キャッシュをクリアして解決
$ git rm --cached logs/debug.log
$ git status  # debug.logが表示されなくなる

「意図していないファイルまで除外されてしまう(または除外されない)」というケース

「buildフォルダを除外しようとしたら、関係ない場所のbuildまで除外されてしまった」「PDFファイルを除外しようとしたのに、なぜか除外されない」といった経験はありませんか?パターンの書き方がちょっと違うだけで、挙動に大きな差が出てきます。

よくあるパターンミスの例:

# 誤: すべての階層のbuildフォルダを除外
build

# 正: ルートフォルダのbuildフォルダのみ除外
/build

# 誤: 特定の拡張子を持つファイルを除外しようとして失敗
.pdf

# 正: 特定の拡張子を持つファイルを除外
*.pdf

確認方法:

# パターンマッチングのテスト
$ git check-ignore -v path/to/file.pdf
.gitignore:25:*.pdf    path/to/file.pdf

# 複数ファイルのテスト
$ git status --ignored  # 無視されているファイルも表示

「チームメンバーとの間で環境設定ファイルの扱いがバラバラ…」というケース

開発チームで「自分の環境では動くのに、他のメンバーの環境で動かない」「環境設定ファイルをうっかりコミットしてしまった」といった問題が発生していませんか?開発の環境によりケースバイケースですが、環境設定ファイルを管理対象外にする場合はチーム内で一貫性を持たせたほうが良いでしょう。

推奨される管理方法:

# 1. テンプレートファイルの作成
$ cp .env .env.example
$ git add .env.example
$ git commit -m "環境設定のテンプレートを追加"

# 2. .gitignoreの設定
$ echo ".env" >> .gitignore
$ echo ".env.local" >> .gitignore
$ echo "!.env.example" >> .gitignore

実装例:

# .env.example
DB_HOST=localhost
DB_PORT=3306
DB_USER=user
DB_PASS=password

# .gitignore
.env
.env.*
!.env.example

「このフォルダの中の、特定のファイルだけ除外したいんだけど…」というケース

「uploadsフォルダは必要だけど、その中の一時ファイルは要らない」「cacheフォルダの直下のファイルだけ除外して、サブフォルダは残したい」といった細かい制御が必要な場合の対処法です。

解決方法:

# uploads/フォルダ内のすべての.tmpファイルを除外
uploads//*.tmp

# uploads/フォルダ自体は維持
!uploads/.gitkeep

# cache/フォルダ内のファイルを除外するが、サブフォルダとその中身は維持
cache/*
!cache/*/

動作確認:

# 無視パターンのテスト
$ git check-ignore -v uploads/temp/test.tmp
.gitignore:3:uploads//*.tmp    uploads/temp/test.tmp

# 管理対象の確認
$ git status

トラブル防止のために

「今後同じような問題を起こしたくない!」という方のために、予防的な対策を紹介します。

パターンを追加する時のおすすめ確認手順

# 1. パターンの追加
$ echo "*.log" >> .gitignore

# 2. 影響範囲の確認
$ git status --ignored

# 3. 特定のパターンのテスト
$ git check-ignore -v path/to/test.log

なんらかのパターンを追加した際は、まずはgit check-ignore -v [ファイルパス]コマンドで確認してみましょう。どの.gitignoreのパターンがそのファイルに適用されているのかが分かります。これにより、「gitを実行したら、想定外のファイルまで影響を受けてしまった」ということがなくなります。

定期的なメンテナンス

$ git clean -ndX  # 無視されているファイルの削除をプレビュー
$ git clean -fXd  # 無視されているファイルを実際に削除

まとめ

効果的な.gitignoreの設定は、プロジェクトの品質と開発効率に大きく影響します。ここで紹介した基本原則とベストプラクティスを参考に、プロジェクトに最適な.gitignoreを作成・運用しましょう。

参考

  1. Git公式ドキュメント
  2. GitHub公式テンプレート
  3. gitignore.io
  4. rtyley/bfg-repo-cleaner
  5. BFG Repo-Cleaner
  6. Gitのコミット履歴から機密情報を削除する