$HOME/.gitignore_global
, $HOME/.config/git/ignore
, $GIT_DIR/info/exclude
, .gitignore
這些地方指定的ignore規則都會在Git倉庫中生效一個.gitignore
文件顯式地指定了哪些文件不該被Git追蹤,即被Git忽略掉。在被gitignore以前已經被Git追蹤的文件不受gitignore規則的影響。關於gitignore規則的詳情請繼續往下看。html
.gitignore
文件中的每一行都指定了一種匹配模式。一般來講,Git會從多個可能的規則源獲取gitignore
規則來決定Git是否要忽略某一個具體的路徑path,以下按照優先級列出了各類規則源,越靠前的規則優先級越高(在一個規則源內部,若是有多個gitignore
匹配,以最後匹配的爲準)linux
.gitignore
文件,或者父級目錄的.gitignore
中定義的規則。其中,越靠近具體路徑的.gitignore
文件的優先級越高,同目錄下的.gitignore
文件優先級最高。項目倉庫中一般都有.gitignore
文件,裏面會包含忽略項目build自動生成的文件的規則$GIT_DIR/info/exclude
中定義的規則core.excludeFile
指定的規則具體講gitignore規則定義在哪一個文件中取決於該規則的做用(域):git
gitignore
規則應該被Git追蹤,別人clone倉庫後規則也生效,那麼它就應該被定義在.gitignore
文件中$GIT_DIR/info/exclude
中吧gitignore
規則要在任何狀況下都生效,這種規則最好放在core.excludesFile
這一變量中,這個變量定義在用戶目錄下-~/.gitconfig
,該變量的默認值是$XDG_CONFIG_HOME/git/ignore
,若是$XDG_CONFIG_HOME
是空的,Git會使用$HOME/.config/git/ignore
Git的底層管道工具,好比git ls-files
和git read-tree
,只從命令行參數||命令行參數指定的文件中讀取gitignore
規則。上層的Git工具,好比git status
和git add
,會從上述規則源中讀取gitignore
規則shell
gitignore
規則的可讀性#
開頭。能夠在#
前加一個反斜槓轉義之,使之可以匹配包含#字符
的文件夾或文件!
前綴來否認以前的規則。若是一個文件被前面的gitignore
規則給匹配到了,那麼該文件不會被Git追蹤,可是若是後面的規則使用!
匹配到了該文件,那麼該文件又會被Git追蹤。固然,若是一個文件的父目錄都被Git忽略了,那麼不管如何,這個文件都不會被Git追蹤。出於性能考慮,Git不會遍歷被忽略的目錄,所以,定義在被忽略目錄下的gitignore
規則都是無效的。有時候,咱們真的是想忽略以感嘆號!
開頭的一個文件或者目錄,這時,能夠在感嘆號!
前面加一個反斜槓轉義之,好比:\!important.txt
會匹配文件!important.txt
foo/
會匹配到目錄foo
和foo
下的子目錄,但不會匹配到文件foo
或者軟連接foo
/
,Git就會就會把該規則當成通配符規則來進行處理,從該規則所在.gitignore
文件所在路徑開始匹配。固然,若是這個規則不是放在.gitignore
文件中的,就會從work tree
的頂部開始匹配FNM_PATHNAME
標記的fnmatch(3)規則進行解析。可是,規則中的通配符不會匹配路徑名中的斜槓/
。舉個栗子,Documentation/*.html
匹配Documentation/git.html
,但不會匹配Documentation/ppc/ppc.html
或者tools/perf/Documentation/perf.html
/*.c
匹配cat-file.c
,但不匹配mozilla-sha1/sha1.c
兩個連續的星號**
在匹配全路徑名的時候可能有特殊含義:bash
**
開頭,後接一個斜槓,這樣的規則會在全部路徑或子路徑中嘗試進行匹配。好比,**/foo
會匹配到文件foo
或者目錄foo
,不管它在哪一個目錄;foo
這條規則一樣會嘗試匹配全部路徑中的文件foo
或者目錄foo
。**/foo/bar
規則會匹配任意文件或目錄foo
下直接跟的文件bar
或目錄bar
**
,那這條規則會匹配下面的全部東西。好比abc/**
會匹配目錄abc
下的全部文件或目錄,固然,這裏的目錄abc
是相對於.gitignore
文件位置而言的,無限遞歸斜槓/
後跟兩個星號,而後再跟一個斜槓的形式,這裏的兩個星號就會匹配0+
個目錄,這裏的0+
是指能夠沒有,也能夠是多個。再舉個例子,好比a/**/b
會匹配a/b
、a/x/b
、a/x/y/b
這些gitignore文件的目的是確保某些不該該被Git追蹤的文件確實沒有被track。若是要中止track一個已經被Git追蹤的文件,請使用git rm --cached Xxx
命令工具
$ git status
[...]
# 暫未被Git追蹤的文件:
[...]
# Documentation/foo.html
# Documentation/gitignore.html
# file.o
# lib.a
# src/internal.o
[...]
$ cat .git/info/exclude
# 忽略,即再也不追蹤倉庫中全部的objects和壓縮文件.
*.[oa]
$ cat Documentation/.gitignore
# 忽略自動生成的html文件,
*.html
# 排除手動維護的foo.html,即不忽略foo.html,即Git會追蹤foo.html
!foo.html
$ git status
[...]
# 暫未被Git追蹤的文件:
[...]
# Documentation/foo.html
[...]
複製代碼
一個例子不夠,再來一個:性能
$ cat .gitignore
vmlinux*
$ ls arch/foo/kernel/vm*
arch/foo/kernel/vmlinux.lds.S
$ echo '!/vmlinux*' > arch/foo/kernel/.gitignore
複製代碼
在這個例子中,第二個.gitignore文件arch/foo/kernel/.gitignore
的優先級更高,它阻止了第一個.gitignore文件試圖忽略arch/foo/kernel/vmlinux.lds.S
的行爲,從而,Git不會忽略arch/foo/kernel/vmlinux.lds.S
,會嘗試追蹤它ui
最後再來一個例子收尾。舉個忽略目錄下全部文件或目錄,除了某個特定的目錄foo/bar
的例子吧(注意下面的/*
,就算沒有前面的斜槓,通配符也會匹配包括foo/bar
在內的全部文件或目錄,因此斜槓/
是無關緊要的):spa
$ cat .gitignore
# exclude everything except directory foo/bar
/*
!/foo
/foo/*
!/foo/bar
複製代碼
譯文到此完畢,我再補充幾個小例子吧命令行