मैं एक हटाई गई रेखा को "कैसे दोष दूं"?


506

git blameसंशोधित और जोड़ी गई लाइनों के लिए बहुत अच्छा है, लेकिन मैं कैसे पा सकता हूं जब एक विशिष्ट पिछली प्रतिबद्ध में मौजूद एक लाइन अंततः नष्ट हो गई थी। मैं सोच bisectरहा था, लेकिन मैं कुछ हाथ लगाने की उम्मीद कर रहा था।

(इससे पहले कि आप से पूछना: इस मामले में, मैं सिर्फ एक किया था git log -pऔर कोड लाइन और के लिए के माध्यम से की खोज (क) कुछ बेवकूफ था सिर्फ पिछले प्रतिबद्ध और (ख) मुझे लगता है कि बेवकूफ था में महत्वपूर्ण लाइन नष्ट कर दिया।)


4
एक उत्तर के साथ एक अनुवर्ती है जो स्पष्ट करता git log -S<string> /path/to/fileहै कि मर्ज (संघर्ष) के दौरान हटाने को दिखाने के लिए एक -cया -ccसाथ ही चाहता है
cfi

3
यह होना चाहिए -cऔर --cc। @ सोलह: सही, इशारा करने के लिए धन्यवाद! मूर्खतापूर्ण निरीक्षण। काश मैं टिप्पणी संपादित कर पाता। एक नया जोड़ना, फिर मेरा डिलीट करना, फिर आप को डिलीट करना, यह सब मुझे बहुत ही बोझिल लगता है :)
cfi

4
काश मेरे git blameपास उस संशोधन के साथ हटाए गए लाइनों (शायद स्ट्राइकथ्रू या लाल पाठ के साथ) को दिखाने का विकल्प होता जिसमें वे हटाए गए थे।
क्रेग मैकक्वीन

क्या यह लिखना कठिन होगा? मैं Git के बारे में बहुत कुछ नहीं जानता।
मालवोलियो

जवाबों:


636

यदि आप लाइन की सामग्री जानते हैं, तो यह एक आदर्श उपयोग मामला है:

git log -S <string> path/to/file

जो आपको दिखाता है कि उस स्ट्रिंग का उदाहरण कौन प्रस्तुत करता है या हटाता है। वहाँ भी है -G<regex>जो नियमित अभिव्यक्ति के साथ एक ही बात करता है! अधिक जानकारी के लिए और विकल्प, या पिकैक्स (इन सुविधाओं के लिए अनुकूल नाम) देखें man git-logऔर खोजें ।-G-S

-Sविकल्प वास्तव में के शीर्षक में उल्लेख किया गया है git-blameभी मैनपेज, विवरण खंड है, जहां यह का उपयोग कर एक उदाहरण देता में git log -S...


शानदार ... बस मुझे इस पोर्टिंग जॉब में जरूरत थी कि मैं +1
jkp

37
1+ वर्ष तक Git का उपयोग करने के बाद, यह अभी भी मुझे आश्चर्यचकित करता है कि Git के पास हमेशा मेरे पास मौजूद किसी भी उपयोग परिदृश्य को संबोधित करने के लिए कहीं न कहीं एक कमांड / विकल्प होता है। यह एक साझा करने के लिए धन्यवाद, यह वही है जो मुझे अभी चाहिए!
पास्कल बॉर्क

22
यह विधि मेरे लिए पहले भी काम कर चुकी है, लेकिन अभी मैंने एक ऐसा मामला देखा, जहां उसे वह वचन नहीं मिला जहां लाइन को हटा दिया गया था। यह पता चला कि विचाराधीन लाइन को मर्ज कमेटी में हटा दिया गया था - क्या यह विफलता को स्पष्ट करेगा? ( git blame --reverseविधि हालांकि यह पाया गया।)
एंटीइन

9
@antinome मर्ज से कमिट दिखाने के लिए, -cअतिरिक्त रूप से विकल्प का उपयोग करें ।
युनेजन

2
मैंने मेनपेज पर "-s" पर ctrl + f किया और कुछ नहीं पाया। पृष्ठ पर आप इसे कहाँ देखते हैं ?? मैं Git 1.8.5.2 उपयोग कर रहा हूँ
temporary_user_name

134

मुझे लगता है कि आप वास्तव में क्या चाहते हैं

git blame --reverse START..END filename

से मैनपेज :

पिछड़ों के बजाय इतिहास को आगे बढ़ाएं। उस संशोधन को दिखाने के बजाय जिसमें कोई रेखा दिखाई देती है, यह अंतिम संशोधन दिखाता है जिसमें एक पंक्ति मौजूद है। इसके लिए START..END की तरह कई संशोधनों की आवश्यकता होती है, जहां START में दोष लगाने का मार्ग मौजूद है।

के साथ git blame reverse, आप पा सकते हैं कि आखिरी बार दिखाई देने वाली लाइन।

आप उलटा गिट लॉग दिखाने के लिए निम्न कमांड का उपयोग कर सकते हैं। पहली बार प्रदर्शित की गई अंतिम बार वह रेखा दिखाई देगी, और अगली प्रतिबद्धता तब होगी जब इसे बदल दिया जाएगा या हटा दिया जाएगा।

git log --reverse --ancestry-path COMMIT^..master

14
यदि शाखा में उस रेखा से कई मर्ज किए गए हों जहां वह शाखा गायब थी, जहां रेखा गायब है (या किसी अन्य मामले में, जहां START से END तक वंश में कई रास्ते हैं), git blame --reverseतो मर्ज होने से पहले का संशोधन दिखाएगा जो कालानुक्रमिक रूप से था अंतिम, प्रारंभिक मर्ज से पहले संशोधन नहीं, जहां लाइन नहीं लेने का निर्णय लिया गया था। क्या सबसे शुरुआती संशोधन को खोजने के लिए कोई रास्ता है जहां लाइन सबसे हाल के एक के बजाय मौजूदा बंद हो गई है?
राकसलिस

2
@rakslice, इसके लिए आप दोष --reverse --first- माता-पिता का उपयोग कर सकते हैं, यह थोड़ा बेहतर है।
अधिकतम ६३०

17

कैस्केबेल के उत्तर को पूरा करने के लिए बस :

git log --full-history -S <string> path/to/file

मुझे यहां बताई गई समस्या समान थी, लेकिन यह पता चला कि लाइन गायब थी, क्योंकि एक शाखा से एक मर्ज कमिट वापस हो गया और फिर इसमें विलय हो गया, प्रभावी रूप से लाइन को प्रश्न में हटा दिया। --full-historyझंडा रोकता है उन प्रतिबद्ध लंघन।


9

Git दोष --reverse आप प्राप्त कर सकते हैं पास जहां लाइन हटा दी जाती है के लिए। लेकिन यह वास्तव में उस संशोधन की ओर इशारा नहीं करता है जहां लाइन हटाई जाती है। यह अंतिम संशोधन की ओर इशारा करता है जहां रेखा मौजूद थी । फिर यदि निम्नलिखित संशोधन एक सादा प्रतिबद्धता है, तो आप भाग्यशाली हैं और आपको हटाए गए संशोधन को मिला है। ओटीओएच, यदि निम्नलिखित संशोधन एक मर्ज कमेटी है , तो चीजें थोड़ी जंगली हो सकती हैं।

डिफ्लेम बनाने के प्रयास के एक भाग के रूप में मैंने इस समस्या से निबटा है, इसलिए यदि आपके पास पहले से ही अपने बॉक्स पर पायथन स्थापित है और आप इसे आजमाना चाहते हैं, तो अब और इंतजार न करें और मुझे बताएं कि यह कैसे होता है।

https://github.com/eantoranz/difflame


0

मर्ज में छिपे बदलावों के लिए

मर्ज कमिट्स में स्वचालित रूप से उनके परिवर्तन Git लॉग आउटपुट से छिपे हुए हैं। पिकैक्स और रिवर्स-ब्लेम दोनों को परिवर्तन नहीं मिला। इसलिए जो लाइन मैं चाहता था उसे जोड़ा गया था और बाद में हटा दिया गया था और मैं उस मर्ज का पता लगाना चाहता था जिसने इसे हटा दिया। फ़ाइल git log -p -- path/fileइतिहास केवल यह जोड़ा जा रहा है दिखाया। यहाँ मुझे इसे खोजने का सबसे अच्छा तरीका है:

git log -p -U9999 -- path/file

परिवर्तन के लिए खोजें, फिर "^ कमिट" के लिए पीछे की ओर खोजें - पहला "^ कमिट" वह प्रतिबद्ध है जहां फ़ाइल में अंतिम रूप से वह लाइन थी। गायब होने के बाद दूसरा "^ कमिट" है। दूसरी प्रतिबद्धता वह हो सकती है जिसने इसे हटा दिया। -U9999यह मानते हुए कि आपकी फ़ाइलों सभी अधिकतम 9999 लाइनें हैं पूरी फ़ाइल सामग्री (हर बार फ़ाइल बदल गया था के बाद) को दिखाने के लिए है,।

ब्रूट फोर्स के माध्यम से किसी भी संबंधित मर्ज को पाता है (प्रत्येक संभावित मर्ज को उसके पहले माता-पिता के साथ प्रतिबद्ध करें, टन के खिलाफ चलाएं)

git log --merges --pretty=format:"git diff %h^...%h | grep target_text" HEAD ^$(git merge-base A B) | sh -v 2>&1 | less

(मैंने संशोधन फ़िल्टर को और अधिक सीमित करने की कोशिश की, लेकिन मैं समस्याओं में भाग गया और यह अनुशंसा नहीं करता। मैं जो कुछ भी अलग-अलग समय पर विलय कर रहा था और A ... B में शामिल नहीं था, मुझे जो / हटाने वाले बदलाव दिख रहे थे, वे अलग-अलग शाखाओं में थे। जब परिवर्तन वास्तव में मेनलाइन में विलय हो गए।)

इन दो हिट्स के साथ एक गिट ट्री दिखाएं (और हटाए गए बहुत सारे जटिल गिट इतिहास):

git log --graph --oneline A B ^$(git merge-base A B) (ए ऊपर की पहली प्रतिबद्धता है, बी ऊपर की दूसरी प्रतिबद्धता है)

ए और बी दोनों के इतिहास का इतिहास ए और बी दोनों का इतिहास दिखाएं।

वैकल्पिक संस्करण (नियमित Git इतिहास के पेड़ के बजाय अधिक रैखिक रूप से पथ दिखाने के लिए लगता है - हालांकि मैं नियमित git इतिहास के पेड़ को पसंद करता हूं):

git log --graph --oneline A...B

तीन, दो डॉट्स नहीं - तीन डॉट्स का अर्थ है "r1 r2 --not $ (git मर्ज-बेस --all r1 r2)। यह कमिट्स का एक सेट है जो r1 (लेफ्ट साइड) या r2 में से किसी एक (राईट) में से एक में उपलब्ध है। पक्ष), लेकिन दोनों से नहीं। " - स्रोत: "आदमी gitrevisions"

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