A Rails .gitignore empties log/, tmp/ and storage/ but keeps their .keep files, ignores compiled assets in public/assets/ and app/assets/builds/, Bundler’s local .bundle/, and config/master.key, the key to your encrypted credentials. Those are the key lines of the tool’s Ruby and Ruby on Rails templates picked together, 36 lines in all.
What the blocks ignore
- Ruby: built
*.gemfiles,/.bundle/and/vendor/bundle/,/coverage/, test reports and/tmp/*. - Runtime files:
/log/*,/tmp/*with/tmp/pids/*, and/storage/*, where Active Storage and development SQLite databases live. - Assets:
/public/assets/fromassets:precompile, the old Webpacker/public/packs/, and/app/assets/builds/*, written by cssbundling-rails, jsbundling-rails and tailwindcss-rails. - Keys:
/config/master.keyand/config/credentials/*.key.
In a scratch repository with this file, git check-ignore -v -n --no-index names the line that matched each path, or prints :: when none did:
.gitignore:47:/config/master.key config/master.key
:: config/credentials.yml.enc
:: Gemfile.lock
.gitignore:26:/log/* log/development.log
.gitignore:27:!/log/.keep log/.keep
.gitignore:28:!/tmp/.keep tmp/.keep
.gitignore:30:/tmp/pids/* tmp/pids/server.pid
.gitignore:32:!/tmp/pids/.keep tmp/pids/.keep
.gitignore:44:/app/assets/builds/* app/assets/builds/application.css
:: .env
Commit the encrypted file, never the key
config/credentials.yml.enc is encrypted and meant to be committed; config/master.key decrypts it and must not be. In production, Rails reads the key from RAILS_MASTER_KEY instead. Commit Gemfile.lock too. The template doesn’t ignore .env: if you use dotenv, add it as a custom line.
Why /tmp/* and not /tmp/
The log, tmp and storage lines end in /* on purpose. /tmp/ would exclude the folder itself, and Git never looks inside an excluded folder, so !/tmp/.keep couldn’t work. With the Ruby line written as /tmp/ instead:
.gitignore:14:/tmp/ tmp/.keep
.gitignore:14:/tmp/ tmp/pids/.keep
tmp/pids/ needs one more step for the same reason: /tmp/* excludes it as a folder, so !/tmp/pids/ re-includes it before !/tmp/pids/.keep can apply.
The leading slash means “next to this file”
Each line is anchored to the folder the .gitignore sits in. If the app lives in api/ inside a larger repository, a root file leaves api/log/development.log and even api/config/master.key unmatched (::); put this file in api/.
Committed master.key or logs?
.gitignore only affects untracked files. Untrack them, keeping them on disk, then add the folders back, which brings back only the .keep files, and commit:
git rm -r --cached config/master.key log tmp
git add log tmp
git commit -m "Stop tracking the key and runtime files"
A key that was ever pushed stays in the history: treat it as leaked and replace it.
Editor and OS files
.idea/, .vscode/ and .DS_Store come from your machine. Keep them in a global ignore file:
git config --global core.excludesFile ~/.gitignore_global