.gitignore 是一个文件,它用来指定 git 需要忽略的文件。它对已经被 git 跟踪的文件是不起作用的。
在 gitignore
文件中的每一行都指定了一个 pattern,在判断是否要忽略一个路径时,git 一般会检查 gitignore
的 pattern。pattern 的来源可以不仅仅是 .gitignore
文件,详细情况可以参考【1】。
- 一个空行不会匹配任何文件,它可以用来提高可读性
- 以
#
开头的行是注释,要使用#
字符的话,可以在#
的前面加上反斜杠\
- 行末的空格会被忽略掉,除非使用反斜杠
\
将它们括起来 - 斜杠
/
用作目录分隔符。它可以出现在 pattern 的前面,中间和最后。- 如果斜杠出现在 pattern 的前面或中间(或两者都有),那么这个模式表示的是
.gitignore
文件所在目录的相对目录。否则 pattern 也可能在任意.gitignore
所在目录的任意下级目录进行匹配 - 如果分隔符在 pattern 的末尾,那么这个 pattern 只会匹配目录,否则它可以匹配文件和目录
- 如果斜杠出现在 pattern 的前面或中间(或两者都有),那么这个模式表示的是
- 星号
*
用于匹配除斜杠/
外的任何东西,问号?
匹配除/
外的任意一个字符。范围记号[a-zA-Z]
可以匹配在范围内的一个字符。 - 双星号
**
在匹配路径名时有特殊意义**/
会在所有目录中进行匹配。例如 pattern**/foo
会匹配任意位置的foo
,就和 patternfoo
一样。**/foo/bar
会匹配任意位置的bar
,只要它在目录foo
之下/**
会匹配任何在里面的东西。例如 patternabc/**
会匹配相对.gitignore
所在目录的目录abc
内的所有文件,且不论文件夹的深度/**/
会匹配 0 个或多个文件目录。例如,a/**/b
会匹配a/b
,a/x/b
,a/x/y/b
等- 其他的双星号会被当做一般的字符进行匹配
- 感叹号
!
前缀会将 pattern 反转。任意之前被排除的文件会被重新包含进来。如果文件的父目录被派出了,那么这个文件就不能被重新包含了。
以上内容翻译自参考资料【1】,参考时间是2021.1.1, utc+8。文档网页可能随时间发生改动,如实践过程中发现了与上述内容不符的事件,可以前往官方页面参考。
在 github 上随手一搜,就可以看到一堆的 emacs.d,目前看到的最多 star 的就是purcell/emacs.d,在他下面的还有 redguardtoo/emacs.d,seagle0128/.emacs.d 等等。
把这些 repo 的 .gitignore
全部贴过来有点太占位置了,我还是把它们都有的 pattern 拿过来简单的做一下说明算了。
经过综合和相当程度的简化,得到了如下的 pattern:
/auto-save-list
/elpa
/elpa-*
elpa/
*~
/recentf
\#*
*.elc
/history
其中最好理解的就是 *~
。如果没有关闭 make-backup-files的话,在编辑完一个文件后,emacs 会保留一个副本,名字是在原文件名后面加上 ~
。使用 pattern *~
可以将其忽略。
/elpa 是忽略掉下载的插件,elpa 一般是放置插件的文件夹。上面也可以看到 elpa/
的写法。
/auto-save-list
, /recentf
和 /history
是 emacs 生成的文件夹,存放一些文件,它们不属于配置文件。
\#~
是忽略掉以 # 开头的文件,它们一般是编辑时临时存在的文件。
就像我在开头说的那样,gitignore 对已被跟踪的文件是不起作用的。那么这时候应该如何处理呢?
参考【2】给出了解决方式
对于被跟踪的文件,可以执行以下命令来取消跟踪:
git rm --cached <file>
对于一整个文件夹,可以加上 -r 参数:
git rm -r --cached <folder>
随后的 add 就不会包含在 gitignore
中标明的 pattern 所匹配的文件了。
嫌麻烦的话也可以这样:
git rm -r --cached .
git add .
git commit -m "fixed untracked files"
github 上有个叫做 gitignore 的项目【3】,里面列举了许多语言的 .gitignore,可以利用它来进一步了解更多的例子。
比如上面的 scheme 对应的 .gitignore 就是这样写的:
*.ss~
*.ss#*
.#*.ss
*.scm~
*.scm#*
.#*.scm
【1】 Git - gitignore Documentation (git-scm.com): https://git-scm.com/docs/gitignore
【2】 How to make Git "forget" about a file that was tracked but is now in .gitignore? - Stack Overflow: https://stackoverflow.com/questions/1274057/how-to-make-git-forget-about-a-file-that-was-tracked-but-is-now-in-gitignore
【3】 github/gitignore: A collection of useful .gitignore templates: https://github.com/github/gitignore