Git:ignore

Nov 11, 2021

目录


ref: https://git-scm.com/docs/gitignore


命令


gitignore - Specifies intentionally untracked files to ignore


概要


$XDG_CONFIG_HOME/git/ignore, $GIT_DIR/info/exclude, .gitignore


描述


gitignore 文件用于指定 Git 应该忽略的文件。 忽略文件的修改不会被 git 跟踪。 已经被 Git 跟踪的文件不会受影响。

gitignore 文件的每一行指定一个模式。 当 Git 要决定是否应该忽略某个文件的修改,Git 会检查 gitignore 文件中指定的模式。 通常会有多个 gitignore 文件,他们有不同的优先级,优先级从高到底:

  • 通过命令行指定的模式

  • 当前目录下的 gitignore 文件中的模式,或者父目录中的模式(从当前目录开始一直到顶级目录)。 离当前目录越接近,优先级越高。 也就是说当前目录的模式优先级高于父目录中的模式。

  • 来自 $GIT_DIR/info/exclude 的模式

  • 通过 core.excludesFile 配置指定的文件中定义的模式

将模式放入哪个文件取决于模式的使用方式。

  • 想要添加到版本控制并可以通过 clone 分享给其他开发者的模式,应该放在一个 gitignore 文件中。

  • 针对特定仓库并且不想跟其他开发者共享的模式,应该放在 $GIT_DIR/info/exclude 文件中

  • 在任何情况下都希望 Git 不跟踪的模式通常通过 ~/.gitconfig 文件的 core.excludesFile 指定的文件中。 他的默认值是 $XDG_CONFIG_HOME/git/ignore,如果前一个值没有设置或者为空,那么使用 $HOME/.config/git/ignore


模式的格式


  • 空行不匹配任何文件,因此它可以用于增加文件内容可读性的分隔符。

  • 以 # 开头的行被当做注释。 Put a backslash ("") in front of the first hash for patterns that begin with a hash.

  • 行尾的空白字符会被忽略,除非使用 \ 进行转义

  • ! 前缀用于取反。 之前被当前模式排除在外的文件,使用 ! 后会被包含进来。 如果一个文件的父目录被排除在外,那么不能重新包含该文件。 可以使用 \! 字符进行转义,这通常用于排除那些以 ! 开始的路径,例如 \!important!.txt

  • / 被作为路径分隔符。 可以出现在模式的开头,中间,或者结尾。

  • 如果一个模式的开头或者中间(或者两个都有)出现了 /, 那么这个模式就匹配相对于当前 .gitignore 文件的目录层级的文件。 否则,这个模式将匹配当前目录以及子目录。

  • 如果一个模式的结尾出现 /, 那么这个模式只匹配目录,否则,将会同时匹配文件和目录。

  • 例如,模式 doc/frotz/ 匹配 doc/frotz 目录,但是不会匹配 a/doc/frotz 目录。 然而,frotz/ 匹配 frotza/frotz目录.

  • * 匹配除了 / 以外的所有。 ? 匹配任意一个字符除了 /

在匹配完整路径名的模式中,两个连续的星号可能有特殊的含义:

  • ** 出现在开始位置并跟着一个 / 意味着在所有目录中进行匹配。 例如, **/foo 匹配任何位置的 foo 文件或者目录,和 foo 含义相同。 **/foo/bar 匹配所有 bar文件或者目录,这个文件或者目录需要时 foo 目录的子文件或子目录。

  • /** 模式会匹配内部的所有文件和目录。 例如,abc/** 匹配目录 abc 中的所有文件。

  • 一个 /, 两个星号,再跟着一个 / 用于匹配零到多个目录。 例如,a/**/b 匹配 a/b, a/x/b, a/x/y/b 等等。

  • 其他连续的星号被认为是常规星号,将按照前面的规则进行匹配。


配置


可选的配置选项 core.excludesFile 指定一个文件,这个文件包含了应该被排除在外的文件模式,和 $GIT_DIR/info/exclude 相似。 除了使用 $GIT_DIR/info/exclude 文件中的模式外,还使用 exclude 文件中的模式。


Notes


gitignore 文件的目的是确保某些未被 Git 跟踪的文件保持不被跟踪。

如果需要停止跟踪那些已经被跟踪的文件,使用命令 git rm --cached.

Git does not follow symbolic links when accessing a .gitignore file in the working tree. This keeps behavior consistent when the file is accessed from the index or a tree versus from the filesystem.


例子


  • 模式 hello.*匹配所有名称以 hello. 开始的文件或者目录。 如果你想限制它仅仅匹配某个目录,而不匹配子目录,可以在这个模式之前添加一个 /, 例如 /hello.* 将只会匹配 hello.txt, hello.c,不会匹配 a/hello.java

  • 模式 foo/ 将会匹配目录 foo 和它的子目录,但是不会匹配 foo 文件。

  • 模式 doc/frotzdoc/frotz/ 是相同的。 也即是说,如果模式中间出现了 /, 那么开始的 / 可以忽略不计。

  • 模式 foo/* 匹配 foo/test.json(普通文件), foo/bar(目录), 但是不会匹配 foo/bar/hello.c

 1    $ git status
 2    [...]
 3    # Untracked files:
 4    [...]
 5    #       Documentation/foo.html
 6    #       Documentation/gitignore.html
 7    #       file.o
 8    #       lib.a
 9    #       src/internal.o
10    [...]
11    $ cat .git/info/exclude
12    # ignore objects and archives, anywhere in the tree.
13    *.[oa]
14    $ cat Documentation/.gitignore
15    # ignore generated html files,
16    *.html
17    # except foo.html which is maintained by hand
18    !foo.html
19    $ git status
20    [...]
21    # Untracked files:
22    [...]
23    #       Documentation/foo.html
24    [...]

另外一个例子:

1    $ cat .gitignore
2    vmlinux*
3    $ ls arch/foo/kernel/vm*
4    arch/foo/kernel/vmlinux.lds.S
5    $ echo '!/vmlinux*' >arch/foo/kernel/.gitignore
6

排除除了特定目录 foo/bar 之外的所有文件或者目录:

1    $ cat .gitignore
2    # exclude everything except directory foo/bar
3    /*
4    !/foo
5    /foo/*
6    !/foo/bar

END!!!


Tags