alt.hn

2/22/2026 at 2:21:35 PM

Git's Magic Files

https://nesbitt.io/2026/02/05/git-magic-files.html

by chmaynard

2/22/2026 at 7:13:20 PM

> 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?

by masfuerte

2/22/2026 at 7:34:11 PM

Not true, you can push a file and later gitignore it and it will remain visible on those UIs. It's still part of the repo.

Doing it the other way around is also possible but harder as the git client will refuse but can be convinced.

by silverwind

2/22/2026 at 7:38:59 PM

Yeah this is wrong.

They will show the files in your repo.

gitignore just decides whether untracked files appear as new or ignored. (But you can commit them anyway if you are so inclined.)

by paulddraper

2/22/2026 at 8:02:30 PM

how do you commit a file without first adding it?

by chrisweekly

2/22/2026 at 8:06:25 PM

`git add -f` will add ignored files. Once you've done that, any files you've added will be part of your commit regardless of the contents of .gitignore.

by JonathonW

2/23/2026 at 9:26:05 AM

Also, files that are added to .gitignore after they’ve already been committed will still appear as modified. To stop tracking them, you need to remove them from the index (staging area):

    git rm --cached <file>

by wumms

2/22/2026 at 8:11:55 PM

Right... and also (I think; unsure bc I only ever use cli) some GUIs (eg github.com web ui) may enable adding files that'd otherwise be ignored.

(shrug)

by chrisweekly

2/23/2026 at 7:14:04 AM

would be nice, if there's a modifier in there, which says showinwebui=(true|false) :D

by deknos

2/22/2026 at 9:37:48 PM

Yeah, also that's probably not the kind of error a human writing this post would make... I stopped reading at that point

by wheybags

2/22/2026 at 10:40:05 PM

This is exactly the sort of error that a human with a slightly incorrect mental model for something makes all the time.

by plorkyeran

2/22/2026 at 9:00:21 PM

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`

by jakub_g

2/23/2026 at 2:29:18 AM

Here's a little extra magic so that you don't even need to be in the root of the repository to create such a temporary file (you'll have to change the readlink invocation if you're on MacOS):

    git-ignore-local () {
      root=$(git rev-parse --show-toplevel)
      path=$(readlink -f "$1")
      # ${path#${root}} should suffice if you don't have realpath
      relpath=$(relpath -m --relative-to="$root" "$path")
      echo "$relpath" >> "${root}.git/info/exclude"
    }
Edit: You could also put the function contents as an executable on your PATH called `git-ignore-local` then it becomes something you can invoke as `git ignore-local`.

by jmholla

2/23/2026 at 3:49:50 PM

FYI: you may want to check `git rev-parse --show-cdup`

- in root of the repo, it prints empty string

- if you're 1 level deep it prints `../`

- if you're 2 levels deep it prints `../../`

One minor drawback: inside `.git` subfolder, it always prints empty string too.

by jakub_g

2/23/2026 at 6:50:51 AM

Whoops, there should be a slash after `${root}` in that last line.

by jmholla

2/22/2026 at 9:08:26 PM

.git/info/exclude is mentioned in the first section (about .gitignore)

by theowaway213456

2/22/2026 at 9:15:12 PM

Oops, I've glanced over it too fast. Thanks - updated my post.

by jakub_g

2/23/2026 at 5:33:21 AM

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.

by anitil

2/23/2026 at 1:33:45 PM

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.

by speleding

2/23/2026 at 4:58:53 PM

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.

by Arrowmaster

2/23/2026 at 6:02:41 PM

I'm not very familiar with deploy tools other than Capistrano, but I would think you also do not want to have the .git directory with your entire repo inside the working directory on the production server, so I assume some kind of "git export" must happen at some stage on most deploy tools? (Or perhaps they just rm -rf the .git directory?)

by speleding

2/23/2026 at 8:12:15 PM

tangential, but deploys/builds that involve worktrees happen to neatly sidestep this since then .git is just a pointer to the real one. i use this to avoid having to otherwise prevent docker from wasting time reading the git info into the build context (especially important for latency if feeding local files into a remote image build)

by nagaiaida

2/22/2026 at 9:39:31 PM

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`

by Jenk

2/22/2026 at 11:27:58 PM

.git/info/exclude

by formerly_proven

2/23/2026 at 7:25:14 PM

Unfortunately not. Git clean still tries to, well, clean it. Unless I goofed it, which is a >0 possibility, I will happily concede.

by Jenk

2/23/2026 at 12:32:22 AM

In the above case, since this touches the local repo, wouldn't a .gitconfig include.path be a better option?

Just in case it's unclear, you'd then set an excludesFile in the included file to the path to a file like jj.gitignore that has a line like .jj in it.

by opello

2/23/2026 at 12:24:38 AM

> 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

by mananaysiempre

2/22/2026 at 7:06:59 PM

.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.

by DHowett

2/22/2026 at 8:22:37 PM

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

by ilostmymangoman

2/23/2026 at 1:51:48 AM

!! Thank you!

by DHowett

2/22/2026 at 6:15:53 PM

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.

by retrodaredevil

2/23/2026 at 7:18:36 AM

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.

by MajorBee

2/22/2026 at 5:20:44 PM

> 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.

by paulddraper

2/22/2026 at 5:28:28 PM

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.

by jmholla

2/22/2026 at 6:03:55 PM

I'd prefer to leave them out. That way I can see who's not paying attention when they make commits and are just doing `git commit -a -m "yolo"`.

by phyzome

2/23/2026 at 1:36:22 AM

Surely you'll be able to tell who's YOLOing commits without allowing junk into your repo that you'll have to clean up (and it almost certainly be you doing it, not that other person).

DS_Store files are just annoying, but I've seen whole bin and obj directories, various IDE directories, and all kinds of other stuff committed by people who only know git basics. I've spent way more effort over time cleaning up than I have on adding a comprehensive gitignore file.

It takes practically no effort to include common exclude patterns and avoid all that. Personally, I just grab a gitignore file from GitHub and make a few tweaks here and there:

https://github.com/github/gitignore/

by saila

2/23/2026 at 3:10:17 AM

I prefer to leave them in. Why waste my time reviewing PRs that would have been fin otherwise. And, why waste other people's time.

by socalgal2

2/22/2026 at 5:40:53 PM

I have this two liner as part of my post-os-install setup script:

    curl -fsSL https://www.toptal.com/developers/gitignore/api/linux > ~/.gitignore
    git config --global core.excludesFile ~/.gitignore

by Defletter

2/22/2026 at 5:45:02 PM

Assuming your global config is ~/.config/git/config, you can download it to ~/.config/git/ignore and not need the overriding explicit excludesFile.

by OJFord

2/22/2026 at 5:47:38 PM

Huh, TIL

by Defletter

2/22/2026 at 9:41:01 PM

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.

by jasonhansel

2/23/2026 at 7:12:48 AM

It can be quite useful to check in project-wide shared editor settings so that everyone in the team is using the same linter/formatter editor settings. We do that in my team for VS Code settings and extensions, even tasks.

I haven't checked if there's a way to maintain a project-scoped _personal_ `.vscode` for those idiosyncratic settings or extensions you want applied to only this project but wouldn't be appropriate to foist on everyone else. I hope there is.

by MajorBee

2/22/2026 at 10:21:07 PM

> 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.

Very well put. This should be in the git-ignore manpage.

by ninkendo

2/22/2026 at 5:43:23 PM

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...

by OJFord

2/22/2026 at 11:28:20 PM

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.

by mhitza

2/23/2026 at 6:16:39 AM

.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.

by tenpa0000

2/23/2026 at 6:54:15 AM

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.

by musicmatze

2/23/2026 at 7:24:49 AM

>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`.

by ta8903