वास्तव में गिट के साथ नामांकित फ़ाइलों के लॉग दिखाने के लिए कैसे?


132

मैं अपेक्षाकृत नया हूँ, मैंने पहले तोड़फोड़ का इस्तेमाल किया था।

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

git log --follow

कमांड लाइन पर, मैं नाम बदलकर संपूर्ण लॉग देख सकता हूं।

लिनुस टॉर्वाल्ड्स के अनुसार - Thefollow स्विच एक "SVN noob" प्लसर है, गंभीर गिट उपयोगकर्ता इसका उपयोग नहीं करते हैं:

- फ़ोलो कुल हैक है, जो पूर्व-एसवीएन उपयोगकर्ताओं को संतुष्ट करने के लिए है, जो कि किसी भी तरह से पैरेंटहुड या अच्छा रिवीजन ग्राफ जैसी चीजों के बारे में कभी नहीं जानते थे।

यह पूरी तरह से मौलिक नहीं है, लेकिन "--follow" का वर्तमान कार्यान्वयन वास्तव में एक त्वरित प्रीप्रोसेसिंग चीज है जो वास्तव में अभिन्न होने के बजाय संशोधन चलने वाले तर्क पर बोली जाती है।

यह सचमुच "SVN noob" याचिकाकर्ता के रूप में डिज़ाइन किया गया था, न कि "वास्तविक गिट कार्यक्षमता" के रूप में। विचार यह था कि आप यह सोचकर (टूटी हुई) मानसिकता से दूर हो जाएंगे कि बड़ी तस्वीर में मामले का नाम बदल दिया जाए।

मेरा प्रश्न : जब आपके नाम को बदला गया, तो आपके बीच के कट्टर उपयोगकर्ताओं को फ़ाइल का इतिहास कैसे मिलता है? ऐसा करने का 'वास्तविक ’तरीका क्या है?


17
@ दाऊद हॉल: git mv oldfile newfileका कारण नहीं है नाम बदलने दर्ज किया जा सब पर है - यह सिर्फ एक फ़ाइल को हटाने और एक अन्य को जोड़ने के समान है। git केवल इस तथ्य के बाद प्रत्येक प्रतिबद्ध पर वृक्ष की स्थिति से नाम और प्रतियाँ निकालता है।
मार्क लॉन्गेयर

20
@ डेविड हॉल: यदि आप फ़ाइल को git (जैसे /bin/mv oldfile newfile) के बाहर किसी अन्य टूल से रीनेम करते हैं , लेकिन फिर करते हैं git add newfile; git rm oldfile, तो परिणाम इससे अप्रभेद्य है git mv oldfile newfile
मार्क लोंगेयर

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

1
नोट: git log --followgit 2.9 (जून 2016) के साथ थोड़ा सुधार हुआ है: नीचे मेरा उत्तर देखें
VonC

1
V2.15 के अनुसार, आप --color-movedजब चाहें प्रयोग कर सकते हैं diff
माइकल

जवाबों:


71

मुझे लगता है कि लिनुस बिंदु के पीछे सामान्य ड्राइव यह है - और इसे एक चुटकी नमक के साथ लें - कट्टर गिट उपयोगकर्ता कभी भी "फ़ाइल" के इतिहास के बारे में परवाह नहीं करते हैं। आप सामग्री को एक गणन भंडार में रखते हैं क्योंकि संपूर्ण रूप में सामग्री का एक सार्थक इतिहास है।

एक फ़ाइल का नाम पथ के बीच चलती "सामग्री" का एक छोटा विशेष मामला है। आपके पास एक फ़ंक्शन हो सकता है जो फ़ाइलों के बीच चलता है जो एक गिट उपयोगकर्ता "पिकैक्स" के साथ कार्यात्मक रूप से ट्रैकडाउन कर सकता है (जैसे log -S)।

अन्य "पथ" परिवर्तनों में संयोजन और विभाजन फाइलें शामिल हैं; git वास्तव में परवाह नहीं करता है कि आप किस फ़ाइल का नाम बदला हुआ मानते हैं और जिसे आप कॉपी (या नामांकित और हटाए गए) मानते हैं, यह आपके पेड़ की पूरी सामग्री को ट्रैक करता है।

git "पूरे पेड़" को प्रोत्साहित करता है जहां कई संस्करण नियंत्रण प्रणाली बहुत फ़ाइल केंद्रित हैं। यही कारण है कि गिट "पथ" को संदर्भित करता है और अधिक बार यह "फ़ाइलनाम" को संदर्भित करता है।


हाय चार्ल्स, आपके उत्तर के लिए धन्यवाद। ऐसा लगता है कि मैं उसी तरह git का उपयोग करता हूं जिस तरह से मैंने SVN का उपयोग किया है। हालांकि मैं समझता हूं कि git अन्य संस्करण नियंत्रण प्रणालियों की तुलना में बहुत अलग है, git में कई अवधारणाएं मेरे लिए अभी तक अजीब दिखती हैं ... मुझे शायद उस git पुस्तक को समाप्त करना चाहिए जिसे मैंने हाल ही में खरीदा था।
माइक

24
लिनुस का कहना था कि एक "उचित" गुई फाइलों में कोड के विखंडन को ट्रैक करने में सक्षम होगी, और वह उम्मीद कर रही थी कि हमारे पास अब तक ऐसे उपकरण होंगे। दुर्भाग्य से, हमारे पास अभी भी वह विलासिता नहीं है, और - फिर भी उपयोगी है।
माइकल पार्कर

11
क्या वास्तव में git आपको इसके अलावा कोई समाधान देता है --follow?
ग्रीव्स

13
मैं तर्क दूंगा कि "संपूर्ण वृक्ष" सोच --followडिफ़ॉल्ट होने से बढ़ी है । मेरे कहने का मतलब यह है कि जब मैं किसी फ़ाइल के भीतर कोड का इतिहास देखना चाहता हूं, तो मुझे वास्तव में परवाह नहीं है कि फ़ाइल का नाम बदला गया था या नहीं, मैं सिर्फ कोड के इतिहास को देखना चाहता हूं, चाहे नाम किसी का भी हो। इसलिए मेरी राय में यह --followडिफ़ॉल्ट होने के लिए समझ में आता है क्योंकि मुझे अलग-अलग फ़ाइलों की परवाह नहीं है; --followमुझे व्यक्तिगत फ़ाइल नाम को अनदेखा करने में मदद करता है, जो आमतौर पर बहुत असंगत हैं।

2
इसलिए ... यदि मैं फ़ाइल के बजाय "सामग्री" के बारे में परवाह करने का निर्णय लेता हूं, तो मैं इस फ़ाइल में मौजूद सामग्री से संबंधित कमिट कैसे प्रिंट करूं? मुझे खुशी होगी अगर git ने मेरे लिए अलग-अलग फाइलों में यह सब ट्रैक किया और सभी परिवर्तनों का एक लॉग रिपोर्ट किया - मुझे नहीं पता कि इसे कैसे प्राप्त किया जाए।
एड एविस

36

मेरे पास ठीक वही मुद्दा है जो आप सामना कर रहे हैं। भले ही मैं आपको कोई जवाब नहीं दे सकता, लेकिन मेरा मानना ​​है कि आप इस ईमेल को पढ़ सकते हैं , जिसे लिनस ने 2005 में वापस लिखा था, यह बहुत ही प्रासंगिक है और आपको इस समस्या को संभालने के तरीके के बारे में संकेत दे सकता है:

... मैं दावा कर रहा हूं कि कोई भी एससीएम जो नाम बदलने की कोशिश करता है, वह तब तक मौलिक रूप से टूट जाता है जब तक कि वह आंतरिक कारणों से ऐसा न करे (यानी कुशल डेल्टास की अनुमति देने के लिए), क्योंकि नाम बदलने से कोई फर्क नहीं पड़ता। वे आपकी मदद नहीं करते हैं, और वे वैसे भी नहीं हैं जो आप में रुचि रखते थे ।

जो मायने रखता है वह यह है कि "यह कहां से आया", और गिट आर्किटेक्चर वास्तव में बहुत अच्छी तरह से करता है - और कुछ भी नहीं है। ...

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

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

जब आप पाते हैं कि कमिट से पहले कोड का ब्लॉक फाइल में मौजूद नहीं था, तो आप कमिट का गहराई से निरीक्षण करते हैं। आप पा सकते हैं कि यह कई संभावित स्थितियों में से एक है, जिसमें शामिल हैं:

  1. प्रतिबद्ध ने सही मायने में कोड के ब्लॉक को पेश किया। कमेटी का लेखक उस शांत विशेषता का आविष्कारक था जिसके लिए आप इसकी उत्पत्ति का शिकार हो रहे थे (या दोषी पक्ष जिसने बग पेश किया था); या
  2. कोड का ब्लॉक फाइल में मौजूद नहीं था, लेकिन इसकी पांच समान प्रतियां अलग-अलग फाइलों में मौजूद थीं, जो सभी कमिटमेंट के बाद गायब हो गईं। एकल हेल्पर फ़ंक्शन की शुरुआत करके प्रतिबद्ध रिफलेक्टेड डुप्लिकेट कोड के लेखक; या
  3. (एक विशेष मामले के रूप में) प्रतिबद्ध होने से पहले, फ़ाइल में वर्तमान में जिस कोड में आप स्वयं रुचि रखते हैं, उसका ब्लॉक मौजूद नहीं था, लेकिन लगभग समान सामग्री वाली एक अन्य फ़ाइल मौजूद नहीं थी, और जिस कोड में आपकी रुचि है, उसका ब्लॉक। साथ में फ़ाइल में मौजूद अन्य सभी सामग्री वापस मौजूद थी, उस अन्य फ़ाइल में मौजूद थी। यह कमिट के बाद चला गया। कमेटी के लेखक ने इसे मामूली संशोधन देते हुए फाइल का नाम बदल दिया।

गिट में, लिनस का अंतिम सामग्री ट्रैकिंग टूल अभी तक पूरी तरह से स्वचालित फैशन में मौजूद नहीं है। लेकिन अधिकांश महत्वपूर्ण तत्व पहले से ही उपलब्ध हैं।

कृपया, हमें इस पर अपनी प्रगति के बारे में पोस्ट करते रहें।


उन लेखों को पोस्ट करने के लिए धन्यवाद। यह तब तक नहीं था जब तक मैंने उन्हें नहीं पढ़ा कि मैंने सामग्री इतिहास के विचार को पूरी तरह से समझ लिया है! मैं इस गलत तरीके के बारे में सोच रहा हूँ!
डेविडजी

लिनस का वह ईमेल बहुत अच्छा है, इसे पोस्ट करने के लिए धन्यवाद।
15:01 बजे mik01aj

मजेदार तथ्य, Git v2.15--color-moved उस "आदर्श ट्रैकिंग सिस्टम" की ओर एक कदम जोड़ता है। मैं इसके साथ खेल रहा था यह देखने के लिए कि यह एक फ़ाइल के भीतर स्थानांतरित लाइनों को ट्रैक करता है, लेकिन गलती से एहसास हुआ कि यह पटरियों ने पूरे अंतर
माइकल

2
लिनस एक जटिल स्थिति की व्याख्या करता है। लेकिन यहां हमारे पास एक सरल स्थिति है: एक फ़ाइल का नाम बदला गया था (या किसी अन्य निर्देशिका में स्थानांतरित किया गया था)। इस प्रकार एक सरल उपाय होना चाहिए। मुझे लगता है कि यह मुद्दा तोड़फोड़ के विपरीत तथ्य से आता है, उपयोगकर्ता जीआईटी को उस समय के लिए निर्देश नहीं दे सकता है जहां से एक फ़ाइल आती है, और यह --followगलत हो सकता है (उदाहरण के लिए, यदि 2 फ़ाइलों में एक ही सामग्री है, या यदि कोई संशोधन है फ़ाइल चाल के अलावा)।
vinc17

13

मैंने देखा कि अधिकांश ग्राफिकल गिट फ्रंट-एंड्स और आईडीई प्लगइन्स को फ़ाइल का नाम बदलने पर फ़ाइल का इतिहास प्रदर्शित करने में सक्षम नहीं लगता है।

आपको यह जानकर खुशी होगी कि कुछ लोकप्रिय Git UI टूल अब इसका समर्थन करते हैं। दर्जनों Git UI उपकरण उपलब्ध हैं इसलिए मैं उन सभी को सूचीबद्ध नहीं करूंगा, लेकिन उदाहरण के लिए:

  • SourceTree, जब एक फ़ाइल लॉग को देखते हैं, तो नीचे बाईं ओर एक चेकबॉक्स "नाम बदलें फ़ाइलों का पालन करें" है
  • TortoiseGit में बाईं ओर लॉग विंडो पर "follow renames" चेकबॉक्स है।

Git UI टूल के बारे में अधिक जानकारी:


एक बार नाम बदलने पर, दो बार नाम बदलने के लिए स्रोत बहुत अच्छा काम करता है, नाम बदलने से पहले बदलने के लिए विवरण उपलब्ध नहीं है। मैंने यहां बग की सूचना दी: jira.atlassian.com/browse/SRCTREE-5715
Intel

इतिहास में दो बार नाम बदलने पर भी gitk बढ़िया काम करता है। कमांड इस तरह दिखता है "gitk --follow path / to / file"
Intel

6

नोट: git 2.9 (June2016) में "छोटी गाड़ी" की प्रकृति में थोड़ा सुधार होगा git log --follow:

SZEDER गैबर ( ) द्वारा प्रतिबद्ध ca4e3ca (30 मार्च 2016) देखें । (द्वारा विलय Junio सी Hamano - - में प्रतिबद्ध 26effb8 , 13 अप्रैल 2016)szeder
gitster

diffcore: नाम बदलने का पता लगाने के दौरान समान फ़ाइलों का क्रम क्रम ठीक करें

यदि दो रास्तों ' dir/A/file' और ' dir/B/file' में समान सामग्री है और मूल निर्देशिका का नाम बदल दिया गया है, जैसे ' git mv dir other-dir', तो diffcoreनिम्न नामों को रिपोर्ट करता है:

renamed:    dir/B/file -> other-dir/A/file
renamed:    dir/A/file -> other-dir/B/file

(यहाँ उलटा ध्यान दें: B/file -> A/fileऔर A/file -> B/file)

जबकि तकनीकी रूप से गलत नहीं है, यह न केवल उपयोगकर्ता के लिए भ्रामक है, बल्कि नाम बदलने की जानकारी के आधार पर निर्णय लेने वाले git आदेशों के लिए भी है, उदाहरण के लिए नाम का "पिछले git log --follow other-dir/A/file" अनुसरण करता है dir/B/file

यह व्यवहार प्रतिबद्ध v2.0.0-rc4 ~ 8 ^ 2 ~ 14 का एक साइड इफेक्ट है ( diffcore-rename.c: सटीक नाम बदलने को सरल बनाएं, 2013-11-14): हैशमप स्टोरिंग स्रोत एक ही बाल्टी से प्रविष्टियां लौटाते हैं, अर्थात वर्तमान गंतव्य से मेल खाते स्रोत , LIFO क्रम में।
इस प्रकार पुनरावृत्ति पहले ' other-dir/A/file' और ' dir/B/file' की जांच करती है और समान सामग्री और बेसनेम खोजने पर, एक सटीक नाम बदल देती है।


2

लिनक्स पर, मैंने सत्यापित किया है कि SmartGit और GitEye किसी विशेष फ़ाइल के इतिहास का अनुसरण करते समय नाम बदलने में सक्षम है। हालाँकि, gitk और GitEye के विपरीत, SmartGit एक अलग फ़ाइल दृश्य और रिपॉजिटरी दृश्य दिखाता है (जिसमें निर्देशिका संरचना होती है, लेकिन फ़ाइलों की सूची नहीं होती है)

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