Free .gitignore Generator Online

Build a .gitignore from 23 built-in templates covering languages, frameworks, IDEs and operating systems. Tick the ones your project uses, add your own patterns, and the generator merges them and strips duplicate rules. 100% client-side — nothing leaves your browser.

.gitignore Generator

What is a .gitignore file? A .gitignore file is a plain-text list of glob patterns that tells Git which untracked files to leave alone, so build output, dependency folders, editor settings and secrets never reach a commit. One pattern per line, # starts a comment, a trailing / restricts a pattern to directories, and ! re-includes something an earlier line excluded. It only affects untracked files — anything Git already tracks stays tracked.

How to Use the .gitignore Generator

  1. Tick every template that applies — Selections stack rather than replace, so a Flutter app built on a Mac in VS Code wants Dart / Flutter, VSCode and macOS all checked. Language, tooling and OS templates are meant to be combined.
  2. Add project-specific patterns — The Custom Additions box takes one pattern per line and lands in its own # === Custom === section at the end. This is where local database dumps, scratch folders and generated fixtures belong.
  3. Click Generate — Each selected template is written out under a # === Name === banner in the order the checkboxes appear on the page, not the order you ticked them.
  4. Read the preview before you trust it — Duplicate patterns are removed automatically, so a rule shared by two templates appears only under the first one. A section can therefore look thinner than expected — that is deduplication, not a missing rule.
  5. Copy or download the fileDownload saves it as .gitignore directly. Place it in the repository root, or in a subdirectory if you want the rules to apply only to that part of the tree.
  6. Commit it before anything else — Add and commit the .gitignore as its own change at the start of a project. Patterns added later do nothing for files Git has already started tracking.

How the Generator Builds the File

Every template lives inside the page as a plain list of patterns — nothing is fetched from a registry, and the tool works offline once the page has loaded. These are curated starting points assembled for common stacks rather than copies of any upstream project's files, so treat the result as a solid first draft you then adapt, not as an authoritative standard.

Generating runs three passes. First it concatenates the templates you ticked, each under a # === Name === banner. Then it appends your custom patterns under # === Custom ===. Finally it walks the combined output line by line and removes repeats:

keep line if it is blank, starts with #, or has not been seen before

The comparison is on the trimmed text of the whole line, and the first occurrence wins. That matters when templates overlap. Both Node.js and Python exclude dist/ and build/; tick both and those patterns appear only in the Node section. Select macOS and then Linux and the Linux section loses .DS_Store and Thumbs.db because macOS claimed them first, which occasionally leaves a comment heading with nothing under it. The resulting file behaves identically — Git does not care which banner a pattern sits below — but the layout can look surprising.

Because the match is exact, near-duplicates survive on purpose. .vscode/ and .vscode/* are different strings and both are kept, as are /build and build/. Those distinctions are meaningful in Git, so collapsing them would change behaviour. Runs of three or more blank lines are compressed to one, and the file ends with a single trailing newline.

.gitignore Pattern Syntax

Git matches patterns with shell-style globbing, evaluated against the path relative to the directory holding the .gitignore. Knowing the six rules below covers nearly everything you will write by hand.

PatternMatchesNotes
*.logAny file ending in .log, at any depthA pattern with no slash is matched against the name in every directory below this one.
build/Directories named build, at any depthThe trailing slash means directories only — a file called build is still tracked.
/buildbuild in this directory onlyA leading slash anchors the pattern, so src/build is unaffected.
doc/*.txtdoc/note.txt but not doc/api/note.txt* never matches a /, so it stops at one level.
doc/**/*.txt.txt files at any depth under doc/** spans directory separators; **/ at the start means "in any directory".
!keep.logRe-includes a file an earlier pattern excludedOrder matters — the last matching pattern decides. Cannot rescue a file whose parent directory is excluded.

The negation limit is the rule that wastes the most time. If logs/ is ignored, !logs/important.log does nothing at all, because Git never descends into an excluded directory to discover the file. Exclude the contents instead — logs/* followed by !logs/important.log works, since the directory itself was never excluded.

What the Templates Cover

The 23 templates fall into three groups that are designed to be combined: one for your language or framework, one for your editor, and one for your operating system.

GroupTemplatesTypical exclusions
Languages & frameworksNode.js, Python, Java, Go, Rust, Ruby, PHP, .NET, Dart / FlutterDependency folders, compiled output, package archives, lockfiles and .env files
Mobile & game enginesiOS, Android, Unity, Unreal, ROSDerived data, user-specific project state, signing keystores, build caches and packaged binaries
InfrastructureTerraform, Ansible, Docker, KubernetesState files, .tfvars, vault passwords, override compose files and secret manifests
EditorsJetBrains, VSCode.idea/, *.iml and .vscode/ — with the VSCode template deliberately re-including shared settings, tasks and launch configs
Operating systemsmacOS, Windows, Linux.DS_Store, Thumbs.db, Desktop.ini, trash folders and editor swap files

Several templates take a deliberate position you may want to reverse. The Node.js template ignores package-lock.json and yarn.lock, and Dart / Flutter ignores pubspec.lock; for an application you almost certainly want those committed so that installs are reproducible, and only a published library has a good reason to omit them. Rust's Cargo.lock line is commented out for the same reason. The Terraform template ignores .terraform.lock.hcl, which most teams do commit. Delete the lines you disagree with before saving.

Rules That Catch People Out

Ignoring does not untrack

A .gitignore only governs files Git is not already tracking. Add .env to it after committing .env once and the file keeps being tracked, keeps appearing in diffs, and stays in the repository. Removing it from the index without deleting your local copy is the fix:

git rm --cached .env
git commit -m "Stop tracking .env"

Note that this only stops future commits. The file remains in history and anyone with the repository can read it. If a real credential was committed, rotate it — rewriting history is disruptive and never as reliable as issuing a new secret.

Git reads more than one ignore file

Alongside the .gitignore in each directory, Git consults .git/info/exclude for rules private to your clone, and a global file set through core.excludesFile for rules that follow you across every repository. Editor and OS noise arguably belongs in the global file rather than in a project everyone shares — a teammate on Linux has no need for your .DS_Store rule. Rules in a subdirectory's .gitignore take precedence over ones higher up.

When a file is ignored and you cannot see why

Ask Git directly rather than reading patterns by eye. git check-ignore -v path/to/file prints the exact file, line number and pattern responsible, including rules from the global and per-clone exclude files. git status --ignored lists everything currently being skipped, which is the fastest way to spot a pattern that is matching far more than you intended.

Frequently Asked Questions

In the repository root for rules that apply to the whole project. Git also reads a .gitignore in any subdirectory, where the patterns apply from that folder downwards and take precedence over rules higher up — useful for a docs/ or vendor/ folder with its own conventions. Paths are always resolved relative to the file that contains them, so a leading slash anchors to that directory, not to the repository root.

Yes, and you generally should. The templates are built to stack: pick one for your language, one for your editor and one for your operating system. Each selected template is written under its own # === Name === banner, in the order the checkboxes appear on the page rather than the order you ticked them.

Because it was already listed above. After merging, the generator removes any non-comment line it has seen before, keeping the first occurrence. Node.js and Python both exclude dist/, so with both ticked it appears only in the Node section. The file behaves the same either way — Git evaluates every pattern regardless of which heading it sits under.

Ignore rules only apply to untracked files. Once a file has been committed, Git keeps tracking it no matter what the ignore file says. Run git rm --cached <file> to drop it from the index while keeping it on disk, then commit. If the file held a password or API key, also rotate that credential — it stays readable in the repository history.

No. They are curated lists built into this page covering the same ground for common stacks, not verbatim copies of any upstream collection, and they are not updated when an ecosystem's conventions change. Treat the output as a good first draft: read it, delete what does not apply, and add what your project actually generates.

For an application, almost always yes — the lockfile is what makes an install reproducible across machines and CI. The Node.js template here ignores package-lock.json and yarn.lock, and Dart / Flutter ignores pubspec.lock, which suits a published library but not an app. Delete those lines from the generated file unless you specifically want floating dependency versions.

Almost certainly because a parent directory is excluded. Git does not look inside an ignored directory, so it never finds the file you are trying to re-include and the ! line has nothing to act on. Exclude the contents rather than the directory: logs/* followed by !logs/keep.log works, while logs/ followed by the same negation does not.

No. Every template is embedded in the page and the merge runs in JavaScript in your tab, so nothing you select or type is transmitted. One thing to know: pressing Generate writes your selections and custom patterns into the page URL so the configuration can be bookmarked or shared. If your custom patterns name something sensitive, clear the box before sharing that link.

Run git check-ignore -v path/to/file. It prints the ignore file, line number and exact pattern that matched, and it covers the global core.excludesFile and .git/info/exclude as well as your project's .gitignore. For the wider picture, git status --ignored lists everything Git is currently skipping.

Use Cases

Starting a Repository on Day One

Before the first commit, tick your language, editor and OS templates and commit the result on its own. Getting node_modules/ and .env ignored up front avoids the far messier job of untracking them after they are already in history.

Adding a Second Language to a Repo

A Python service picks up a JavaScript dashboard. Tick both templates, generate, and paste the new sections into the existing file rather than trying to recall which artifacts a Node toolchain leaves behind.

Settling an Editor Argument on a Team

When half the team uses JetBrains and half uses VS Code, tick both so neither group's local settings churn the diff. The VSCode template still keeps shared settings.json, tasks.json and launch.json in the repo.

Keeping Terraform State Out of Git

Terraform state files record every resource and often contain plaintext secrets. The Terraform template covers *.tfstate, *.tfvars and .terraform/ so state lives in a remote backend instead of in version control.

Blocking a Secret Before It Leaks

Add local credential files, service-account JSON and database dumps under Custom Additions. An ignore rule written before the first commit is the cheapest possible protection — after the fact, the only real remedy is rotating the key.