2010-06-08 38 views
123

我正試圖解決大目錄結構上的gitignore問題,但爲了簡化我的問題,我將它縮小到了以下內容。gitignore排除規則如何實際工作?

我有一個全新的git倉庫兩個文件(FOO,吧)(未提交到目前爲止)以下的目錄結構:

a/b/c/foo 
a/b/c/bar 

顯然, 'git的狀態-u' 顯示:

# Untracked files: 
... 
#  a/b/c/bar 
#  a/b/c/foo 

我想要做的是創建一個.gitignore文件,忽略a/b/c中的所有內容,但不會忽略文件'foo'。

如果我創建因此的.gitignore:

c/ 

然後一個 'git的狀態-u' 同時顯示foo和bar爲忽略:

# Untracked files: 
... 
#  .gitignore 

這是我的期望。

現在,如果我添加排除規則foo的,因此:

c/ 
!foo 

按照gitignore手冊頁,我期望這工作。但事實並非如此 - 它仍然忽略富:

# Untracked files: 
... 
#  .gitignore 

這不起作用或者:

c/ 
!a/b/c/foo 

無論是做這個的:

c/* 
!foo 

給出:

# Untracked files: 
... 
#  .gitignore 
#  a/b/c/bar 
#  a/b/c/foo 

在這種情況下,儘管foo不再是無知的ed,bar也不會被忽略。

.gitignore中規則的順序似乎也不重要。

這還沒有做我所期望的:

a/b/c/ 
!a/b/c/foo 

這一個忽略這兩個foo和酒吧。這不工作

的一種情況是,如果我創建文件/ B/C /的.gitignore和擺在那裏:

* 
!foo 

但這個問題是,終究會有下,其他的子目錄/ b/c,而且我不希望將每個單獨的.gitignore放入每個項目中 - 我希望創建可以位於每個項目頂部目錄中的「基於項目」的.gitignore文件,並覆蓋所有'標準'子目錄結構。

這也似乎是等同的:

a/b/c/* 
!a/b/c/foo 

這可能是「工作」,我可以做到最接近,但完整的相對路徑和明確的例外必須指出,這是會如果我在子目錄樹的不同級別中有很多名稱爲'foo'的文件,那就太痛苦了。

總之,無論是我不太明白排除規則是如何工作的,或者他們沒有在目錄(而不是通配符)被忽略在所有的工作 - 通過在/

結束了統治任何人都可以請對此有所瞭解?

有沒有辦法讓gitignore使用像正則表達式那樣明智的東西,而不是這種笨拙的基於shell的語法?

我在github上使用git-1.6.6.1,在Ubuntu/bash3上使用Cygwin/bash3和git-1.7.1。

+0

相關問題:http://stackoverflow.com/questions/2820255/how-do-negated-patterns-work-in-gitignore/2820310#2820310 – Cascabel 2010-06-09 03:37:50

回答

121
/a/b/c/* 
!foo

似乎爲我工作(Linux上的git 1.7.0.4)。 *是重要的,否則你會忽略目錄本身(所以git不會在裏面)而不是目錄中的文件(它允許排除)。

認爲排除是「但不是這個」而不是「但包括這個」 - 「忽略此目錄(/a/b/c/)但不是這個(foo)」沒有多大意義; 「忽略此目錄中的所有文件(/a/b/c/*),但不是這個(foo)」。引用手冊頁:

可選的前綴!否定了這種模式;任何先前模式排除的匹配文件將再次包含在內。

文件已被排除已經再次被包括在內。希望能夠流露出一些光芒。

+0

是的,你給的例子也適用於我。問題是如果foo在c中,那麼/ a/b/*不起作用,這意味着如果我在c下的各個子目錄中有多個foo文件(例如d /,e /,f/g/h /,i/j /等),那麼否定規則'!foo'將不會捕獲這些規則。 – meowsqueak 2010-06-08 23:29:53

+0

@meowsqueak確實不會。如果你忽略/ a/b/*那麼沒有foo的目錄!如果你試圖忽略/ a/b目錄下的整個目錄樹,但是包含任何名爲「foo」的文件,它可以在樹中的任何位置,我認爲它不適用於.gitignore模式:\ – Chris 2010-06-08 23:37:18

+0

實際上,這可能會解釋爲什麼這對我不起作用 - 以下規則不起作用:「/ a/b/*」,「!c/foo」。如果有效,可能沒有問題。 – meowsqueak 2010-06-08 23:37:19

4

這絕對不是明確的.gitignore手冊頁。這工作:

* 
!/a 
!/a/b 
!/a/b/c 
!/a/b/c/foo 

# don't forget this one 
!.gitignore 

正如克里斯提到的一個目錄甚至不打開,如果它被排除在外。所以,如果你想能夠忽略*但是一些文件,你必須建立這些文件的路徑,如上所述。對我來說這很方便,因爲我想對庫的1個文件進行代碼審查,如果稍後我想再添加一個文件,而其他所有內容都將被忽略。

6

這裏是另一種選擇:

* 
!/a* 
!/a/* 
!/a/*/* 
!/a/*/*/* 

這會忽略所有的文件和目錄,除了文件/目錄深內的三個層次。

19

我有類似的情況,我的解決辦法是使用:

/a/**/* 
!/a/**/foo 

應該針對中間目錄任意數量的工作,如果我正確讀取**

+0

天才!謝謝你,這只是幫助我解決了在最後一個小時裏我一直在毆打我的頭的問題。 – Baggers 2012-10-09 15:29:27

+0

完美,像魅力一樣工作! – hungdoan 2016-05-24 05:01:06

+0

不錯,這是爲我做的! – 2017-09-27 10:49:23

4

在更一般的筆記,git1.8.2將包括patch(也in its v4prompted by some Stack Overflow question)從Adam Spiers有關確定哪些gitignore規則實際上忽略了你的文件。

git1.8.2 release notes和SO問題 「which gitignore rule is ignoring my file」:
這將是命令git check-ignore

+0

感謝您播放此信息。 'check-ignore'還會告訴你哪個規則可以防止你的文件被忽略,如果是這樣的話。 – 2013-03-09 19:37:57

+0

@AdamSpiers聽起來不錯。我一定會玩它。 – VonC 2013-03-09 19:50:40