2011-03-20 19 views
4

我正在將我的Mercurial存儲庫轉換爲Git。部分文件系統如下所示:如何在.gitignore中獲得.hgignore的正則表達式^ var /(?! log | .dummy)和^ var/log /(?!。dummy)的等效項?

|-- .gitignore 
|-- .hgignore 
`-- var 
    |-- .dummy 
    |-- asdf 
    `-- log 
     |-- .dummy 
     `-- asdf 

我的.hgignore文件使用正則表達式。我.hgignore文件的部分如下:

^var/(?!\log|.dummy) 
^var/log/(?!\.dummy) 

我要跟蹤的.dummy文件,但不是asdf文件。 hg status回報:

? var/.dummy 
? var/log/.dummy 

如何在.gitignore中獲得相同的效果?我曾嘗試以下方法:

/var/**/* 
!/var/.dummy 
!/var/log/.dummy 

但是,根據需要,這不會忽略var/asdf。如何跟蹤var/.dummyvar/log/.dummy並忽略var/asdfvar/log/asdf

+0

'**'在Git排除模式中沒有特殊含義。它的結尾與'*'的意思相同(並不意味着「在任何深度匹配以下內容」)。 – 2011-03-20 08:44:52

回答

10

如果你只使用.dummy文件佔位符,以確保您始終獲得那些特定的(幾乎是空的)目錄,當你做出一個乾淨的檢出,那麼你或許應該只是排除/var和使用git add -f var/.dummy var/log/.dummy開始明確地跟蹤佔位符文件。有效的結果是,除了您明確跟蹤的.dummy文件外,您將忽略所有內容。另一方面,如果你打算擴展幾乎空目錄的層次結構,而不僅僅是var/log,那麼你可能會利用一些解釋。

規則在gitignore(5)中描述,但有時很難理解所有規則以及它們如何相互作用。重要的部分是最後一條規則獲勝,而後面的規則只有在它們所作用的目錄尚未被完全忽略時纔會有效。這意味着如果你忽略了目錄,你必須取消管理它們,然後才能取消它們的一些內容(同時重新忽略其內容的其餘部分)。


如果你想自動忽略var下,除了.dummy文件的一切,那麼這樣做的最簡單的方法涉及到把一個.gitignore文件在您var目錄,而不是在頂層做的。我在另一個SO answer中描述了這個解決方案。

# var/.gitignore 
* 
!/.gitignore 
!.dummy 
!*/ 
  1. 忽略這個目錄(var)的一切。
  2. 但是,不要忽略這一項的.gitignore文件(如果你願意做git add -f開始跟蹤此.gitignore文件,你可以離開了這一點)。
  3. 此外,不要忽略位於此目錄(var)的層次結構中任意深度的.dummy文件。
  4. 此外,不要忽略此目錄下任何深度的任何目錄(var)。
    沒有這個規則,第一條規則會忽略子目錄,Git甚至永遠不會打開它們來查找.dummy文件。

最後兩個模式是「遞歸」,因爲他們不具有非尾隨斜線(這意味着*將除了其它字符匹配斜線)。尾部斜線使模式僅匹配目錄。 Leading和嵌入的斜槓有效地將模式錨定到.gitignore文件的位置(或來自其他排除文件的模式的存儲庫的根目錄)。這個想法是,一個普通的*.o應該匹配任何地方,但dir/*.o應該只匹配直接在dir下的項目(並且我們可以使用/*.o來處理dir/.gitignore中的後一個效果)。


如果你不能忍受一個var/.gitinore文件,那麼你仍然可以做你問什麼,但你不能自動「屏蔽」新.dummy文件下var的任何地方,而無需編輯排除模式。

# .gitignore at root of repository 
/var/* 
!/var/.dummy 

!/var/log/ 
/var/log/* 
!/var/log/.dummy 
  1. 忽略var目錄,它是此.gitignore文件的同級下的一切。
  2. 但是,不要忽視var/.dummy
  3. 此外,不要忽略目錄var/log
  4. 但是,在var/log中直接忽略所有內容。
  5. 但是,請不要忽略var/log/.dummy

的模式是:屏蔽一個有趣的目錄(跳過這是第一次,因爲一切都是「不可忽視的」默認情況下),忽略了什麼是目錄,屏蔽了.dummy文件在裏面。對層次結構的每個更深層部分重複該模式。

您可以*替代log,使之成爲任何目錄直屬var工作,但它不會自動爲更深層次的目錄(例如,其將工作var/cache/.dummy,而不是var/log/ssh/.dummy)工作。這是因爲我們使用了非尾隨斜線並錨定了模式。要手動使其工作,必須重複該模式以爲更深層的部分生成更多的排除規則(忽略有趣的目錄,忽略目錄的內容,忽略文件)。

2

你不需要用正則表達式排除.dummy。只需忽略所有內容,然後手動添加所有.dummy

忽略僅影響狀態命令結果。

+0

我喜歡「只是忽略所有內容和'git add -f'佔位符」的主意,但排除模式不僅僅影響status命令(例如'git add --all')。 – 2011-03-20 08:58:51