`.gitignore 本质上是西西弗斯式的`
.gitignore Is Inherently Sisyphean

原始链接: https://rgbcu.be/blog/gitignore/

一个开发者的项目获得了贡献者,但每次贡献都伴随着意外提交的无关文件——`.DS_Store`、`.vscode`、`.idea`以及无数其他文件。尽管`.gitignore`文件不断增长,清理的循环仍在继续,让人感到无休止和沮丧。 解决方案不是更好的沟通,而是策略的转变。开发者不再*排除*不需要的文件,而是采用了*白名单*方法——忽略所有*除了*明确需要的文件和目录(例如`src`、项目文件和文档)。 这大大减少了意外提交,创建了一个更健壮和可维护的仓库。虽然承认未来可能还会出现IDE的奇怪行为,但开发者终于从与不需要文件的持续斗争中解脱出来,实现了一个更具未来感的流程。

Hacker News 的讨论集中在维护 Git 仓库中干净的 `.gitignore` 文件这一持续挑战上。发帖者认为,尽管尽了最大努力,`.gitignore` 文件不可避免地会因开发者提交 IDE 特定的文件(如 `.DS_Store` 或 `.vscode`)而变得臃肿。 一些评论者提出了策略:使用几乎详尽的初始 `.gitignore`(通过 `gitnr` 或 GitHub 的模板等工具),采用白名单方法(明确包含*仅*所需文件),或利用全局 `.gitignore` 配置来满足个人偏好。然而,一个共同的主题是核心问题在于开发者没有仔细审查他们的提交。 许多人提倡更严格的代码审查实践,并要求贡献者对其包含的未所需文件负责。另一些人建议使用 `$GIT_DIR/info/exclude` 来进行个人设置,使共享的 `.gitignore` 专注于项目特定的排除项。最终,讨论强调了易用性(“添加所有内容”)与维护干净、集中的仓库之间的矛盾。
相关文章

原文

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.

联系我们 contact @ memedata.com