Git grep खोज से कुछ निर्देशिकाओं / फ़ाइलों को बाहर कैसे करें


144

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

मुझे उपयोग करने की आवश्यकता है git grepक्योंकि grepबड़े गिट रिपॉजिटरी पर बहुत धीरे-धीरे सीधे रन का उपयोग करना ।


बैश पर ऐसा करना एक संभावित समाधान होगा: stackoverflow.com/questions/216995/…
Ciro Santilli Sant ash ash ash '19

8
इस फीचर को 1.9.0 में जोड़ा गया है, नीचे मेरा जवाब देखें
20

जवाबों:


17

यह संभव नहीं है, लेकिन हाल ही में चर्चा की गई है । लिंक में प्रस्तावित वर्कअराउंड:

आप *.dll.itignore फ़ाइल तब डाल सकते हैं git grep --exclude-standard

EDIT ने केवल जवाब देखा है , क्योंकि यह 1.9.0 से संभव है।


2
यह सच हुआ करता था, लेकिन अब यह संभव नहीं है। नीचे वास्तविक जवाब क्या होना चाहिए देखें: stackoverflow.com/a/30084612/1391445
user1391445

206

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

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

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

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

ध्यान दें कि g2 संस्करणों में v2.12 तक, एक बहिष्करण का उपयोग करते समय pathspec, आपके पास कम से कम एक "समावेशी" होना चाहिए pathspec। उपरोक्त उदाहरणों में यह है ./*(वर्तमान निर्देशिका के तहत सब कुछ शामिल है)। Git v2.13 में यह प्रतिबंध हटा दिया गया था और git grep foobar -- ':!*.java'बिना काम करता है ./*

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

वहाँ सभी "जादुई शब्द" एक में अनुमति के लिए एक अच्छा संदर्भ है pathspecपर git-scm.com (या बस git help glossary)। किसी कारण के लिए, कर्नेल ओआरजी पर डॉक्स वास्तव में पुराने हैं, भले ही वे अक्सर Google खोजों में पहले आते हैं।


4
git grep clock.gettime -- './*' ':!arch/**' ':!drivers/**'कई संपूर्ण निर्देशिकाओं को बाहर करने के लिए। मुझे नहीं लगता कि यह पुनरावृत्ति को रोकता है।
सिरो सेंटिल्ली 郝海东 冠状 iro i 法轮功 '

2
बार-बार उपयोग के लिए, आप बहिष्करण के साथ एक git उपनाम बना सकते हैं git config alias.mygrep '!git grep "$@" -- "${GIT_PREFIX}/*" ":!*.java*" #':। फिर बस git mygrep foobar। (उर्फ शेल # ट्रिक और करंट डायर का उपयोग करना ।)
ध्यान

समस्या मैं इस समाधान के साथ हल नहीं कर सकता है कि फ़ाइलों के सूचित पथ WC रूट के सापेक्ष हैं। इसलिए, अगर मैं WC के एक उप dir में हूँ, तो मैं केवल पाए गए फ़ाइल के पथ का उपयोग नहीं कर सकता, जैसे कि (उदाहरण के लिए कम) लेकिन सामान्य रास्तों को जंक करना है। क्या इसका कोई हल है (w / o को अपने आप को सेड करना)? [
विन 7

1
@elonderin इस समाधान का मिलान की गई फ़ाइलों की रिपोर्ट के साथ कोई लेना-देना नहीं है। लेकिन मैंने अभी-अभी git grepऔर git ls-filesउपनिर्देशिकाओं से और दोनों रिपोर्ट की कोशिश की है कि वर्तमान निर्देशिका के सापेक्ष फ़ाइल नाम (भले ही आप ':(top)'शामिल पथ का उपयोग करें )। दोनों आदेशों --full-nameमें रूट के सापेक्ष नामों को रिपोर्ट करने का विकल्प है, लेकिन यह डिफ़ॉल्ट रूप से बंद है।
केवल

1
मैं तो मैं एक पार्टी समारोह बना Git उपनाम का प्रयोग नहीं करते, लेकिन संभवतः एक Git उर्फ बेहतर है gist.github.com/cmdcolin/04e2378b60f4457a41904c659368066f
कॉलिन डी

62

अपडेट: git> = 1.9 के लिए, बाहर के पैटर्न के लिए मूल समर्थन है, केवल जवाब देखें

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

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

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


इसके लिए धन्यवाद! Git grep, ack & co की तुलना में बहुत तेज़ है, लेकिन मनमाने रास्तों को बाहर करने में सक्षम नहीं है, इसलिए बोलने में थोड़ा असुविधाजनक था :)
Tomasz Zieliński

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

2
यह बेनिसिमो की "आर्ग्युमेंट लिस्ट बहुत लंबी" समस्या और मेरी समस्या को हल करना चाहिए। बैश द्वारा व्याख्या किए गए फ़ाइल नाम कारैक्टर्स के साथ मेरी समस्या (जैसे []) या फ़ाइल नाम रिपॉजिटरी में रिक्त स्थान वाले हैं: git ls-files | grep -v <exclue-pattern> | xargs -d '\ n' git grep <पैटर्न> -
स्काउट

2
Onlynone के उत्तर की जाँच करें, संभवतः यह पूरी तरह से (आधुनिक संस्करणों में) git के भीतर अब संभव है।
डेविड

क्यों घटता है? यह उत्तर अभी भी 1.9 से पहले के संस्करणों पर लागू होता है। मैंने केवल जवाब देने के लिए एक नोट जोड़ा है।
किन्नन

5

आप अपनी रिपॉजिटरी में एक विशेषता फ़ाइल बनाकर फ़ाइलों या निर्देशिकाओं को बाइनरी के रूप में चिह्नित कर सकते हैं, जैसे

$ cat .git/info/attributes 
directory/to/ignore/*.* binary
directory/to/ignore/*/*.* binary
another_directory/to/also/ignore/*.* binary

बाइनरी फ़ाइलों में मेल को बिना लाइन के सूचीबद्ध किया जाता है, जैसे

$ git grep "bar"
Binary file directory/to/ignore/filename matches
other_directory/other_filename:      foo << bar - bazz[:whatnot]

2

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

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

#!/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 "$@" -- `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 "$@"; 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

इसके अनुसार इस चीज को नाम देना संभव है git-ggऔर इसे नियमित रूप से कमांड के रूप में कॉल करने में सक्षम होना चाहिए:

$ git gg searchstring

लेकिन मुझे यह काम नहीं मिल रहा है। मैंने अपनी स्क्रिप्ट तैयार की ~/bin/और एक git-ggसिम्कलिन बनाया /usr/lib/git-core/

नोट 2

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.