2012-05-02 8 views
97

git grep का उपयोग कर गिट रिपॉजिटरी खोजने का कोई तरीका है लेकिन खोज से कुछ पथ/निर्देशिका/फ़ाइलों को बाहर कर दें? सामान्य grep कमांड में --exclude विकल्प की तरह।गिट grep खोज से कुछ निर्देशिका/फ़ाइलों को बाहर करने के लिए कैसे करें

यदि आप उत्सुक हैं: मैं सामान्य grep का उपयोग नहीं करना चाहता क्योंकि यह git grep से धीमा है जब गिट भंडार का आकार बड़ा है।

+0

इसे बैश पर करना संभव कामकाज होगा: http://stackoverflow.com/questions/216995/how-can-i-use-inverse-or-negative-wildcards-when-pattern-matching-in-a -unix-linu –

+5

यह सुविधा 1.9.0 में जोड़ा गया था [नीचे मेरा जवाब देखें] (/ a/30084612/436287) – onlynone

उत्तर

16

यह संभव नहीं है, लेकिन has been discussed recently। लिंक में प्रस्तावित वर्कअराउंड:

आपपर .gitignore फ़ाइल को git grep --exclude-standard डाल सकते हैं।

संपादित करें केवल एक जवाब देखें, क्योंकि गिट 1.9.0 यह संभव है।

+0

कोई विचार अगर यह अभी भी संभव नहीं है? या पिछले 2+ सालों में कुछ बदल गया है? –

+3

@ mustafa.0x सबसे ऊपर जवाब देने वाला उत्तर देखें, यह संभव है – CharlesB

+1

केवल किसी के जवाब की जांच करें, संभवतः यह पूरी तरह से गिट के भीतर ऐसा करने के लिए संभव है। – David

54

अद्यतन: गिट के लिए> = 1.9 पैटर्न को बाहर करने के लिए मूल समर्थन है, onlyone's answer देखें।

यह पीछे की ओर लग सकता है, लेकिन आप इस तरह git grep करने के लिए अपने को बाहर पैटर्न मिलान नहीं फ़ाइलों की एक सूची पारित कर सकते हैं:

git grep <pattern> -- `git ls-files | grep -v <exclude-pattern>` 

grep -v रिटर्न हर पथ नहीं<exclude-pattern> मिलान। ध्यान दें कि git ls-files भी --exclude पैरामीटर लेता है, लेकिन यह केवल अनचाहे फ़ाइलों पर लागू होता है।

+0

इसके लिए धन्यवाद! गिट grep एएके और सह से बहुत तेज है लेकिन मनमाने ढंग से पथ को बाहर करने में सक्षम नहीं होने के कारण थोड़ा असुविधाजनक था :) –

+1

दुर्भाग्यवश मेरे रेपो में बहुत सी फाइलें हैं। जब मैं @ kynan के दृष्टिकोण को आज़माता हूं तो मुझे मिलता है: "-बैश:/usr/bin/git: तर्क सूची बहुत लंबी है" – Benissimo

+1

यह बेनिसिमो की "तर्क सूची बहुत लंबी" समस्या और बैश द्वारा व्याख्या किए गए फ़ाइल नाम कैरेक्टर के साथ मेरी समस्या को हल करना चाहिए (जैसे []) या भंडार में रिक्त स्थान वाले फ़ाइल नाम: git ls-files | grep -v | xargs -d '\ n' git grep - – Scout

2

@kynan आधार के रूप में उदाहरण के साथ मैंने इस स्क्रिप्ट को बनाया और इसे मेरे पथ (~/bin/) में gg के रूप में रखा। यह git grep का उपयोग करता है लेकिन कुछ निर्दिष्ट फ़ाइल प्रकारों से बचाता है।

हमारे रेपो में इसकी बहुत सारी छवियां हैं इसलिए मैंने छविफाइल को बाहर रखा है, और अगर मैं पूरे रेपो को खोजता हूं तो यह serchtime को 1/3 तक ले जाता है। लेकिन स्क्रिप्ट आसानी से अन्य filestypes या geleralpatterns को बाहर करने के लिए संशोधित किया जा सकता है।

$ git gg searchstring 

लेकिन मैं कर सकते हैं:

#!/bin/bash                  
#                    
# Wrapper of git-grep that excludes certain filetypes.       
# NOTE: The filetypes to exclude is hardcoded for my specific needs.   
#                    
# The basic setup of this script is from here:         
# https://stackoverflow.com/a/14226610/42580         
# But there is issues with giving extra path information to the script   
# therefor I crafted the while-thing that moves path-parts to the other side 
# of the '--'.                 

# Declare the filetypes to ignore here           
EXCLUDES="png xcf jpg jpeg pdf ps"            

# Rebuild the list of fileendings to a good regexp        
EXCLUDES=`echo $EXCLUDES | sed -e 's/ /\\\|/g' -e 's/.*/\\\.\\\(\0\\\)/'`  

# Store the stuff that is moved from the arguments.        
moved=                   

# If git-grep returns this "fatal..." then move the last element of the   
# arg-list to the list of files to search.          
err="fatal: bad flag '--' used after filename"         
while [ "$err" = "fatal: bad flag '--' used after filename" ]; do    
    {                   
     err=$(git grep "[email protected]" -- `git ls-files $moved | grep -iv "$EXCLUDES"` \ 
      2>&1 1>&3-)               
    } 3>&1                  

    # The rest of the code in this loop is here to move the last argument in 
    # the arglist to a separate list $moved. I had issues with whitespace in 
    # the search-string, so this is loosely based on:       
    # http://www.linuxjournal.com/content/bash-preserving-whitespace-using-set-and-eval 
    x=1                   
    items=                  
    for i in "[email protected]"; do               
     if [ $x -lt $# ]; then             
      items="$items \"$i\""            
     else                 
      moved="$i $moved"             
     fi                  
     x=$(($x+1))                
    done                  
    eval set -- $items               
done                   
# Show the error if there was any            
echo $err                  

नोट 1

this के अनुसार यह बात git-gg नाम और की तरह एक नियमित रूप से Git आदेश के रूप में यह कॉल करने के लिए सक्षम होने के लिए संभव हो जाना चाहिए यह काम नहीं मिल रहा है। मैंने अपने ~/bin/ में स्क्रिप्ट बनाई और में git-gg सिम्लिंक बनाया।

नोट 2

आदेश के बाद से यह तो रेपो की जड़ में सक्रिय किया जाएगा एक नियमित sh Git-उर्फ में नहीं बनाया जा सकता। और वह वही नहीं है जो मैं चाहता हूं!

122

गिट 1.9.0 में "जादू शब्द" excludepathspec एस में जोड़ा गया था।तो तुम क्या कर सकते हैं अगर आप *.java मिलान को छोड़कर हर फ़ाइल में foobar लिए खोज करना चाहते:

git grep foobar -- './*' ':(exclude)*.java' 

या बाहर करने के लिए ! "संक्षिप्त रूप" का उपयोग:

git grep foobar -- './*' ':!*.java' 

ध्यान दें कि जब एक का उपयोग कर pathspec को बाहर निकालें, आपके पास कम से कम एक "समावेशी" pathspec होना चाहिए। उपर्युक्त उदाहरणों में यह ./* है (वर्तमान में वर्तमान निर्देशिका के तहत सबकुछ शामिल है)।

रेपो के शीर्ष से सबकुछ शामिल करने के लिए आप :(top) (लघु फ़ॉर्म: :/) जैसे कुछ भी उपयोग कर सकते हैं। लेकिन फिर आप शीर्ष से शुरू करने के लिए अपने बहिष्कार pathspec को भी समायोजित करना चाहते हैं: :/!*.java (अन्यथा यह केवल आपकी वर्तमान निर्देशिका के अंतर्गत *.java फ़ाइलों को बाहर कर देगा)।

pathspecgit-scm.com (या केवल git help glossary) पर दिए गए सभी "जादू शब्द" के लिए एक अच्छा संदर्भ है। किसी कारण से, kernel.org पर दस्तावेज़ वास्तव में पुराने हैं, भले ही वे अक्सर Google खोजों में पहले आते हैं।

+1

'git grep clock.gettime - './*' ':! Arch/**' ':! ड्राइवर/**' 'कई संपूर्ण निर्देशिकाओं को बाहर करने के लिए। मुझे नहीं लगता कि यह रिकर्सन को रोकता है। –

+0

लगातार उपयोग के लिए, आप बहिष्करण के साथ गिट उपनाम बना सकते हैं: 'git config alias.mygrep'! Git grep "$ @" - "$ {GIT_PREFIX}/*" ":! * जावा *" # "' । फिर बस 'git mygrep foobar'। (उपनाम [खोल # चाल] का उपयोग करना (http://stackoverflow.com/a/39523506/647002) और [वर्तमान डीआईआर] (http://stackoverflow.com/a/22039008/647002)।) – medmunds

+0

समस्या मैं नहीं कर सकता इस समाधान के साथ हल करें कि फाइलों के रिपोर्ट किए गए पथ डब्ल्यूसी रूट के सापेक्ष हैं। इसलिए, यदि मैं डब्ल्यूसी के उप-डीआईआर में हूं, तो मैं बस पाया गया फ़ाइल (जैसे) के पथ का उपयोग नहीं कर सकता (उदा। कम के लिए) लेकिन सामान्य पथों को जूनक करना है। क्या इसका कोई समाधान है (w/o खुद को मजबूर करना है)? [win7 पर git bash] – elonderin

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