48 comments

[ 0.19 ms ] story [ 18.8 ms ] thread
I'd never heard of .git/info/exclude, core.excludesFile, or ~/.config/git/ignore before. Thanks for posting this!
This is great, and nicely written up in the context of agentic repos etc, but presumably no-one reads the official docs, right: https://git-scm.com/docs/gitignore where the multiple ways of ignoring files are clearly stated?
I have never seen these two files in any git repository I've cloned so far.
Until Claude suggested .git/info/exclude, it never crossed my mind to question how ignoring worked. A search would have answered it in seconds, but you have to think to ask first. I didn't, and I suspect most people don't either. Especially with git, which nearly everyone learns by doing; very few of us ever sit down and learn it properly. That's why I wrote it up: so a few more people can learn this the way we learn everything else in git, by accident.

Now that you mention it, I should add a link to those docs in the article. Thanks!

This is true, using AI to help discover better ways of working with stuff is pretty epic, reading docs are about as exciting as writing docs, esp when you are trying to get something done.
The motivation fades to make things intuitive.
For a lot of tools, people usually read the docs once, and obscure stuff is quickly forgotten.
This is great... one thing I wish is to be able to exclude are lines, for instance some lines in my config that only benefits the work I do. Some configs don't allow extending and that's where this would come in handy. Anyone have any tricks for that?
(comment deleted)
Magit really is the only git frontend worth using. It exposes all of this kind of stuff in an easy to use way. You can easily ignore files using all three methods with magit.

The more useful thing here is the "typical use" of each one. People who don't know about other methods get this wrong a lot and put cruft from their own tools/editors in .gitignore which is annoying.

Just a nit-pick, but some/repo/path/.gitignore isn't necessarily committed to the repo. For example, if your repo has no .gitignore file, you can totally add one in your clone without adding it to the tree. Of course then you can't do something like `git add .` without committing it.

Also `~/.gitignore` works as a global gitignore. I usually stick something like `katie*` in there so I can copy some `script.sh` to `katie_script.sh` and then I can make changes that I don't want to commit.

Quick edit: I'm not sure `~/.gitignore` works out of the box.. looks like I stuck that in my `~/.gitconfig` for excludesfile

(comment deleted)
I've been using $REPO/.scratch/ and .scratch/.gitignore with just `*` in it as a place for coding agents to use as temp storage (scripts, exports, plans, etc) that won't get committed. It's much easier to access these files under the repo path instead of wading through /tmp.
Wait until you learn about

  .git/exclude
  --assume-unchanged
  --no-update-index
.

And fwiw, I think global/home-dir .gitignore is bad, for everything except of OS-level spam like .DS-Store

Nah, I generate dependency trees from gradle because of the crappy way current $job has aggressive transient dependency scanning and I can't stand just updating someone else's transient dependency without validating that there isn't at least a new version of whatever pulled it in.

I have dependency_tree globally excluded because it is my unique naming convention. Actually it might just be my unique approach because other people don't seem to mind having 1000 overrides for libraries they don't use.

(comment deleted)
[delayed]
Or, you could have a build system that does a 100% out-of-tree build into ./build, and then if the build is broken you delete that one directory. You hardly need git to help you with that.
Oh, I can? Cool advice! How do I get the people with bad hygiene that we're talking about to follow it?

(You have lost the plot; your response amounts to explaining how soap and water works to someone who has just described their office mate's tendency not to shower.)

Get a new job? You can't be that "in charge of" a repo if you can't enforce rules this basic. In fact, I don't understand how you can enforce something as (being polite) unusual as banning .gitignore and yet can't enforce build system hygiene.
Believe it or not, there are people whose interactions with software are not limited to projects that they wrote and have control over.
(comment deleted)
So all your fellow devs do `ln -s contrib/gitignore ./git/info/exclude`?

Also you can do `git status --ignored` and it will list all files changed, even if ignored. If that is really your main issue.

[delayed]
The symlink creates what is effectively a version-controlled gitignore. It would be the obvious way of getting around your arbitrary restriction (and how do you know they are not doing this, the symlink is not checked in).

My comment and the other replies show you how to use git to check and clean the files of the much maligned horked build script. These will work regardless of the gitignore contents.

But then again, pretty sure you are just having a laugh at our expense by taking this ridiculous position.

This is one of the strangest opinions I've seen in awhile. Your complaint seems like it should be pointed at projects not having a working "clean" make target.

Also:

  git status --ignored
  git clean -ndX # preview what would be removed
  git clean -fdX # actually delete the files (warning: destructive)
(comment deleted)
I would not recommend this setup, which is effectively using a more complicated and error prone system. That being said, I could handle it.
this was probably discovered by many when seeking how to globally ignore agent configs, until perhaps they decided they'd like to start committing agent configs. though that's just a `git add -f`
On Windows I never found ~/.config/git/ignore. I just used .gitignore for everything.

I've been leaving notes sitting untracked rather than put a filename only I use into the repo. .git/info/exclude is what I actually needed.

Very useful. Minor typo in the post if you're adding the claude code flag: it's "respectGitIgnore" not "respectGitignore".
I prefer a presubmit check for DO NOT SUBMIT and also disable Git smart commits. And then I have those floating around as needed. Seems to avoid all the foot guns I'm reading about, and makes it obvious and easy for other people to use as well. I guess it still shows in my diff tree, but /shrug I still prefer seeing them.
I absolutely despise when people commit their personal ignore patterns into .gitignore. My opinion is that the code in the repository shouldn't know anything about the dev environment. The exception is when the entire team benefits from having their common ignore patterns in the repo - it doesn't make much sense to not commit them in that scenario. In any other situation, people are perfectly capable of ignoring their crap on their own.
> I absolutely despise when people commit their personal ignore patterns.

Beyond things not being neatly compartmentalized, what is the problem? The only risk I see is that you'll have a file you forgot to commit because it happened to match one of those patterns.

Having strong opinions on stuff like this is not healthy.

It depends on whether the pattern is general enough to potentially be useful for others. If it is, then by all means add it to .gitignore. If on the other hand it's specific to the user, e.g. '2026_report.docx', then no, it should not be added.
Does anyone have a trick to blacklist files by type e.g. object / binary code, gz files. Often objects & commands lack extensions so going by extension doesn’t work. Git seems to guess binary pretty well upon diff, how to tap into that.

I’ve used pre-commit hooks for this but I’d rather a simple config flag, it seems trivial.

> but pushing the silly filename I picked for my private notes to a remote repository feels unclean

Pick a directory for them and ignore the directory. Other team members who want to keep their own notes can use that directory as well.

I learned this while using IntelliJ, because it suggests both options. I searched for the difference and, once understood, I was able to use the knowledge everywhere.

The other useful advice is when there is a full folder you want to ignore. Putting a .gitignore with a single "*" ignores the full folder...including the gitignore file itself.

I do use it when I quickly need to ignore the .idea folder

Oh this is nice. I've fallen into the habit of ignoring /devtools and put any input for agents there,I mount it in the agent container and have it put it's auth and memory there, and plans. And a "start agent container"-script, because people have their own preferences when it comes to agents.
> editor clutter has no business in any project's .gitignore, and yet there it is, in most of them

I couldn't agree more with this - except that, in practice, nobody bothers to add their own environment clutter to their own global (or even project-related) gitignore. So invariably we end up with PRs (and even main :scream:) peppered with various .vscode and similar lost souls.