Git के साथ रिकॉर्ड फ़ाइल कॉपी ऑपरेशन


141

जब मैं git-mv का उपयोग करके किसी फ़ाइल को git में ले जाता हूं, तो स्थिति यह दिखाती है कि फ़ाइल का नाम बदल दिया गया है और भले ही मैं कुछ अंशों को बदल दूं, फिर भी इसे लगभग एक ही चीज़ माना जाता है (जो अच्छा है क्योंकि यह मुझे इसके इतिहास का पालन करने देता है) ।

जब मैं किसी फाइल की कॉपी करता हूं तो मूल फाइल में कुछ इतिहास होता है जिसे मैं नई कॉपी के साथ जोड़ना चाहता हूं।

मैंने फ़ाइल को स्थानांतरित करने की कोशिश की है, फिर मूल स्थान पर फिर से चेकआउट करने की कोशिश कर रहा है - एक बार ले जाने के बाद मुझे मूल स्थान की जाँच नहीं करने देगा।

मैंने एक फाइल सिस्टम कॉपी करने की कोशिश की है और फिर फाइल को जोड़ते हुए - git इसे एक नई फाइल के रूप में सूचीबद्ध करता है।

क्या एक तरह से फ़ाइल कॉपी ऑपरेशन रिकॉर्ड करने का कोई तरीका है कि कैसे यह एक फ़ाइल का नाम / चाल रिकॉर्ड करता है जहां इतिहास को मूल फ़ाइल में वापस खोजा जा सकता है?

जवाबों:


112

Git ट्रैकिंग का नाम नहीं बदलता है और न ही ट्रैकिंग की नकल करता है, जिसका अर्थ है कि यह नाम या प्रतियों को रिकॉर्ड नहीं करता है । इसके बजाय यह क्या करता है और नाम का पता लगाने की नकल है । आप विकल्प का उपयोग करके git diff(और git show) में नाम का पता लगाने का -Mअनुरोध कर सकते हैं, आप विकल्प का उपयोग करके परिवर्तित फ़ाइलों में अतिरिक्त प्रतिलिपि का पता लगाने का अनुरोध कर सकते हैं -C( -Cजिसका अर्थ है -M), या आप सभी फाइलों के बीच --find-copies-harderया -C -C(जिसका तात्पर्य है -C, जो अधिक महंगी प्रति का पता लगाने का अनुरोध कर सकते हैं , जिसका तात्पर्य है) -M)। Git-diff मैनपेज देखें ।

आप diff.renamesबूलियन सही मान (जैसे trueया 1) पर सेट करके हमेशा नाम का पता लगाने के लिए git को कॉन्फ़िगर कर सकते हैं , और आप git को कॉपी सेटिंग का पता लगाकर copyया उससे सेटिंग करके भी अनुरोध कर सकते हैं copiesGit-config manpage देखें ।

-lविकल्प git diffऔर संबंधित कॉन्फ़िगरेशन चर की भी जाँच करें diff.renameLimit


ध्यान दें कि git log <pathspec>Git में अलग तरह से काम करता है: यहाँ <pathspec>पथ परिसीमाओं का सेट है, जहाँ पथ उप (उप) निर्देशिका नाम हो सकता है। यह नाम बदलने और प्रतिलिपि का पता लगाने से पहले इतिहास को फ़िल्टर और सरल करता है । यदि आप नाम और प्रतियों का पालन करना चाहते हैं, तो उपयोग करें git log --follow <filename>(जो वर्तमान में थोड़ा सीमित है, और केवल एकल फ़ाइल के लिए काम करता है)।


1
@allyourcode: आप किस उलझन में हैं? डिफ़ॉल्ट रूप से आपके द्वारा निर्धारित (जैसे ' ') पर कॉपी डिटेक्शन चालू करने के diff.renamesलिए । मैं मानता हूं कि यह थोड़ा उल्टा है। copiesgit config diff.renames copies
जकुब नारबस्की

एक खंड जिसे मैं पार्स नहीं कर सकता हूं वह है "और आप डिफ़ॉल्ट रूप से भी नाम बदलने का अनुरोध कर सकते हैं"। क्या आप कह रहे हैं कि ऐसे चार मूल्य हैं जो diff.renames का उपयोग कर सकते हैं (सही, 1, कॉपी, कॉपी), और यह कि वे सभी एक ही काम करते हैं?
अल्लौरकोड

1
@allyourcode: मुझे क्षमा करें, मैंने इस पर ध्यान नहीं दिया। अब तय है, धन्यवाद।
जैकब नारęबस्की

4
@ peschü: Git एक रिपॉजिटरी स्टोरेज के रूप में कंटेंट-एड्रेस ऑब्जेक्ट डेटाबेस का उपयोग करता है। फ़ाइल सामग्री को पते के तहत 'बूँद' सामग्री में संग्रहीत किया जाता है जो सामग्री की SHA-1 हैश (अच्छी तरह से, टाइप + लंबाई + सामग्री) है। इसका मतलब है कि दी गई सामग्री केवल एक बार संग्रहीत की जाती है। नायब। यह स्वत: समर्पण "पैक" बैकअप सिस्टम बनाने के पीछे का कारण था, git पैक प्रारूप का उपयोग करना।
Jakub Nar

1
नीचे दिए गए समाधान के विपरीत, यह एक सीमा में परिवर्तन ट्रैकिंग के साथ काम नहीं करता है। गेट लॉग एक सीमा तर्क ( git log -L123,456:file.xyz) की अनुमति देता है जो ठीक से नाम का अनुसरण करता है, लेकिन प्रतियां नहीं, और आप उस मामले में पास नहीं कर सकते हैं; इसके अलावा, AFAICT, यह गिट दोष के साथ काम नहीं करता है।
क्लेमेंट

57

2020-05-19: निम्नलिखित समाधान में मूल फ़ाइल के लॉग को नहीं बदलने, मर्ज संघर्ष नहीं बनाने और कम होने के फायदे हैं।

आप तीन कमिट में कॉपी की गई फ़ाइल के इतिहास का पता लगाने के लिए Git को बाध्य कर सकते हैं:

  • कॉपी करने के बजाय, एक नई शाखा करने के लिए स्विच और ले जाने के अपने नए वहाँ स्थान के लिए फ़ाइल।
  • वहां मूल फाइल को फिर से जोड़ें।
  • नई शाखा को मूल शाखा में बिना तेजी से अग्रेषित विकल्प के साथ मिलाएं --no-ff

(क्रेडिट रेमंड चेन में जाते हैं ।)


पूर्व समाधान में चार कमिट थे:

  • कॉपी करने के बजाय, एक नई शाखा करने के लिए स्विच और ले जाने के अपने नए वहाँ स्थान के लिए फ़ाइल।
  • मूल शाखा में स्विच करें और फ़ाइल का नाम बदलें।
  • मूल शाखा में नई शाखा को मिलाएं, दोनों फाइलों को रखकर तुच्छ संघर्ष को हल करें।
  • एक अलग प्रतिबद्ध में मूल फ़ाइल नाम को पुनर्स्थापित करें।

(समाधान https://stackoverflow.com/a/44036771/1389680 से लिया गया ।)


7
सादगी, संक्षिप्तता, 100% ... यह जवाब सार्वजनिक सेवा है ... सब कुछ दृष्टि में रखते हुए
ptim

1
के बीच अंतर क्या moveऔर rename?
वॉन

@vovan क्या आप इस तथ्य का उल्लेख कर रहे हैं कि बाश में आप mvदोनों कार्यों के लिए उपयोग करेंगे ? मैं उस मामले के लिए 'चाल' का उपयोग कर रहा था जिसमें फ़ाइल की निर्देशिका को बदलना शामिल हो सकता है, और उस मामले के लिए 'नाम बदलें' जहां यह नहीं है।
रॉबर्ट पोलाक

1
मैंने इस (नई) रेसिपी को फॉलो करने की कोशिश की और यह काम नहीं किया। यदि आपने वास्तविक आदेश दिखाए तो यह मदद कर सकता है।
ग्रेग लिंडाहल

@RobertPollak मैंने इसके विभिन्न संस्करणों की कोशिश की है, लेकिन उन्होंने काम नहीं किया। "फ़ाइल को स्थानांतरित करें" से, क्या आपका मतलब है git mv orig new? "मूल पढ़ें" से, क्या आपका मतलब है cp new orig && git add orig?
। ᆼ ᆼ
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.