天天看點

.gitignore檔案文法和常見寫法(就看這篇就行了).gitignore檔案文法和常見寫法(就看這篇就行了)

.gitignore檔案文法和常見寫法(就看這篇就行了)

1. 文法

  • 空行會被忽略
  • 比對是區分大小寫的,如:/abc 和 /Abc 含義不同
  • #

    開頭是注釋,會被忽略
  • *

    表示0-n個字元
  • **

    兩個星含義是子目錄子子目錄等多層比對
  • ?

    比對1個字元(注意不是0-1個字元!)
  • []

    用來比對括号内的任一字元,如

    [abc]

    ,也可以在括号内加連接配接符,如

    [0-9]

    比對0至9的數
  • *~

    忽略所有以

    ~

    結尾的檔案(這種檔案通常被許多編輯器标記為臨時檔案)
  • *.[oa]

    忽略所有以".o"或".a"結尾
  • !

    表示不忽略某檔案(為什麼要特别指出不忽略? 不寫規則不就不會被忽略嗎?,這是配合使用的,比如要忽略*.log,但是要排除a.log,這種需求就需要使用!)
  • 比對規則前面别留白格,會讓規則失效。如

    一個空格Ab?.txt

    Ab?.txt

    是有差別的

注意:

  • 空目錄(包括隐藏目錄)會被忽略,無法送出追蹤
  • 如果不希望空目錄被忽略,在裡頭建.gitkeep檔案

2. 例子

2.1 前提約定

2.1.1 約定1

“目前目錄、子目錄、子子目錄…” 的表述包含的目錄是:.gitignore檔案所在的目錄,以及該目錄下的所有目錄和它們的所有子目錄及子子目錄… 總之是這顆目錄樹的所有節點。

例如:

.gitignore檔案在

/Users/stonewang/git-ignore-test/.gitignore

,即.gitignore檔案所在的目錄為

/Users/stonewang/git-ignore-test/

該表述的含義是:以

/Users/stonewang/git-ignore-test/

作為起點的所有目錄樹節點

如圖:

# 該表述包含了dir1、dir2、dir1_sub、dir1_sub2、dir1_sub_sub、dir1_sub_sub2、dir1_sub2_sub
/Users/stonewang/git-ignore-test/
														|-------.gitignore
														|
														|-------dir1
														|				|----dir1_sub
														|								|-----dir1_sub_sub
														|								|-----dir1_sub_sub2
														|				|----dir1_sub2
														|								|-----dir1_sub2_sub
														|
														|-------dir2
           
2.1.2 其他補充
  • 目錄(即檔案夾)的名字有各種表現形式,如顯示的、隐藏的、帶擴充名的和不帶擴充名的。例如:dir、.dir、dir.ext、.dir.ext
  • 檔案名的形式也各種各樣,如顯示的,隐藏的,帶擴充名的,不帶擴充名的。如file、.file、file.ext、.file.ext
  • 在.gitignore中,以 / 結尾的隻會比對目錄,不帶 / 結尾的比對檔案和目錄,注意沒有一種寫法僅比對檔案的
  • 在Mac和Windows中都不允許檔案之間重名,目錄之間重名,目錄和檔案之間重名。不區分大小寫
  • 在Mac和Windows中,目錄名都是允許帶點的,如

    dir.ext

    可以作為目錄名(看起來就像檔案的擴充名)

2.2 例子(着重看)

  • 為了表述準确,引入自創數學符号
    • (.gitignore)N 表示.gitignore檔案所在的目錄+所有子目錄包括直接或間接
    • (.gitignore)O 表示.gitignore檔案所在的目錄,不包括其任何子目錄
寫法 作用
dir/ 忽略

(.gitignore)N

中的dir目錄
/dir/ 忽略

(.gitignore)O

中的dir目錄
file 忽略

(.gitignore)N

中的file 檔案&目錄(名為file的目錄也會被忽略)
/file 忽略

(.gitignore)O

中的file檔案|目錄
*.log 忽略

(.gitignore)N

中的*.log 檔案&目錄(符合名字的目錄也将被忽略)
/dir/file 忽略

(.gitignore)O

中的dir目錄下的file檔案|目錄

/dir/Abc*

/dir/Abc*.java

/dir

忽略

(.gitignore)O

中的dir目錄下符合Abc*的目錄(不忽略dir下的檔案!)
/dir*.txt 忽略

(.gitignore)O

中的dir目錄下的符合*的子目錄下的,符合*.txt的檔案&目錄。注意是一個星,僅忽略一層,即/dir/sub/a.txt 和 /dir/sub/sub2/b.txt,僅僅忽略a.txt,不忽略b.txt,另外/dir/k.txt也不會被忽略
/dir*.txt 忽略

(.gitignore)O

中的dir目錄下的直接和間接子目錄下的,符合*.txt的檔案&目錄。兩個星号表示0-n層級的目錄

/sub

/sub/

是不等價的
親測。前者明确表示忽略目錄除掉了檔案,是以對于/sub/file是不會被忽略的。

sub/

/sub/

含義不同
前者忽略

(.gitignore)N

下的sub目錄,後者忽略

(.gitignore)O

下的sub

sub/abc/

/sub/abc/

這兩個的含義完全相同(有點奇怪,本以為前者是遞歸所有的目錄)

**/src/main/java/

src/main/java/

不等價。前者比對

(.gitignore)N

下的src/main/java/ 目錄,要滿足這個目錄的層級結構的。後者等價于

/src/main/java/

,僅僅忽略

(.gitignore)O

下的該目錄

**/src/main/file.txt

src/main/file.txt

不等價。前者比對

(.gitignore)N

下的src/main/file.txt,符合這個目錄層級結構的将會被忽略,後者等價于

/src/main/file.txt

,僅僅忽略

(.gitignore)O

下所比對的

**/dir/

dir/

是等價的。上面的例子等價這個不等價,就是因為目錄的層級數的問題導緻的

**/file.txt

file.txt

是等價的。
先後寫

!a.txt

*.txt

後面的配置覆寫前面的,導緻所有*.txt檔案都被忽略(有點奇怪,實際測試确實如此)
先後寫

*.txt

!a.txt

正确。能夠忽略除了a.txt外的檔案。
對于.gitignore檔案不在git倉庫根目錄的情況:參考特殊情況 (參考特殊情況)
  • 特殊情況
# 對于.gitignore檔案并非和git倉庫根目錄相同目錄,如下所示,git倉庫根目錄即.git所在的目錄,跟.gitignore目錄并非相同
# /sub2       忽略的是sub/sub2,并不是git根目錄的那個sub2
# sub2				忽略的也是sub/sub2,也就是說.gitignore的寫法隻能管該檔案所在的目錄及其子目錄和子子目錄...,其父目錄管不着

|---.git
|---a.txt
|---sub
|			|----.gitignore
|	 		|----b.txt
|	 		|----sub_sub
|	 		|   	|-----c.txt	
|   	|----sub2
|   				|-----test.txt		
|---sub2
	 |----x.txt
	 |----sub2_sub
	 					|------y.txt