2010-06-08 15 views
123

मैं एक बड़ी निर्देशिका संरचना पर एक गिटिनोर समस्या को हल करने की कोशिश कर रहा हूं, लेकिन मेरे प्रश्न को सरल बनाने के लिए मैंने इसे निम्न में घटा दिया है।गिटिग्नोर बहिष्करण नियम वास्तव में कैसे काम करते हैं?

मेरे पास एक नया Git भंडार में दो फ़ाइलें (foo, बार) (कोई अब तक करता) के निम्नलिखित निर्देशिका संरचना:

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

जाहिर है, एक 'Git स्थिति -u' से पता चलता है:

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

मैं जो करना चाहता हूं वह एक .gitignore फ़ाइल है जो/b/c के अंदर सब कुछ अनदेखा करता है लेकिन फ़ाइल 'foo' को अनदेखा नहीं करता है।

अगर मैं एक .gitignore इस प्रकार बनाने के लिए:

c/ 

फिर एक 'Git स्थिति -u' दोनों foo पता चलता है और के रूप में नजरअंदाज कर दिया बार:

# Untracked files: 
... 
#  .gitignore 

है कौन सा रूप में मैं उम्मीद करते हैं।

अब मैं foo के लिए एक अपवर्जन नियम जोड़ते हैं, इस प्रकार:

c/ 
!foo 

gitignore मैनपेज के अनुसार, मैं इस काम करने के लिए करने के लिए उम्मीद थी। लेकिन यह नहीं है - यह अभी भी ध्यान नहीं देता foo:

# Untracked files: 
... 
#  .gitignore 

यह या तो काम नहीं करता:

c/ 
!a/b/c/foo 

न तो करता है:

c/* 
!foo 

देता है:

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

उस स्थिति में, हालांकि foo अब अनदेखा नहीं है एड, बार भी अनदेखा नहीं किया जाता है।

.gitignore में नियमों का क्रम या तो कोई फर्क नहीं पड़ता।

यह भी है कि मैं क्या उम्मीद थी भी नहीं करता है: एक दोनों foo और बार पर ध्यान नहीं देता

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

है।

* 
!foo 

लेकिन इस के साथ समस्या यह है कि अंततः वहाँ एक के तहत अन्य उपनिर्देशिका होगा:

एक स्थिति है कि काम करता है अगर मैं फ़ाइल एक/बी/सी/.gitignore बना सकते हैं और वहाँ में डाल दिया है/बी/सी और मैं एक अलग .gitignore को हर एक में रखना नहीं चाहता - मैं 'प्रोजेक्ट-आधारित' बनाने की उम्मीद कर रहा था .gitignore फ़ाइलें जो प्रत्येक प्रोजेक्ट की शीर्ष निर्देशिका में बैठ सकती हैं, और सभी को कवर कर सकती हैं 'मानक' उपनिर्देशिका संरचना।

यह भी बराबर हो रहा है:

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

यह निकटतम बात है कि मैं प्राप्त कर सकते हैं "काम" हो सकता है, लेकिन पूर्ण संबंधित पथ और स्पष्ट अपवाद कहा जा करने की जरूरत है जो करने जा रहा है यदि मेरे पास उपनिर्देशिका पेड़ के विभिन्न स्तरों में नाम 'foo' की बहुत सारी फ़ाइलें हैं तो दर्द हो।

वैसे भी, या तो मैं काफी कैसे बहिष्कार नियम काम समझ में नहीं आता, या वे सब पर जब निर्देशिका (बल्कि वाइल्डकार्ड से) अनदेखी कर रहे हैं काम नहीं करते - एक नियम के एक/

में समाप्त होने से किसी को भी कर सकते हैं तो कृपया इस पर कुछ प्रकाश डाला?

क्या गिटिग्नोर इस बेकार शेल-आधारित वाक्यविन्यास के बजाय नियमित अभिव्यक्तियों की तरह कुछ समझदार उपयोग करने का कोई तरीका है?

मैं इसका उपयोग कर रहा हूं और इसे सिबविन/बैश 3 और गिट -17.1 पर उबंटू/बैश 3 पर गिट-1.6.6.1 के साथ देख रहा हूं।

+0

संबंधित प्रश्न: http://stackoverflow.com/questions/2820255/how-do-negated-patterns-work-in-gitignore/2820310#2820310 – Cascabel

उत्तर

121
/a/b/c/* 
!foo

मेरे लिए काम करने लगता है (लिनक्स पर गिट 1.7.0.4)। * महत्वपूर्ण है अन्यथा आप निर्देशिका के भीतर फ़ाइलों की बजाय निर्देशिका को अनदेखा कर रहे हैं (इसलिए गिट अंदर नहीं दिखेगा) (जो बहिष्करण के लिए अनुमति देता है)।

यह कहते हुए बहिष्करण के लगता है कि "लेकिन यह एक नहीं" के बजाय "लेकिन इस में शामिल हैं" - "इस निर्देशिका (/a/b/c/) की उपेक्षा नहीं बल्कि यह एक (foo)" ज्यादा मतलब नहीं है; "इस निर्देशिका में सभी फाइलों को अनदेखा करें (/a/b/c/*) लेकिन यह नहीं (foo)" करता है। मैन पेज को उद्धृत करने के लिए:

एक वैकल्पिक उपसर्ग! जो पैटर्न को अस्वीकार करता है; पिछले पैटर्न द्वारा छोड़ा गया कोई मिलान फ़ाइल फिर से शामिल हो जाएगी।

अर्थात, फ़ाइल पहले से ही बाहर रखा गया है करने के लिए फिर से शामिल किया जाना है। उम्मीद है कि कुछ प्रकाश बहाल करता है।

+0

हां, आपके द्वारा दिया गया उदाहरण भी मेरे लिए ठीक काम करता है। समस्या यह है कि अगर foo c में है, तो/a/b/* काम नहीं करता है, जिसका अर्थ है कि मेरे पास सी के तहत विभिन्न उपनिर्देशिकाओं में एकाधिक foo फ़ाइलें हैं (जैसे डी /, ई /, एफ/जी/एच /, i/j /, आदि) तो नकारात्मक नियम '! foo' उनको पकड़ नहीं पाएगा। – meowsqueak

+0

@meowsqueak वास्तव में यह नहीं होगा। यदि आप अनदेखा करते हैं/a/b/* तो foo के लिए निर्देशिका नहीं है! यदि आप पूरे निर्देशिका पेड़ को/ए/बी के अंतर्गत अनदेखा करने की कोशिश कर रहे हैं, लेकिन "foo" नामक कोई भी फ़ाइल शामिल करें जो पेड़ में कहीं भी हो सकती है, मुझे नहीं लगता कि यह .gitignore पैटर्न के साथ करने योग्य है: \ – Chris

+0

असल में यह समझा सकता है यह मेरे लिए क्यों काम नहीं करता है - निम्नलिखित नियम काम नहीं करते हैं: "/ a/b/*", "! c/foo"। अगर यह काम करता है, तो कोई समस्या नहीं हो सकती है। – meowsqueak

4

यह निश्चित रूप से .gitignore मैन पेज से स्पष्ट नहीं है। यह काम करता है:

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

# don't forget this one 
!.gitignore 

जैसा कि क्रिस द्वारा वर्णित है, निर्देशिका को छोड़कर भी खोला नहीं जाता है। इसलिए यदि आप अनदेखा करने में सक्षम होना चाहते हैं * लेकिन कुछ फाइलें, तो आपको उपरोक्त फ़ाइलों के लिए पथ बनाना होगा। मेरे लिए यह सुविधाजनक है, क्योंकि मैं लाइब्रेरी की 1 फ़ाइल पर कोड समीक्षा करना चाहता हूं और यदि मैं बाद में कुछ करना चाहता हूं तो मैं इसे जोड़ता हूं, और बाकी सब कुछ अनदेखा कर दिया जाता है।

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

कि हर फ़ाइल और निर्देशिका, सिवाय फ़ाइलें/निर्देशिका तीन स्तरों एक भीतर गहरे उपेक्षा होगा:

6

यहाँ एक और विकल्प है। अगर मैं ** सही ढंग से पढ़ा

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

कि मध्यवर्ती निर्देशिका के एक मनमाना संख्या के लिए काम करना चाहिए:

19

मैं एक ऐसी ही स्थिति है, मेरे समाधान का उपयोग किया गया था।

+0

में 'git add -force'' को एक हुक लिखें प्रतिभाशाली! शुक्रिया-इसने मुझे इस समस्या को दरकिनार करने में मदद की है कि मैं पिछले घंटे के लिए अपने सिर को मार रहा हूं। – Baggers

+0

बिल्कुल सही, एक आकर्षण की तरह काम करते हैं! – hungdoan

+0

अच्छा, यह मेरे लिए किया था! –

4

एक अधिक सामान्य टिप्पणी पर, git1.8.2patch (भी in its v4, prompted by some Stack Overflow question) जो gitignore नियम निर्धारित करने के बारे में Adam Spiers से वास्तव में अपनी फ़ाइल पर ध्यान नहीं देता शामिल होंगे।

git1.8.2 release notes देखती है और इसीलिए सवाल "which gitignore rule is ignoring my file":
कि आदेश git check-ignore हो जाएगा।

+0

इस जानकारी को प्रसारित करने के लिए धन्यवाद। 'चेक-अनदेखा' आपको यह भी बताएगा कि कौन सा नियम * आपकी फाइल को अनदेखा होने से रोक रहा है, अगर ऐसा है। –

+0

@AdamSpiers महान लगता है। मुझे यकीन है कि इसके साथ खेलना होगा। – VonC

संबंधित मुद्दे