在使用Git的過(guò)程中,我們喜歡有的文件比如日志,臨時(shí)文件,編譯的中間文件等不要提交到代碼倉(cāng)庫(kù),這時(shí)就要設(shè)置相應(yīng)的忽略規(guī)則,來(lái)忽略這些文件的提交。簡(jiǎn)單來(lái)說(shuō)一個(gè)場(chǎng)景:在你使用git add .的時(shí)候,遇到了把你不想提交的文件也添加到了緩存中去的情況,比如項(xiàng)目的本地配置信息,如果你上傳到Git中去其他人pull下來(lái)的時(shí)候就會(huì)和他本地的配置有沖突,所以這樣的個(gè)性化配置文件我們一般不把它推送到git服務(wù)器中,但是又為了偷懶每次添加緩存的時(shí)候都想用git add .而不是手動(dòng)一個(gè)一個(gè)文件添加,該怎么辦呢?很簡(jiǎn)單,git為我們提供了一個(gè).gitignore文件只要在這個(gè)文件中申明那些文件你不希望添加到git中去,這樣當(dāng)你使用git add .的時(shí)候這些文件就會(huì)被自動(dòng)忽略掉。
有三種方法可以實(shí)現(xiàn)忽略Git中不想提交的文件:
- 在Git項(xiàng)目中定義.gitignore文件
對(duì)于經(jīng)常使用Git的朋友來(lái)說(shuō),.gitignore配置一定不會(huì)陌生。這種方式通過(guò)在項(xiàng)目的某個(gè)文件夾下定義.gitignore文件,在該文件中定義相應(yīng)的忽略規(guī)則,來(lái)管理當(dāng)前文件夾下的文件的Git提交行為。.gitignore 文件是可以提交到公有倉(cāng)庫(kù)中,這就為該項(xiàng)目下的所有開(kāi)發(fā)者都共享一套定義好的忽略規(guī)則。在.gitingore 文件中,遵循相應(yīng)的語(yǔ)法,在每一行指定一個(gè)忽略規(guī)則。如:
*.log
*.temp
/vendor
- 在Git項(xiàng)目的設(shè)置中指定排除文件
這種方式只是臨時(shí)指定該項(xiàng)目的行為,需要編輯當(dāng)前項(xiàng)目下的 .git/info/exclude文件,然后將需要忽略提交的文件寫(xiě)入其中。需要注意的是,這種方式指定的忽略文件的根目錄是項(xiàng)目根目錄。
- 定義Git全局的 .gitignore 文件
除了可以在項(xiàng)目中定義 .gitignore 文件外,還可以設(shè)置全局的git .gitignore文件來(lái)管理所有Git項(xiàng)目的行為。這種方式在不同的項(xiàng)目開(kāi)發(fā)者之間是不共享的,是屬于項(xiàng)目之上Git應(yīng)用級(jí)別的行為。這種方式也需要?jiǎng)?chuàng)建相應(yīng)的 .gitignore 文件,可以放在任意位置。然后在使用以下命令配置Git:
# git config --global core.excludesfile ~/.gitignore
首先要強(qiáng)調(diào)一點(diǎn),這個(gè)文件的完整文件名就是".gitignore",注意最前面有個(gè)“.”。一般來(lái)說(shuō)每個(gè)Git項(xiàng)目中都需要一個(gè)“.gitignore”文件,這個(gè)文件的作用就是告訴Git哪些文件不需要添加到版本管理中。實(shí)際項(xiàng)目中,很多文件都是不需要版本管理的,比如Python的.pyc文件和一些包含密碼的配置文件等等。這個(gè)文件的內(nèi)容是一些規(guī)則,Git會(huì)根據(jù)這些規(guī)則來(lái)判斷是否將文件添加到版本控制中。
Git忽略文件的原則
- 忽略操作系統(tǒng)自動(dòng)生成的文件,比如縮略圖等;
- 忽略編譯生成的中間文件、可執(zhí)行文件等,也就是如果一個(gè)文件是通過(guò)另一個(gè)文件自動(dòng)生成的,那自動(dòng)生成的文件就沒(méi)必要放進(jìn)版本庫(kù),比如Java編譯產(chǎn)生的.class文件;
- 忽略你自己的帶有敏感信息的配置文件,比如存放口令的配置文件。
.gitignore文件的使用方法
首先,在你的工作區(qū)新建一個(gè)名稱為.gitignore的文件。
然后,把要忽略的文件名填進(jìn)去,Git就會(huì)自動(dòng)忽略這些文件。
不需要從頭寫(xiě).gitignore文件,GitHub已經(jīng)為我們準(zhǔn)備了各種配置文件,只需要組合一下就可以使用了。
有時(shí)對(duì)于git項(xiàng)目下的某些文件,我們不需要納入版本控制,比如日志文件或者IDE的配置文件,此時(shí)可以在項(xiàng)目的根目錄下建立一個(gè)隱藏文件 .gitignore(linux下以.開(kāi)頭的文件都是隱藏文件),然后在.gitignore中寫(xiě)入需要忽略的文件。
有時(shí)對(duì)于git項(xiàng)目下的某些文件,我們不需要納入版本控制,比如日志文件或者IDE的配置文件,此時(shí)可以在項(xiàng)目的根目錄下建立一個(gè)隱藏文件 .gitignore(linux下以.開(kāi)頭的文件都是隱藏文件),然后在.gitignore中寫(xiě)入需要忽略的文件。
[root@kevin ~]# cat .gitignore
*.xml
*.log
*.apk
.gitignore注釋用'#', *表示匹配0個(gè)或多個(gè)任意字符,所以上面的模式就是要忽略所有的xml文件,log文件和apk文件。
.gitignore配置文件用于配置不需要加入版本管理的文件,配置好該文件可以為版本管理帶來(lái)很大的便利。
.gitignore忽略規(guī)則的優(yōu)先級(jí)
在 .gitingore 文件中,每一行指定一個(gè)忽略規(guī)則,Git檢查忽略規(guī)則的時(shí)候有多個(gè)來(lái)源,它的優(yōu)先級(jí)如下(由高到低):
- 從命令行中讀取可用的忽略規(guī)則
- 當(dāng)前目錄定義的規(guī)則
- 父級(jí)目錄定義的規(guī)則,依次遞推
- $GIT_DIR/info/exclude 文件中定義的規(guī)則
- core.excludesfile中定義的全局規(guī)則
.gitignore忽略規(guī)則的匹配語(yǔ)法
在 .gitignore 文件中,每一行的忽略規(guī)則的語(yǔ)法如下:
1)空格不匹配任意文件,可作為分隔符,可用反斜杠轉(zhuǎn)義
2)以“#”開(kāi)頭的行都會(huì)被 Git 忽略。即#開(kāi)頭的文件標(biāo)識(shí)注釋,可以使用反斜杠進(jìn)行轉(zhuǎn)義。
3)可以使用標(biāo)準(zhǔn)的glob模式匹配。所謂的glob模式是指shell所使用的簡(jiǎn)化了的正則表達(dá)式。
4)以斜杠"/"開(kāi)頭表示目錄;"/"結(jié)束的模式只匹配文件夾以及在該文件夾路徑下的內(nèi)容,但是不匹配該文件;"/"開(kāi)始的模式匹配項(xiàng)目跟目錄;如果一個(gè)模式不包含斜杠,則它匹配相對(duì)于當(dāng)前 .gitignore 文件路徑的內(nèi)容,如果該模式不在 .gitignore 文件中,則相對(duì)于項(xiàng)目根目錄。
5)以星號(hào)""通配多個(gè)字符,即匹配多個(gè)任意字符;使用兩個(gè)星號(hào)"*" 表示匹配任意中間目錄,比如a/**/z
可以匹配 a/z, a/b/z 或 a/b/c/z等。
6)以問(wèn)號(hào)"?"通配單個(gè)字符,即匹配一個(gè)任意字符;
7)以方括號(hào)"[]"包含單個(gè)字符的匹配列表,即匹配任何一個(gè)列在方括號(hào)中的字符。比如[abc]表示要么匹配一個(gè)a,要么匹配一個(gè)b,要么匹配一個(gè)c;如果在方括號(hào)中使用短劃線分隔兩個(gè)字符,表示所有在這兩個(gè)字符范圍內(nèi)的都可以匹配。比如[0-9]表示匹配所有0到9的數(shù)字,[a-z]表示匹配任意的小寫(xiě)字母)。
8)以嘆號(hào)"!"表示不忽略(跟蹤)匹配到的文件或目錄,即要忽略指定模式以外的文件或目錄,可以在模式前加上驚嘆號(hào)(!)取反。需要特別注意的是:如果文件的父目錄已經(jīng)被前面的規(guī)則排除掉了,那么對(duì)這個(gè)文件用"!"規(guī)則是不起作用的。也就是說(shuō)"!"開(kāi)頭的模式表示否定,該文件將會(huì)再次被包含,如果排除了該文件的父級(jí)目錄,則使用"!"也不會(huì)再次被包含。可以使用反斜杠進(jìn)行轉(zhuǎn)義。
需要謹(jǐn)記:git對(duì)于.ignore配置文件是按行從上到下進(jìn)行規(guī)則匹配的,意味著如果前面的規(guī)則匹配的范圍更大,則后面的規(guī)則將不會(huì)生效;
.gitignore忽略規(guī)則簡(jiǎn)單說(shuō)明
# 表示此為注釋,將被Git忽略
*.a 表示忽略所有 .a 結(jié)尾的文件
!lib.a 表示但lib.a除外
/TODO 表示僅僅忽略項(xiàng)目根目錄下的 TODO 文件,不包括 subdir/TODO
build/ 表示忽略 build/目錄下的所有文件,過(guò)濾整個(gè)build文件夾;
doc/*.txt 表示會(huì)忽略doc/notes.txt但不包括 doc/server/arch.txt
bin/: 表示忽略當(dāng)前路徑下的bin文件夾,該文件夾下的所有內(nèi)容都會(huì)被忽略,不忽略 bin 文件
/bin: 表示忽略根目錄下的bin文件
/*.c: 表示忽略cat.c,不忽略 build/cat.c
debug/*.obj: 表示忽略debug/io.obj,不忽略 debug/common/io.obj和tools/debug/io.obj
**/foo: 表示忽略/foo,a/foo,a/b/foo等
a/**/b: 表示忽略a/b, a/x/b,a/x/y/b等
!/bin/run.sh 表示不忽略bin目錄下的run.sh文件
*.log: 表示忽略所有 .log 文件
config.php: 表示忽略當(dāng)前路徑的 config.php 文件
/mtk/ 表示過(guò)濾整個(gè)文件夾
*.zip 表示過(guò)濾所有.zip文件
/mtk/do.c 表示過(guò)濾某個(gè)具體文件
被過(guò)濾掉的文件就不會(huì)出現(xiàn)在git倉(cāng)庫(kù)中(gitlab或github)了,當(dāng)然本地庫(kù)中還有,只是push的時(shí)候不會(huì)上傳。
需要注意的是,gitignore還可以指定要將哪些文件添加到版本管理中,如下:
!*.zip
!/mtk/one.txt
唯一的區(qū)別就是規(guī)則開(kāi)頭多了一個(gè)感嘆號(hào),Git會(huì)將滿足這類規(guī)則的文件添加到版本管理中。為什么要有兩種規(guī)則呢?
想象一個(gè)場(chǎng)景:假如我們只需要管理/mtk/目錄中的one.txt文件,這個(gè)目錄中的其他文件都不需要管理,那么.gitignore規(guī)則應(yīng)寫(xiě)為::
/mtk/*
!/mtk/one.txt
假設(shè)我們只有過(guò)濾規(guī)則,而沒(méi)有添加規(guī)則,那么我們就需要把/mtk/目錄下除了one.txt以外的所有文件都寫(xiě)出來(lái)!
注意上面的/mtk/*不能寫(xiě)為/mtk/,否則父目錄被前面的規(guī)則排除掉了,one.txt文件雖然加了!過(guò)濾規(guī)則,也不會(huì)生效!
----------------------------------------------------------------------------------
還有一些規(guī)則如下:
fd1/*
說(shuō)明:忽略目錄 fd1 下的全部?jī)?nèi)容;注意,不管是根目錄下的 /fd1/ 目錄,還是某個(gè)子目錄 /child/fd1/ 目錄,都會(huì)被忽略;
/fd1/*
說(shuō)明:忽略根目錄下的 /fd1/ 目錄的全部?jī)?nèi)容;
/*
!.gitignore
!/fw/
/fw/*
!/fw/bin/
!/fw/sf/
說(shuō)明:忽略全部?jī)?nèi)容,但是不忽略 .gitignore 文件、根目錄下的 /fw/bin/ 和 /fw/sf/ 目錄;注意要先對(duì)bin/的父目錄使用!規(guī)則,使其不被排除
溫馨提示:
如果你不慎在創(chuàng)建.gitignore文件之前就push了項(xiàng)目,那么即使你在.gitignore文件中寫(xiě)入新的過(guò)濾規(guī)則,這些規(guī)則也不會(huì)起作用,Git仍然會(huì)對(duì)所有文件進(jìn)行版本管理。簡(jiǎn)單來(lái)說(shuō)出現(xiàn)這種問(wèn)題的原因就是Git已經(jīng)開(kāi)始管理這些文件了,所以你無(wú)法再通過(guò)過(guò)濾規(guī)則過(guò)濾它們。所以大家一定要養(yǎng)成在項(xiàng)目開(kāi)始就創(chuàng)建.gitignore文件的習(xí)慣,否則一單push,處理起來(lái)會(huì)非常麻煩。
.gitignore忽略規(guī)則常用示例