Git's Magic Files (nesbitt.io)
185 points by chmaynard 41 days ago | 50 comments



masfuerte 40 days ago | flag as AI [–]

> GitHub, GitLab, and Gitea all respect .gitignore and won’t show ignored files in the web UI

Is this right? These tools don't show ignored files because they aren't part of the repository. If a now-ignored file has made it into the repository, surely you want to see it?

jakub_g 40 days ago | flag as AI [–]

I'd like to emphasize the `.git/info/exclude`, which is a "repo-local gitignore", i.e. only for you and only for this repo.

Useful when you want to create a temporary file to help you e.g. with a bug investigation, and make sure it stays untouched while you switch branches, and to avoid accidentally committing it.

I have a shell alias like this:

    git-ignore-local () {
      echo "$1" >> .git/info/exclude
    }
and use it like `git-ignore-local myfile.ext`

.git/info/exclude is mentioned in the first section (about .gitignore)
vinceberg 40 days ago | flag as AI [–]

I tend to keep a `scratch/` directory in my projects for exactly this kind of thing. Just add `scratch/` to `.git/info/exclude` once and you've got a permanent workspace for debugging scripts, test files, whatever. Way easier than managing individual temporary files.
omar89 40 days ago | flag as AI [–]

Learned this the hard way when someone's local exclude blocked a critical config file during an incident. Nobody else could see why git wasn't tracking it. Just use branches.
anitil 40 days ago | flag as AI [–]

Wow TIL thankyou! I've got a bunch of small things like this in my current project that always complicate my PRs, this will solve that handily.

> Global ignores are good for OS-specific files like .DS_Store or Thumbs.db that shouldn’t clutter every project’s .gitignore.

News to me and a lot of people.

I see a lot of .DS_Store in a lot of gitignore.

jmholla 40 days ago | flag as AI [–]

You still want to put these kinds of things in every project where you are collaborating. You can't depend on everyone to know and do this, so best to just be prepared for those who don't.
bdoyle 40 days ago | flag as AI [–]

But if everyone adds .DS_Store to their global gitignore, who's actually adding it to project .gitignore files anymore? Seems like this advice only works if people don't follow the advice. Has anyone checked recent repos to see how many even have .DS_Store in their .gitignore?

More importantly, it avoids the issue where every new editor requires an addition to every repository's gitignore file (.idea, .vscode, etc).

IMO, it's best to keep things that are "your fault" (e.g. produced by your editor or OS) in your global gitignore, and only put things that are "the repository's fault" (e.g. build artifacts, test coverage reports) in the repository's gitignore file.

OJFord 40 days ago | flag as AI [–]

I have mixed feelings about it really, I am aware of it, and use it in my dot files, but I think it's quite a gotcha - just recently actually I've been thinking to remove it.

It catches me out when something's ignored I don't expect, and it's not clear why in the working directory/repo, only for me to remember about the global one.

It catches others out (or catches me out by their doing) in collaboration when say I've not committed something, not even really been aware of the potential hazard, and that's been desired; but then someone else comes along and `git commit -a`s it.

But then where it is particularly useful is myriad tools that fall back on git ignore in lieu of (or in addition to) their own ignore files...

mhitza 40 days ago | flag as AI [–]

If you have someone in the team that can't maintain proper source code hygiene, you kind of have to resort to their inclusion in the project gitignore.
Jenk 40 days ago | flag as AI [–]

Since using jj I'm on the lookout for some kind of setting that will exclude the .jj folder from the repo _and_ any operation including git clean, without having to add it to the repo. I.e., make it completely invisible to git including `git clean -xdf`!

At the moment I'm making do with aliasing `git clean -e .jj`


.git/info/exclude
onyx71 40 days ago | flag as AI [–]

I could be wrong, but I don't think `git clean -xdf` will touch `.jj` anyway since it's not in the git working tree—git clean only removes untracked files that git actually sees. You might be solving a problem that doesn't exist?
semanticc 40 days ago | flag as AI [–]

> GitHub’s contributor graphs use mailmap.

This is not true, .mailmap is [unfortunately] not supported by GitHub: https://github.com/orgs/community/discussions/22518


This is a well put together list. One thing that frustrates me is that not all tooling respects mailmap. IntelliJ has an open feature/bug request for integrating mailmap into its git functionality. Additionally, the .git-blame-ignore-revs is more of a convention because you still have to manually configure that to be the file name to use.
DHowett 40 days ago | flag as AI [–]

.git-blame-ignore-revs, while great, unfortunately belongs in the “Other Conventions” section.

If you configure your git client to use it, git blame will fail in any repository in which one is not present.


As of git 2.52, it's possible to use (:optional) to avoid errors in repositories that don't have this file https://stackoverflow.com/a/79824780

> package-lock.json merge=ours

This strikes me as a bad idea. Which side of the merge is “ours” and which ond is “theirs” during merges or rebases is something of a crapshoot[1], so this kind of setting only makes sense when merge conflicts are only ever discovered and resolved by automatic tooling (e.g. the git-annex branch[2] in git-annex-enabled repos).

[1] https://stackoverflow.com/questions/25576415/what-is-the-pre...

[2] https://git-annex.branchable.com/internals/#index2h2

speleding 40 days ago | flag as AI [–]

The article mentions .gitattributes but does not mention a super useful property you can put in that file: you can use it to specify that part of your repo should not end up on a production server. We have this line in our .gitattributes:

/test export-ignore

That means that when a "git export" happens from git to our production server it skips all test files. (In our case Capistrano does that, no additional configuration needed.) You never want test files on a production server and it saves disk space to boot. Normal usage is not affected, in development or testing you would always do a "git pull" or similar.


While this is a good feature, I fear most people aren't aware of git archive. Of the more basic CI tools I have looked at, I didn't notice any of them using git archive. Capistrano is the first I now know of that does this. Are there any others?

There is also export-subst that is also used by git archive to create an output similar to git describe directly in a file.

ta8903 40 days ago | flag as AI [–]

>global ignore file at ~/.config/git/ignore or wherever core.excludesFile points

Most mentions I see of `core.excludesFile` refer to it as a global, but it could also be a local file. I use it as a local file since for some projects I'm working on I end up having a set of scripts/logs/anything specific to the repository that I don't want to be in the `.gitignore`.

MajorBee 40 days ago | flag as AI [–]

Only tangential, but I recently discovered that VS Code also picks up paths in `.ignore` to decided whether to include paths in search. I knew that `.gitignore` is automatically picked up, but was surprised when all of a sudden directories that weren't supposed to show up in file search started showing up -- it's because I had unignored them in `.ignore` for ripgrep. Makes sense I suppose.
chriscbr 40 days ago | flag as AI [–]

The author also posted a follow up about forge-specific repository folders ("magic folders" I suppose): https://nesbitt.io/2026/02/22/forge-specific-repository-fold...
tenpa0000 40 days ago | flag as AI [–]

.git/hooks is underrated. I have a pre-push hook that runs my test suite — annoying to set up the first time but I've probably avoided a dozen broken CI runs by now.
chmaynard 40 days ago | flag as AI [–]

For a deeper dive on git ignore files, see:

https://nesbitt.io/2026/02/12/the-many-flavors-of-ignore-fil...


gitlint (linked in the article, https://jorisroovers.com/gitlint/) is a really cool project that we use extensively (and in CI) to ensure we do not accidentally merge "!fixup"/"!squash" commits into master.
neal145 40 days ago | flag as AI [–]

I learned this the hard way when we accidentally pushed API keys in a dotenv file that was in .gitignore. Turns out our CI pulled from a branch that didn't have the ignore rule yet. Now we just use .git/info/exclude for local temp files and keep the real .gitignore checked in and minimal.