एक regexp के आधार पर एक अंतर / पैच के केवल प्रासंगिक हक्स प्रदर्शित करें


20

git log -G<regex> -pनिर्दिष्ट पैटर्न से मेल खाने वाले परिवर्तनों के लिए कोडबेस के इतिहास को खोजने के लिए एक अद्भुत उपकरण है। हालांकि, ज्यादातर अप्रासंगिक हंक के समुद्र में अंतर / पैच आउटपुट में प्रासंगिक हंक का पता लगाना भारी हो सकता है।

git logमूल स्ट्रिंग / रेगेक्स के आउटपुट की खोज करना निश्चित रूप से संभव है , लेकिन यह दृश्य शोर को कम करने और कई असंबंधित परिवर्तनों की विकर्षण को कम करने के लिए है।

पर पढ़ना git log, मुझे लगता है कि वहाँ है --pickaxe-all, जो मैं चाहता हूँ के विपरीत है: यह उत्पादन (पूरे बदलाव के लिए) को व्यापक करता है, जबकि मैं इसे (विशिष्ट हंक तक) सीमित करना चाहता हूं।

अनिवार्य रूप से, मैं अलग-अलग हंक में अंतर / पैच पार्स करने के लिए "बुद्धिमानी से" एक रास्ता खोज रहा हूं और फिर प्रत्येक हंक (लक्षित लाइनों को लक्षित करना) के खिलाफ एक खोज को निष्पादित करता हूं, उन हंक्स को त्यागें जो मेल नहीं खाते हैं, और जो आउटपुट करते हैं। यह काम करता है।

क्या एक उपकरण जैसे मैं वर्णन करता हूं मौजूद है? क्या मिलान / प्रभावित हंक प्राप्त करने के लिए एक बेहतर तरीका है?

कुछ प्रारंभिक शोध मैंने किए हैं ...

  • यदि यह grepअंतर / पैच आउटपुट के लिए संभव था और संदर्भ विकल्प मानों को गतिशील बनाता है - पंक्ति गणना के बजाय regexps के माध्यम से - जो पर्याप्त हो सकता है। लेकिन grepबिल्कुल उस तरह से नहीं बनाया गया है (और न ही मैं जरूरी उस सुविधा का अनुरोध कर रहा हूं)।

  • मुझे चिथड़े मिल गए सूट सूट , जो शुरू में ऐसा लगता था जैसे यह मेरी आवश्यकताओं के अनुरूप हो। लेकिन इसके manपृष्ठों को पढ़ने के बाद , उपकरण regexps के आधार पर मिलान हंक को संभालने के लिए प्रकट नहीं होते हैं। (वे लोकों की सूची स्वीकार कर सकते हैं, हालांकि ...)

  • मैं आखिरकार स्प्लिटपैच.आरबी में आया , जो पैच के पार्सिंग को अच्छी तरह से संभालने के लिए लगता है, लेकिन stdinवांछित पैच का मिलान, और फिर स्टॉक्स को आउटपुट करने के लिए इसे पढ़ने के पैच को संभालने के लिए काफी संवर्धित होने की आवश्यकता होगी ।


1
नहीं जो आप से पूछा लेकिन git log की कोशिश करो -Gfoo | कम + / फू
जेम्स यंगमैन

जवाबों:


7

यहाँ /programming//a/35434714/5305907 जो आप ढूंढ रहे हैं उसे करने का एक तरीका बताया गया है। प्रभावी रूप से:

git diff -U1 | grepdiff 'console' --output-matching=hunk

यह दी गई स्ट्रिंग "कंसोल" के साथ मेल खाने वाली केवल हंक दिखाती है।


धन्यवाद। grepdiffमूल रूप से मैं क्या चाहता हूँ; मैं अपने हंक मिलान विकल्प याद किया होगा! हालाँकि ... git कमिट की जानकारी द्वारा छीन ली गई है grepdiff, इसलिए एक बार जब आप संबंधित हंक का पता लगा लेते हैं, तो आपको ऑब्जेक्ट को / shab से डिमांड हेडर को अलग हेडर में रखना चाहिए - काफी महंगा ऑपरेशन। (देखें stackoverflow.com/a/223890/2284440 ) यह कुछ इस तरह होगाgit find-object SHA --reverse | head -1 | cut -c 1-7 | { read sha ; git log -1 $sha; }
wrksprfct

यह भी ध्यान दें कि स्वीकृत तर्क के संदर्भ में एक गोलगप्पा संस्करणgrepdiff अधिक नंगे है। ध्यान दें कि जब मिलान हंक एक अलग में अंतिम हंक है, तो इसमें गलत तरीके से निम्नलिखित कमिट के git प्रतिबद्ध हेडर शामिल हैं - कुछ ऐसा जो मुझे पूरी तरह से भ्रमित कर देता है जब तक मुझे एहसास नहीं होता कि क्या हो रहा है!
wrrprfct

0

बिल्कुल नहीं आप क्या पूछ रहे हैं, लेकिन एक तरह से हंक के माध्यम से grep इंटरैक्टिव-ऐड मोड है। इसके लिए आवश्यक है कि आप जिस पैच में रुचि रखते हैं उसके बाद कमिट की जाँच करें

git checkout COMMIT_ID

फिर वीसीएस में एक और कदम पीछे जाएं, लेकिन कार्यशील निर्देशिका में नहीं

git reset --soft HEAD^

(इस बिंदु पर, सूचकांक और काम करने वाली निर्देशिका के बीच का अंतर उस पैच के अनुरूप होगा, जिसमें आप रुचि रखते हैं।)

अब आप निष्पादित कर सकते हैं git add -p। यह एक संवादात्मक सत्र लॉन्च करेगा जिसमें एक /विकल्प है, जो आपको हक्स का पता लगाने की अनुमति देता है जिसमें कुछ रेखा एक रेग्ज से मेल खाती है। विशेष रूप से उपयोगी यदि आप वास्तव में उन पैच को आगे की प्रक्रिया करना चाहते हैं (जैसे, एक आंशिक चेरी-पिक तैयार करना)।

दुर्भाग्य से, कम से कम अभी /कमांड add -pकेवल एक फ़ाइल के भीतर काम करती है, इसलिए आपको कई अप्रासंगिक फ़ाइलों को छोड़ना पड़ सकता है।


0

@Nagu द्वारा ऊपर दिए गए उत्तर पर निर्माण, और अन्य जुड़े हुए उत्तर, मैं git log -Gकेवल प्रासंगिक हंक दिखाने में सक्षम था ।

  1. पहले इस सामग्री के साथ अपने $ PATH में कहीं एक स्क्रिप्ट बनाएं:

    #!/bin/bash
    
    # pickaxe-diff : external diff driver for Git.
    #                To be used with the pickaxe options (git [log|show|diff[.*] [-S|-G])
    #                to only show hunks containing the searched string/regex.
    
    path=$1
    old_file=$2
    old_hex=$3
    old_mode=$4
    new_file=$5
    new_hex=$6
    new_mode=$7
    
    filtered_diff=$(diff -u -p $old_file $new_file | \
                    grepdiff "$GREPDIFF_REGEX" --output-matching=hunk | \
                    grep -v -e '+++ ' -e '--- ')
    
    a_path="a/$path"
    b_path="b/$path"
    
    echo "diff --git $a_path $b_path"
    echo "index $old_hex..$new_hex $old_mode"
    echo "--- $a_path"
    echo "+++ $b_path"
    echo "$filtered_diff"
  2. कॉल करें git log -Gऔर बताएं कि pickaxe-diffस्क्रिप्ट का बाहरी अंतर चालक के रूप में उपयोग करने के लिए :

    export GREPDIFF_REGEX=<string>; 
    GIT_EXTERNAL_DIFF=pickaxe-diff git log -p --ext-diff -G $GREPDIFF_REGEX

    यह पिकक्स-डिफरेंट स्क्रिप्ट का उपयोग सिर्फ डिफरेंशियल जेनरेट करने के लिए करेगा, इसलिए बाकी git logआउटपुट (कम से कम हैश, मैसेज आदि) अनछुए हो जाएंगे।

कैविट
जिस तरह से गिट पिकैक्स काम करता है वह यह है कि यह आउटपुट को उन फाइलों तक सीमित करता है जिनके हॉक दिए गए स्ट्रिंग / रेगेक्स को बदलते हैं। इसका मतलब यह है कि अगर इन फ़ाइलों में एक और हंक भी खोज स्ट्रिंग / regex शामिल है, लेकिन इसे परिवर्तित नहीं करता है, तो यह अभी भी उपरोक्त स्क्रिप्ट के साथ प्रदर्शित किया जाएगा। यह grepdiff की एक सीमा है। पैचपिल्स परियोजना में एक खुला पुल अनुरोध है कि एक --only-matchingझंडे को grepdiff में जोड़ने के लिए, जो इन फ़ोकस को सही ढंग से फ़िल्टर करने के लिए आवश्यक कार्यक्षमता प्रदान करेगा।


मैंने इस समाधान में अपना समाधान लिख दिया ।

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