.gitignore Is Inherently Sisyphean

2025-07-2616:494563rgbcu.be

And how to roll the rock over the edge.

You just started a new project. You ran cargo init, poetry init and go mod init.

Those commands created the necessary files to work, it also added the following lines to your .gitignore:

All great. You continue implementing features, and when the time comes, you publish your project to your Git hosting platform of choice.

People start to get interested in your project. One even decides that he's going to implement a new feature! Literally free work done for you!

Alright. That person uses his code editor and tools bundled with his operating system to implement a very cool new feature. He then submits the merge request.

You start reviewing the code and notice a file quite out of place: .DS_Store. You ask the person what it is, he says he has no clue.

Hundreds of thousands of merge requests on GitHub trying
to gitignore .DS_Store

Whatever. You just delete the file from the branch and add the file's name to the repositories gitignore:

target
__pycache__
bin
.DS_Store

Nice. Now the code is on master, and your repository only contains relevant information.

Then, someone using an IDE created using web technologies submits another merge request. You look at it, and see that there is a whole directory that is irrelevant. You tell that person to delete the directory from the branch and add it to the gitignore. The gitignore lives on:

target
__pycache__
bin
.DS_Store
.vscode

Then, someone that uses IntelliJ IDEA commits five hundred XML files and the .idea directory. You repeat this process:

target
__pycache__
bin
.DS_Store
.vscode
.idea

Years pass. Now your gitignore is hundreds of lines long, yet people keep accidentally committing in test scripts, foo, a, qux, data.tar.gz, start.sh, bin-release, cat, asd, fgsgskfh.

Hell. You feel like a mythic god undergoing punishment for cheating death and deceiving the underworld.

Sisyphus pushing up a boulder that has .DS_Store written
on it

How will you escape this endless loop of ignoring files that sneak in? Maybe by educating every single merge request author? Nope, that definitely won't work, there should be a way to automatically handle this with tooling, rather than subjective human communication.

Luckily, you realize that you can turn the blacklist of files (the gitignore) into a whitelist, by just ignoring everything and manually un-ignoring desired files. You change your gitignore to this:

*

!.gitignore

# whitelist `src` directories and their children, regardless of place
!src/**/
!src/**/*.rs
!Cargo.{toml,lock}

# whitelist root `pysrc` directory
!/pysrc/*.py
!pyproject.toml
!poetry.lock

!/cmd/*.go
!main.go
!go.{mod,sum}

!/docs/*.md

Now, nobody can accidentally commit undesired files, as git automatically ignores them all and only allows the files that are explicitly whitelisted. It's also future proof, future proof until an IDE decides to use the src/ide.rs file as a convenient way of storing project specific configuration. And hopefully that future never comes.

You feel relieved.

Copyright 2025

Read the original article

Comments

  • By yencabulator 2025-07-2822:461 reply

    This is a bad idea and if this seems necessary you are interacting with very low quality committers. People who don't even bother reading their own commits do not deserve to get their commits merged.

    Also, that gitignore doesn't even work. man gitignore:

           •   An optional prefix "!" which negates the pattern; any
               matching file excluded by a previous pattern will become
               included again. It is not possible to re-include a file
               if a parent directory of that file is excluded. Git
               doesn’t list excluded directories for performance
               reasons, so any patterns on contained files have no
               effect, no matter where they are defined. [...]

    • By cstrahan 2025-07-2823:53

      > Also, that gitignore doesn't even work.

      It's not terribly far off. This works:

        diff --git a/.gitignore b/.gitignore.new
        index 7dc7aea..fc9ebfe 100644
        --- a/.gitignore
        +++ b/.gitignore.new
        @@ -3,17 +3,21 @@
         !.gitignore
         
         # whitelist `src` directories and their children, regardless of place
        +!src
         !src/**/
         !src/**/*.rs
         !Cargo.{toml,lock}
         
         # whitelist root `pysrc` directory
        +!/pysrc
         !/pysrc/*.py
         !pyproject.toml
         !poetry.lock
         
        +!/cmd
         !/cmd/*.go
         !main.go
         !go.{mod,sum}
         
        +!/docs
         !/docs/*.md
      
      This is how I've been managing my dotfiles for over a decade (https://github.com/cstrahan/dotfiles/blob/master/.gitignore).

      This is the email thread I started back on 2016/03/3 to pin down the gitignore behavior that we now have today (there was a regression between git version 2.6.0 and 2.7.0):

      https://lore.kernel.org/git/1457057516.1962831.539160698.3C8...

      (For posterity: the subject line was "Change in .gitignore handling: intended or bug?")

  • By arcfour 2025-07-2822:393 reply

    I have never once experienced this problem. Mostly because I don't work with people who blindly commit everything without even looking once to see what's in their commit.

    • By pxc 2025-07-2822:501 reply

      I use gitnr[1] to add fairly comprehensive `.gitignore` files to my repos at creation time.

      Ultimately, it's the responsibility of each developer to determine whether or not the files they've added to their local clone really belong in source control! I've never encountered this issue, either, and I think I'd be unhappy working on a team where it was a serious problem.

      That said, the whitelist approach does seem kinda interesting. It's really what should be present from the start, since Git had a manual staging process. But maybe this gap highlights a legit usabiiity issue. Maybe "add everything" plus an explicit, version-controlled whitelist is somehow easier or more intuitive than the "add nothing" default.

      --

      1: https://github.com/reemus-dev/gitnr

      • By arcfour 2025-07-294:03

        In the Go world, the whitelist approach is a popular alternative to the standard gitignore, since Go projects can kind of take any structure the developer sees fit.

        To me the normal approach makes equal sense. I create a file, but I'm not ready for other people to see it yet, because it's just a placeholder. So I don't add it. But another set of files are ready, and are part of one logical step of the change, so I add them specifically and commit.

    • By plorkyeran 2025-07-2823:362 reply

      Interns and new hires sometimes need a quick chat about actually looking at their changes before asking for a review, but that's about it in my experience. I guess it could be a problem for a project which accepts a large number of public PRs from mostly non-technical or beginner users?

      • By vdfs 2025-07-290:201 reply

        It's not a problem with PRs if you use Squash merge, the developer can make any number of changes to that PR but in the end, only the final version (in this case it doesn't include .DS_Store) will be commited. even the .DS_Store file will not be in the git index

        • By matheusmoreira 2025-07-2918:59

          That sacrifices the git history though. It turns the PR into a huge atomic change instead of a series of step-by-step changes that are easy to review.

      • By arcfour 2025-07-294:05

        Yes, I have run into that once or twice but never to the extent that I would call it "sisyphean", haha.

    • By wpollock 2025-07-290:32

      I had this issue all the time. Until I retired as a CS college professor. An accept-list is the way to go when you have lots of people making commits.

  • By edflsafoiewq 2025-07-2822:414 reply

    Ideally people who have .DS_Store, .vscode, etc. would put them into their own $GIT_DIR/info/exclude files and not pollute the shared .gitignore with stuff from their personal setup.

    • By nomel 2025-07-2823:082 reply

      I've found that reducing the friction, as much as possible, is the only way to get people to actually contribute.

      Excluding things like .vscode and .DS_store, which is a common and universal "don't need that in my repo", is a trivial way to reduce the burden for everyone (the goal of software, imo), maintainer included.

      • By eadmund 2025-07-291:342 reply

        > Excluding things like .vscode and .DS_store

        I’m old and cranky enough to want to believe that excluding contributions from VS Code and macOS users is a trivial way to reduce the maintainer’s burden and improve software quality.

        That’s completely unfair, of course, and probably false too.

        edit: s/maybe/probably/

        • By Ferret7446 2025-07-293:52

          I don't think you need to fencesit that hard. VS Code and macOS users *that don't know how to double check their commit or ignore their junk files locally will definitely cause extra burden and lower software quality. If they can't check their commits for .vscode, do you really think they tested their code properly or thought hard about the code that they wrote? If they don't know abut local git ignore files, do you think they know the language and libraries well enough? If they didn't read the Git docs, then did they read the docs that said to not use a specific function in this way?

      • By Ferret7446 2025-07-293:47

        If you want to attract novice contributors, sure. This is as much give-and-take as anything else; if you want these kind of people, then you're going to have to throw a bone to these people.

        Now, if you don't want contributors, or at least novice contributors that don't know to proofread their commits or ignore their own IDE files, then this actually helps you screen out the contributors you don't want to engage with early.

    • By mook 2025-07-293:54

      Just use core.excludesFile, once per machine.

      https://git-scm.com/docs/git-config#Documentation/git-config...

    • By gruez 2025-07-2823:532 reply

      [deleted]

      • By do_not_redeem 2025-07-290:061 reply

        This post is about unwanted files ending up in git. So if you don't use git and you collaborate by swapping floppy disks or whatever, you won't have this problem. (But you'll have other problems, of course)

      • By meatmanek 2025-07-290:053 reply

        What project is using .gitignore but not git?

        • By gpm 2025-07-291:19

          Lots of non-git tools use them. Some that come to mind are ripgrep (by default ignores .gitignore'd files), some editors (greying them out in the file selector, not searching them, etc), rustic (not backing them up), probably more.

        • By weikju 2025-07-290:15

          For one thing, many AI code helpers use the contents of .gitignore as a suggestion for files to not include in their context or changes.

        • By gruez 2025-07-290:15

          My bad, I misinterpreted the proposal.

    • By adastra22 2025-07-2823:07

      TIL

HackerNews