git 的 .gitignore 配置

如果你正在使用 git 做版本管理,想必对 .gitignore 文件并不会陌生 .gitignore 配置文件用于配置不需要加入版本管理的文件,配置好该文件可以为我们的版本管理带来很大的便利。

配置语法:

  • 以斜杠“/”开头表示目录;
  • 以星号“*”通配多个字符;
  • 以问号“?”通配单个字符;
  • 以方括号“[]”包含单个字符的匹配列表;
  • 以叹号“!”表示不忽略(跟踪)匹配到的文件或目录;

此外,git 对于 .gitignore 配置文件是按行从上到下进行规则匹配的,这意味着如果前面的规则匹配的范围更大,则后面的规则将不会生效。

规则示例与说明:

  1. 规则:

    1
    fd1/*

    说明:忽略目录 fd1 下的全部内容;注意,不管是根目录下的 /fd1/ 目录,还是某个子目录 /child/fd1/ 目录,都会被忽略。

  2. 规则:

    1
    /fd1/*

    说明:忽略根目录下的 /fd1/ 目录的全部内容。

  3. 规则:

    1
    2
    3
    4
    5
    6
    7
    /*

    !.gitignore

    !/fw/bin/

    !/fw/sf/

    说明:忽略全部内容,但是不忽略 .gitignore 文件、根目录下的 /fw/bin/ 和 /fw/sf/ 目录。

范例:

  1. 忽略.o和.a文件

    1
    *.[oa]
  2. 忽略.b和.B文件,my.b除外

    1
    2
    3
    *.[bB]

    !my.b
  3. 忽略dbg文件和dbg目录

    1
    dbg
  4. 只忽略dbg目录,不忽略dbg文件

    1
    dbg/
  1. 只忽略dbg文件,不忽略dbg目录
    1
    2
    dbg
    !dbg/
  1. 只忽略当前目录下的dbg文件和目录,子目录的dbg不在忽略范围内

    1
    /dbg

为什么我增加了.gitignore文件, 但是里面的规则却没有生效?

这是因为我们误解了.gitignore文件的用途,该文件只能作用于 Untracked Files,也就是那些从来没有被 git 记录过的文件(自添加以后,从未被 add 及 commit 过的文件)。

之所以你的规则不生效,是因为那些文件曾经被 git 记录过,因此 .gitignore 对它们完全无效。

所以如果你不慎在创建 .gitignore 文件之前就 push 了项目,那么即使你在 .gitignore 文件中写入新的过滤规则,这些规则也不会起作用,git 仍然会对所有文件进行版本管理。

简单来说,出现这种问题的原因就是 git 已经开始管理这些文件了,所以你无法再通过过滤规则来过滤它们。

所以大家记得一定要养成在项目开始就创建 .gitignore 文件的习惯,否则一旦 push,处理起来会比较麻烦。

那么有没有办法解决呢?

答案是:有的。

举个栗子:

比如说现在有一个 nodejs 项目,一开始的时候就忘记了创建 .gitignore 文件忽略掉 node_modules 的内容,所以其中的内容已经被提交了。

即使你紧接着在 .gitignore 加了一行 node_modules , 已经被提交的文件是不会自动删除的。

所以这时候你就需要做的就是:

  1. 从 git 的数据库中删除对于该文件的追踪;

    1
    2
    3
    4
    git rm --cached filePath (filePath 为文件路径)

    #nodejs案例就是
    git rm --cached node_modules
  2. 把对应的规则写入 .gitignore,让忽略真正生效;

    1
    2
    3
    #nodejs案例就是在 .gitignore 文件里添加以下内容

    node_modules/
  3. 提交 + 推送。

    1
    2
    3
    #例如
    git commit -m 'delete remote some file'
    git push

.gitignore文件的妙用

.gitignore 还有个有意思的小功能, 一个空的 .gitignore 文件可以被当作是一个 placeholder 。当你需要为项目创建一个空的 log 目录时, 这就变的很有用。

例如你可以创建一个 log 目录 在里面放置一个空的 .gitignore 文件。这样当你 clone 这个 repo 的时候 git 会自动的创建好一个空的 log 目录了。(正常情况下 git 是不会推送一个空目录到 repo 的)

参考资料