git - गिट इतिहास में grep(खोज) प्रतिबद्ध कोड कैसे करें?




diff (9)

@ जीट का जवाब पावरशेल में काम करता है।

git grep -n <regex> $(git rev-list --all)

निम्नलिखित सभी फ़ाइलों को किसी भी प्रतिबद्धता में प्रदर्शित करता है, जिसमें password

# store intermediate result
$result = git grep -n "password" $(git rev-list --all)

# display unique file names
$result | select -unique { $_ -replace "(^.*?:)|(:.*)", "" }

मैंने अतीत में फ़ाइल में फ़ाइल या कुछ कोड हटा दिया है। क्या मैं सामग्री में grep कर सकता हूं (प्रतिबद्ध संदेशों में नहीं)?

लॉग को grep करने के लिए एक बहुत ही खराब समाधान है:

git log -p | grep <pattern>

हालांकि यह सीधे हैश को वापस नहीं लौटाता है। मैंने git grep साथ कोई फायदा नहीं हुआ।


आपको git log के पिकैक्स ( -S ) विकल्प का उपयोग करना चाहिए

Foo लिए खोज करने के लिए:

git log -SFoo -- path_containing_change 
git log -SFoo --since=2009.1.1 --until=2010.1.1 -- path_containing_change

गिट इतिहास देखें - अधिक से अधिक कीवर्ड द्वारा खोए गए लाइन को ढूंढें

जैसा कि Jakub Narębski टिप्पणी की:

  • यह उन अंतरों को देखता है जो <string> उदाहरण को पेश या हटाते हैं
    इसका आमतौर पर अर्थ होता है "संशोधन जहां आपने 'फू' के साथ लाइन को जोड़ा या हटा दिया।

  • - --pickaxe-regex विकल्प आपको एक स्ट्रिंग की खोज के बजाय विस्तारित POSIX regex का उपयोग करने की अनुमति देता है।

जैसा कि Rob ने टिप्पणी की, यह खोज केस-संवेदी है - उसने केस-असंवेदनशील खोज करने के तरीके पर एक फॉलो-अप प्रश्न खोला।


तो क्या आप कोड के पुराने संस्करणों के माध्यम से grep करने की कोशिश कर रहे हैं यह देखने के लिए कि आखिरी चीज़ कहां मौजूद है?

अगर मैं ऐसा कर रहा था, तो शायद मैं गिट बिसेक्ट का उपयोग करूंगा। बिसेक्ट का उपयोग करके, आप एक ज्ञात अच्छा संस्करण, एक ज्ञात खराब संस्करण, और एक साधारण स्क्रिप्ट निर्दिष्ट कर सकते हैं जो यह देखने के लिए जांच करता है कि संस्करण अच्छा है या बुरा है (इस मामले में यह देखने के लिए एक grep है कि आप जिस कोड को ढूंढ रहे हैं वह मौजूद है या नहीं )। इसे हटाए जाने पर कोड को हटा दिया जाएगा।


प्रतिबद्ध सामग्री की खोज करने के लिए (यानी, स्रोत की वास्तविक रेखाएं, संदेश भेजने के विपरीत और इसी तरह), आपको क्या करना है:

git grep <regexp> $(git rev-list --all)

अद्यतन : git rev-list --all | xargs git grep expression git rev-list --all | xargs git grep expression काम करेगी यदि आप "तर्क सूची बहुत लंबी" त्रुटि में भाग लेते हैं

यदि आप कुछ subtree (उदाहरण के लिए "lib / util") पर खोज को सीमित करना चाहते हैं तो आपको इसे rev-list उपसमंड और grep के साथ पास करने की आवश्यकता होगी:

git grep <regexp> $(git rev-list --all -- lib/util) -- lib/util

यह regexp के लिए आपके सभी प्रतिबद्ध पाठ के माध्यम से grep होगा।

दोनों आदेशों में पथ पारित करने का कारण यह है कि पुन: सूची संशोधन सूची वापस कर देगी जहां lib/util में किए गए सभी परिवर्तन हुए, लेकिन आपको grep को पास करने की आवश्यकता है ताकि यह केवल lib/util पर खोज सके।

बस निम्न परिदृश्य की कल्पना करें: grep को अन्य फ़ाइलों पर वही <regexp> मिल सकता है जो पुन rev-list द्वारा लौटाए गए एक ही संशोधन में निहित हैं (भले ही उस संशोधन में उस फ़ाइल में कोई परिवर्तन न हो)।

अपने स्रोत को खोजने के कुछ अन्य उपयोगी तरीके यहां दिए गए हैं:

टेक्स्ट मिलान नियमित अभिव्यक्ति regexp के लिए काम कर रहे पेड़ की खोज करें:

git grep <regexp>

टेक्स्ट मिलान की नियमित अभिव्यक्ति regexp1 या regexp2 के मिलान के लिए काम कर रहे पेड़ की खोज करें:

git grep -e <regexp1> [--or] -e <regexp2>

नियमित मिलान अभिव्यक्ति regexp1 और regexp2 से मेल खाने वाले पाठ की रेखाओं के लिए काम करने वाले पेड़ की खोज करें, केवल फ़ाइल पथों की रिपोर्ट करना:

git grep -e <regexp1> --and -e <regexp2>

उन फाइलों के लिए काम करने वाले पेड़ की खोज करें जिनमें पाठ की रेखाएं नियमित अभिव्यक्ति regexp1 से मिलती हैं और टेक्स्ट मिलान की नियमित अभिव्यक्ति regexp2:

git grep -l --all-match -e <regexp1> -e <regexp2>

पाठ मिलान पैटर्न की बदली हुई लाइनों के लिए काम कर रहे पेड़ की खोज करें:

git diff --unified=0 | grep <pattern>

टेक्स्ट मिलान नियमित अभिव्यक्ति regexp के लिए सभी संशोधन खोजें:

git grep <regexp> $(git rev-list --all)

टेक्स्ट मिलान नियमित अभिव्यक्ति regexp के लिए rev1 और rev2 के बीच सभी संशोधन खोजें:

git grep <regexp> $(git rev-list <rev1>..<rev2>)

मैंने @ जीट का जवाब लिया और इसे विंडोज़ में पहुंचाया ( इस जवाब के लिए धन्यवाद):

FOR /F %x IN ('"git rev-list --all"') DO @git grep <regex> %x > out.txt

ध्यान दें कि मेरे लिए, किसी कारण से, इस रेगेक्स को हटाए गए वास्तविक प्रतिबद्धता कमांड के आउटपुट में दिखाई नहीं दे रही थी, बल्कि इससे पहले कि कोई भी प्रतिबद्ध हो।


यदि आप कोड परिवर्तन ब्राउज़ करना चाहते हैं (देखें कि पूरे इतिहास में दिए गए शब्द के साथ वास्तव में क्या बदला गया है) patch मोड के लिए जाएं - मुझे ऐसा करने का एक बहुत ही उपयोगी संयोजन मिला:

git log -p
# hit '/' for search mode
# type in the word you are searching
# if the first search is not relevant hit 'n' for next (like in vim ;) )

git log सभी शाखाओं में पाठ की खोज का एक और अधिक प्रभावी तरीका हो सकता है, खासकर यदि कई मैचों हैं, और आप पहले हालिया (प्रासंगिक) परिवर्तन देखना चाहते हैं।

git log -p --all -S 'search string'
git log -p --all -G 'match regular expression'

ये लॉग कमांड सूची यह बताती है कि दिए गए खोज स्ट्रिंग / रेगेक्स को जोड़ या हटाएं, (आमतौर पर) हाल ही में पहले। -p विकल्प प्रासंगिक diff को दिखाया जा सकता है जहां पैटर्न जोड़ा गया था या हटा दिया गया था, ताकि आप इसे संदर्भ में देख सकें।

एक प्रासंगिक प्रतिबद्धता प्राप्त करने के बाद जो पाठ आप ढूंढ रहे थे (उदाहरण के लिए 8beeff00d) जोड़ते हैं, उन शाखाओं को ढूंढें जिनमें प्रतिबद्धता है:

git branch -a --contains 8beeff00d

SourceTree में ऐसा करने की कोशिश करने वाले किसी और के लिए, इसके लिए UI में कोई प्रत्यक्ष आदेश नहीं है (संस्करण 1.6.21.0 के रूप में)। हालांकि आप टर्मिनल विंडो (मुख्य टूलबार में उपलब्ध बटन) खोलकर स्वीकृत उत्तर में निर्दिष्ट आदेशों का उपयोग कर सकते हैं और उन्हें कॉपी / पेस्ट कर सकते हैं।

नोट: SourceTree का खोज दृश्य आंशिक रूप से आपके लिए टेक्स्ट खोज कर सकता है। खोज दृश्य पर जाने के लिए Ctrl + 3 दबाएं (या नीचे उपलब्ध खोज टैब पर क्लिक करें)। दूर से, खोज प्रकार को फ़ाइल में सेट करें और फिर वह स्ट्रिंग टाइप करें जिसे आप खोजना चाहते हैं। उपरोक्त आदेश की तुलना में इस विधि में निम्नलिखित सीमाएं हैं:

  1. SourceTree केवल उन गतिविधियों को दिखाता है जिनमें बदली गई फ़ाइलों में से एक में खोज शब्द होता है। खोज टेक्स्ट युक्त सटीक फ़ाइल ढूंढना एक मैन्युअल कार्य है।
  2. RegEx समर्थित नहीं है।

git rev-list --all | xargs -n 5 git grep EXPRESSION

@ जीट के समाधान के लिए एक चिमटा है, इसलिए यह परिणाम दिखाता है, जबकि यह खोज करता है और अंत में नहीं (जो एक बड़े रेपो में लंबा समय ले सकता है)।





diff