忽略文件与良好习惯


你克隆了一个叫 weather-app 的项目,运行了 npm install,然后查看新仓库的状态。
$ git status
Untracked files:
(use "git add <file>..." to include in what will be committed)
node_modules/
dist/
.env有三个文件夹和文件被标记为未跟踪,而它们都不该出现在提交里。node_modules/ 是几千个文件,npm install 几秒钟就能从 package.json 重新生成出来。dist/ 是构建产物,每次都会从你的源码重新构建出来。而 .env 里存着一个 API 密钥。这些东西永远都不该进入项目的历史记录,可要是不假思索地敲一句 git add .,恰恰就会把它们全带进去。
告诉 Git 该忽略什么
.gitignore 文件列出了 Git 永远不该跟踪的文件和文件夹的匹配模式。你只需要在项目根目录(也就是你在你的第一个仓库中运行 git init 建立仓库的那个位置)创建一次这个文件,从那以后,git status 和 git add . 就会悄悄跳过所有匹配的内容。
# .gitignore
node_modules/
dist/
.env每一行都是一个匹配模式:像 dist/ 这样的普通文件夹名会忽略项目中任何位置出现的整个同名文件夹。 .gitignore 文件本身要提交进仓库。它体积很小,对每一个克隆这个项目的人都有用,理应像你的源码一样被写进历史记录。
$ git status
On branch main
nothing to commit, working tree clean这些规则一旦到位,git status 就会安静下来。这正是它的意义所在:那些你永远不想提交的文件夹和文件不再冒出来打扰你,这样一来,真正显示出来的才是值得你关注的东西。
.gitignore 文件列出了 Git 永远不该跟踪的内容:node_modules/、dist/ 和 .env 几乎是每个项目里的常客。把 .gitignore 文件本身也提交进去,这样每个克隆项目的人拿到的状态都是干净的。我曾经有一次不小心把几千个依赖文件都加进了暂存区,白白浪费了一整个下午才搞明白这个道理。 永远不要提交密钥
API 密钥、数据库密码或签名证书永远不应该出现在提交记录里。 无论是私有仓库还是公开仓库,这条规则同样适用,而且从第一次提交开始就该遵守。把密钥放进像 .env 这样的文件里,第一天就把这个文件加进 .gitignore,然后让应用从那里读取这些值,而不是直接写进源码文件里。
# .env
WEATHER_API_KEY=sk_live_9f8e7d6c5b4a# .gitignore
.env每次都要自动遵守这条规则,没有例外。一旦密钥出现在提交记录里,任何能访问这个仓库的人都能拿到它;如果是公开仓库,那就是任何人都能拿到。
.env 这样的文件里,并在你第一次运行 git add 之前,就把 .env 加进 .gitignore。这是整章里唯一一条值得当作铁律来遵守的规则。 文件已被跟踪后再加进 .gitignore
这是几乎每个人都至少会踩一次的坑。你不小心提交了一个文件,发现了这个失误,把它加进 .gitignore(下面这行 echo 命令会把路径追加到那个文件里),然后指望 Git 从此忘掉它。但事实并非如此。
$ git add config/settings.json
$ git commit -m "Add app settings"
# later, you realize this was a mistake
$ echo "config/settings.json" >> .gitignore
$ git status
On branch main
nothing to commit, working tree cleangit status 显示工作区是干净的,但 config/settings.json 依然被跟踪着,未来每一次 git log 和每一次克隆里它都还在。忽略规则只对 Git 还不知道的文件起作用。 一个文件一旦被添加并提交,它就成了历史记录的一部分,而 .gitignore 对已经进入历史的文件没有任何话语权。
要真正让它从此不再被跟踪,你需要告诉 Git 把这个文件从跟踪列表里剔除,同时保留它在磁盘上的实际内容:
$ git rm --cached config/settings.json
$ git commit -m "Stop tracking config/settings.json"git rm --cached <file> 会把这个文件从 Git 的跟踪范围里移除,但不会把它从你的工作目录里删掉。提交这次移除操作之后,从这时起,你的 .gitignore 规则才终于起到了它一开始就该起的作用。
.gitignore 也没用。忽略规则只对 Git 从来没添加过的文件起作用。要让一个不小心混进去的文件不再被跟踪,运行 git rm --cached <file> 然后提交这次改动。 良好习惯:小提交与干净的仓库
一份整洁的 .gitignore 只是让仓库好用的一半,另一半在于你怎么组织提交。让每次提交只做一件专注的事:一个 bug 修复、一个小功能、一次单独的重构。如果一个下午的工作涉及好几件互不相关的事,就把它拆成好几次提交,而不是到了一天结束时一股脑塞进一次提交里。
$ git add src/weather-widget.js
$ git commit -m "Fix temperature rounding in weather widget"小提交更容易review,出问题时也更容易回退,六个月后你想搞清楚某一行代码为什么存在时也更容易读懂。提交循环讲了怎样写出有用的提交信息;而这个习惯讲的是把改动本身控制得足够小,让写一条好的提交信息成为可能。
.gitignore 覆盖那些永远不该被跟踪的文件夹和密钥。这两个习惯加在一起,基本上就决定了一个仓库用起来是不是舒服。养成的小习惯越早,之后省下的清理工作就越多。 
