एक निश्चित स्ट्रिंग के लिए रिपॉजिटरी में सभी गिट और मर्क्यूरियल के माध्यम से खोज कैसे करें?


287

मेरे पास कुछ शाखाओं और झूलने वाले कमिट्स के साथ Git रिपॉजिटरी है। मैं विशिष्ट स्ट्रिंग के लिए रिपॉजिटरी में ऐसे सभी कमिट्स को खोजना चाहता हूं।

मुझे पता है कि इतिहास में सभी कमिट का लॉग कैसे मिलता है, लेकिन इनमें शाखाएँ या झूलने वाली बूँदें शामिल नहीं हैं, सिर्फ हेड का इतिहास। मैं उन सभी को प्राप्त करना चाहता हूं, जो एक विशिष्ट प्रतिबद्ध को ढूंढना है जो गलत हो गया है।

मैं यह भी जानना चाहूंगा कि यह कैसे मर्क्यूरियल में करना है, क्योंकि मैं स्विच पर विचार कर रहा हूं।


जवाबों:


331

आप झूलते हुए देख सकते हैं git log -g

-g, --walk-reflogs
 Instead of walking the commit ancestry chain, walk reflog entries from
 the most recent one to older ones. 

तो आप ऐसा कर सकते हैं कि एक विशेष संदेश में एक स्ट्रिंग को खोजने के लिए जो झूल रहा है:

git log -g --grep=search_for_this

वैकल्पिक रूप से, यदि आप किसी विशेष स्ट्रिंग के लिए परिवर्तनों को खोजना चाहते हैं, तो आप पिकैक्स खोज विकल्प, "-S" का उपयोग कर सकते हैं:

git log -g -Ssearch_for_this
# this also works but may be slower, it only shows text-added results
git grep search_for_this $(git log -g --pretty=format:%h)

Git 1.7.4 -G विकल्प जोड़ेगा , जिससे आप पा सकते हैं -G <regexp> खोजने के लिए जब <regexp> वाली एक लाइन ले जाया गया, जो -S नहीं कर सकता। -एस आपको केवल तभी बताएगा जब स्ट्रिंग वाली कुल संख्या बदल गई हो (यानी स्ट्रिंग जोड़ना / निकालना)।

अंत में, आप झटके का उपयोग करने के लिए झूलने वाले दृश्यों की कल्पना कर सकते हैं:

gitk --all $(git log -g --pretty=format:%h)

और फिर गलत फ़ाइल देखने के लिए इसकी खोज सुविधाओं का उपयोग करें। इन सभी कामों को गुमशुदा मानते हुए "समाप्त" नहीं किया गया है और कचरा एकत्र किया गया है, जो कि हो सकता है अगर यह 30 दिनों के लिए झूल रहा है और आप रिफ्लक्स को समाप्त करते हैं या एक कमांड चलाते हैं जो उन्हें समाप्त करता है।


4
शायद (संभवतः बड़ी) संख्याओं पर "git grep" चलाने के बजाय, जो किसी परियोजना में कहीं न कहीं 'search_for_this' करने वाले सभी कमिटों को ढूंढेगा, तथाकथित "pickaxe" खोज का उपयोग करें, अर्थात् 'log' करने का विकल्प , जो दिए गए स्ट्रिंग को पेश या हटाए जाने, या अधिक सटीक होने के लिए कमिट पाता है, जहां किसी दिए गए स्ट्रिंग के होने की संख्या बदल जाती है।
जकुब नारबस्की 10

5
आप कई शाखाओं को निर्दिष्ट कर सकते हैं, या '--all' विकल्प का उपयोग कर सकते हैं, उदाहरण के लिए 'git log --grep = "एक प्रतिबद्ध संदेश में स्ट्रिंग" --all'
Jakub Narębski

इसने मुझे 2 दिन के काम के लिए खोई हुई कमिटमेंट खोजने की अनुमति दी। पूरी तरह से मेरी गांड बचाई, धन्यवाद!
माइक चेम्बरलेन

2
मैं कुछ स्थितियों में आया हूं, जहां मैंने अपने डेटाबेस में कमिट किया था, लेकिन मेरे रिफ्लॉग में नहीं। मुझे नहीं पता कि यह कितना आम है। मैं अलग-अलग hg / git पुलों को आज़मा रहा था। मुझे लगता है कि यह भी गिरी हुई लड़ाइयों के साथ पैदा हो सकता है। किसी भी मामले में, यह उपनाम उन मामलों को पकड़ने के लिए अच्छी तरह से काम करता है:!git fsck --unreachable | sed -ne 's/^unreachable commit //p' | xargs git log --no-walk
dubiousjim

ध्यान दें, जिसमें खोज नोट ऑब्जेक्ट शामिल नहीं हैं। इसे अभी तक लागू नहीं किया गया है: git.661346.n2.nabble.com/…
एंटनी स्टब्स

54

Mercurial में आप hg log --keywordकमिट मैसेज में कीवर्ड hg log --userखोजने और किसी विशेष उपयोगकर्ता की खोज करने के लिए उपयोग करते हैं। hg help logलॉग को सीमित करने के अन्य तरीकों के लिए देखें ।


36
जोसिप ने लिखा कि वह मर्क्यूरियल में स्विच करने पर विचार कर रहा है और वह यह भी सुनना चाहेगा कि यह वहाँ कैसे किया जाता है।
मार्टिन गेइस्लर

1
hg log -kपरिवर्तनों में उपयोगकर्ता का नाम और फ़ाइल नाम भी खोजते हैं (मैं कमांड्सहोम में इसे देखता हूं), जो कि उन कुछ चीजों में से एक है जो मुझे hg में समझ नहीं आ रही है। प्रतिबद्ध संदेशों और फ़ाइल नामों में खोज करने के लिए अलग-अलग विकल्प होने चाहिए। लगता hg log --template '{desc}\n'|grepहै कि निश्चित तरीका है।
ज्योफ्री झेंग

@GeoffreyZheng: ऐसा करने के तरीके हैं। "Hg help revsets", एस्प को desc (), उपयोगकर्ता (), और फ़ाइल () फ़ंक्शन देखें। इस व्यवहार के अधिकांश के लिए hg लॉग स्विच भी हैं। मेरे अनुभव में, हालांकि -k / कीवर्ड () आमतौर पर चीजों की खोज करने के लिए सबसे उपयोगी तरीका है।
केविन हॉर्न

वास्तविक प्रतिबद्ध फ़ाइल सामग्री ... diffs के माध्यम से कोई कैसे खोज करता है? मुझे पता है कि यह एक धीमी खोज होगी, लेकिन मैं एक लापता फ़ंक्शन नाम के लिए एक गहरी खोज करना चाहता हूं।
जोनाथन

ओह यहाँ यह है:hg grep --all <term>
जोनाथन

24

के अलावा richq जवाब का उपयोग कर के git log -g --grep=<regexp>या git grep -e <regexp> $(git log -g --pretty=format:%h): Junio सी Hamano, वर्तमान Git मेंटेनर द्वारा निम्न ब्लॉग पोस्ट पर एक नज़र


सारांश

दोनों Git ग्रेप और Git लॉग --grep कर रहे हैं लाइन उन्मुख , में है कि वे लाइनों कि निर्दिष्ट मेल खाने वाला पैटर्न के लिए देखो।

आप git log --grep=<foo> --grep=<bar>या तो पैटर्न (अंतर्निहित या अर्थ) से मेल खाने वाले कमिट्स को खोजने के लिए (या git log --author=<foo> --grep=<bar>आंतरिक रूप से दो में अनुवाद --grep) का उपयोग कर सकते हैं ।

लाइन-ओरिएंटेड होने के कारण, उपयोगी और शब्दार्थ का उपयोग कमिटgit log --all-match --grep=<foo> --grep=<bar> खोजने के लिए करना है, जिसमें दोनों लाइन पहले से मेल खाते हैं और लाइन मिलान दूसरे स्थान पर है।

साथ git grepआप एक से अधिक पैटर्न (जो सभी का उपयोग करना चाहिए गठजोड़ कर सकते हैं -e <regexp>के साथ फार्म) --or(जो डिफ़ॉल्ट है), --and, --not, (और )। Grep के लिए --all-matchइसका मतलब है कि फ़ाइल में ऐसी लाइनें होनी चाहिए जो प्रत्येक विकल्प से मेल खाती हों।


हे जकूब, उन ब्लॉग पोस्ट से उद्धरण / सारांश को एकीकृत करने का मन? अभी विंटेज लिंक में से एक जैसा दिखता है।
नाथन टग्गी

11

Rq के उत्तर पर निर्माण, मैंने पाया कि यह लाइन मुझे क्या चाहिए:

git grep "search for something" $(git log -g --pretty=format:%h -S"search for something")

जो इस तरह से कमिटेड आईडी, फाइलनाम, और मैचिंग लाइन को प्रदर्शित करेगा:

91ba969:testFile:this is a test

... क्या कोई मानता है कि यह मानक git grep कमांड में शामिल होने के लिए एक अच्छा विकल्प होगा?


5

कोई भी आदेश जो संदर्भ के रूप में लेता --allहै, वह git rev-listनिम्नानुसार के लिए मैन पेज में प्रलेखित विकल्प को स्वीकार करेगा :

   --all
       Pretend as if all the refs in $GIT_DIR/refs/ are listed on the
       command line as <commit>.

उदाहरण के लिए, git log -Sstring --allसभी उल्लेख प्रदर्शित होंगे जो stringएक शाखा से या एक टैग से सुलभ हैं (मैं मान रहा हूं कि आपके झूलने वाले कम से कम एक टैग के साथ नामित किए गए हैं)।


3
ऐसा प्रतीत नहीं होता है git grep, जहाँ इसका --allअनुवाद / के रूप में किया जाना प्रतीत होता है --all-match। यह मेरे लिए एक बग की तरह दिखता है .. Git 1.7.2.3 का उपयोग करके ( $(git rev-list --all)काम करता है)।
ब्लू

5

मर्क्यूरियल के साथ आप ए

$ hg grep "search for this" [file...]

ऐसे अन्य विकल्प हैं जो खोजे जाने वाले संशोधनों की सीमा को कम करते हैं।


1
मुझे झंडा भी पसंद हैhg grep --all
जोनाथन

2

Git के बारे में नहीं जानते, लेकिन Mercurial में मैं hg लॉग के आउटपुट को कुछ sed / perl / जो भी स्क्रिप्ट की खोज करने के लिए जो भी आप खोज रहे हैं, उसे पाइप करेगा। यदि आप चाहें तो एचजी लॉग के आउटपुट को टेम्प्लेट या शैली का उपयोग करके आसानी से खोज सकते हैं।

इसमें रेपो में सभी नामित शाखाएं शामिल होंगी। मर्क्यूरियल में झूलने वाले अफाक जैसे कुछ नहीं है।


1
मुझे समझ नहीं आता कि यह उत्तर निर्दिष्ट समस्या के लिए कैसे प्रासंगिक है।
jribeiro

3
यह मर्क्यूरियल के प्रश्न का उत्तर है, जो मूल प्रश्न अंतिम पैराग्राफ के बारे में पूछता है।
कर्ट शेलफथआउट

1

यदि आप एक विम उपयोगकर्ता हैं, तो आप वीआईएम में खोज करने के लिए tig (apt-get install tig) स्थापित कर सकते हैं और /, उसी कमांड का उपयोग कर सकते हैं

https://blogs.atlassian.com/2013/05/git-tig/


1

अभी तक उल्लेख नहीं किए गए सिर्फ एक और समाधान को जोड़ने के लिए, मुझे यह कहना था कि gitg के ग्राफिकल सर्च बॉक्स का उपयोग करना मेरे लिए सबसे सरल समाधान था। यह पहली घटना का चयन करेगा और आप Ctrl-G के साथ अगला पा सकते हैं।


1

Git में एक आदेश है कि मुझे लगता है कि एक स्ट्रिंग को ढूंढना बहुत आसान है:

git log --pretty=oneline --grep "string to search"

Git 2.0.4 में काम करता है

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