I was building a CLI tool that records sensitive info in a dot folder, and went looking for best practices to avoid those folders being accidentally committed to git. To my surprise, git doesn’t really provide a way for tool builders to declare that their files shouldn’t be committed. That got me thinking: what if there was a file you could drop in your dot folder, or a comment you could add to the top of a file, or a naming convention you could use, that git would ignore by default?

Today, the best a tool author can do is append a line to .gitignore, which means modifying someone else’s repository, or hope the user adds the right pattern themselves. GitHub has revoked millions of leaked tokens found by scanning public repositories, and tools like git-secrets and detect-secrets try to catch credentials before each commit. These all work after the fact. The person best positioned to prevent the leak is the tool author, and they have no mechanism to do it.

Git’s existing ignore mechanisms all require someone other than the tool to act. .gitignore requires the repository maintainer to anticipate every tool that might drop files in the project directory. --assume-unchanged and --skip-worktree are per-clone flags that get forgotten after every fresh clone, .git/info/exclude lives outside the working tree so tools can’t safely or portably write to it, and export-ignore in .gitattributes only affects git archive. I catalogued all of these in my post on git’s magic files, and none of them let the file or tool declare itself untrackable.

A .gitlocal marker file would let the tool speak for itself. A tool creates its config directory as usual: .sometool/config.json, .sometool/credentials.json, and drops an empty .gitlocal file alongside them. Git sees the marker and ignores the entire directory. No filenames need to change, no comment headers, no format restrictions, so it works with JSON, YAML, binary blobs, anything. The pattern follows .gitignore and .gitkeep as a marker file that changes git’s behavior, and the name isn’t used by any existing convention. An empty .gitlocal would ignore the whole directory, but the file could also contain glob patterns like .gitignore does, so a tool that wants to protect credentials.json but leave config.json trackable could list just the sensitive files.

Tools that write sensitive files usually write them into their own config directory, so the directory marker covers most cases. A tool that writes standalone files and controls the filename could use a .local.json or .gitlocal extension instead, writing .sometool/credentials.local.json rather than .sometool/credentials.json. When the tool doesn’t control the name, a # gitlocal comment on the first line works for any format that supports comments: shell, Python, Ruby, YAML, TOML, INI, which covers most text config formats where this problem actually shows up. JSON can’t take a comment, but JSON config files almost always live inside tool-specific directories.

New tools ship all the time, and their authors currently have to choose between modifying the user’s .gitignore (presumptuous), documenting which files to ignore (easily missed), or hoping for the best, which is how we got here. .gitlocal gives them an option that requires nothing from the user at all.

The idea of a marker file that changes tool behavior isn’t new. Android’s .nomedia is probably the most widely deployed version: an empty file that tells the media scanner to skip a directory. Backup tools like restic and Borg support --exclude-if-present, which does exactly the same thing for arbitrary filenames. Git already has .gitignore, .gitkeep, and .gitattributes in this family, and .gitlocal would fit alongside them.

The obvious objection is invisible behavior: a file that suppresses its own tracking could surprise people. I think the scale of the secret-leaking problem has outgrown that concern. GitHub is revoking millions of tokens a year, and that’s just the ones they can detect. The semantics can be tight enough to avoid surprises: .gitlocal should only work on untracked directories, never affecting paths that are already tracked, it should show up clearly in git status (something like “ignored due to .gitlocal”), and be visible through git check-ignore. With those constraints it behaves like any other ignore rule, just one that lives closer to the files it describes.

Getting this into git itself means a patch through the git mailing list and convincing the maintainers it belongs in core, a high bar. In the meantime, I built a proof of concept pre-commit hook that checks for all three conventions: marker files, file extensions, and first-line comments. You lose the experience where git just knows, but tool authors could start using the convention today and build an evidence base for a core proposal. That’s more or less how .gitkeep works today: no git code supports it, but the community treats it as standard.

Sure, another dotfile in the growing pile. But every leaked secret means rotated credentials and audited access logs, sometimes worse. An empty marker file in a tool’s config directory seems like a reasonable tradeoff, especially for tools being written right now by authors who know exactly which files are sensitive and have no good way to act on that.