किसी भिन्न नाम और पथ वाली फ़ाइल में Git पैच कैसे लागू करें?


100

मेरे पास दो रिपॉजिटरी हैं। एक में, मैं फ़ाइल में परिवर्तन करता हूँ ./hello.test। मैं बदलाव करता हूं और उस कमिटमेंट से एक पैच बनाता हूं git format-patch -1 HEAD। अब, मेरे पास एक दूसरा रिपॉजिटरी है जिसमें एक फाइल है जिसमें हेल्लो के समान सामग्री है। लेकिन एक अलग नाम के तहत एक अलग निर्देशिका में रखा गया है ./blue/red/hi.test:। मैं hi.testफ़ाइल में पूर्वोक्त पैच लागू करने के बारे में कैसे जाना है ? मैंने कोशिश की, git am --directory='blue/red' < patch_fileलेकिन निश्चित रूप से शिकायत करता है कि फ़ाइलों को नाम नहीं दिया गया है (जो मुझे लगा कि गिट के बारे में परवाह नहीं है?)। मुझे पता है कि मैं शायद उस विशिष्ट फ़ाइल पर लागू करने के लिए अंतर को संपादित कर सकता हूं, लेकिन मैं एक कमांड समाधान की तलाश कर रहा हूं।


जवाबों:


97

आप पैच का उपयोग करके बना सकते हैं git diffऔर फिर इसे patchउपयोगिता का उपयोग करके लागू कर सकते हैं , जो आपको उस फ़ाइल को निर्दिष्ट करने की अनुमति देता है जिसे आप अंतर को लागू करना चाहते हैं।

उदाहरण के लिए:

cd first-repo
git diff HEAD^ -- hello.test > ~/patch_file

cd ../second-repo
patch -p1 blue/red/hi.test ~/patch_file

7
आह, अच्छा, यह नहीं सोचा था। हालांकि, Git कमांड के साथ ऐसा करने का कोई तरीका है ताकि डेटा (दिनांक और समय, प्रतिबद्ध लेखक, प्रतिबद्ध संदेश) को समान रखा जाए?
Mart1n

2
यह वहाँ कुछ आप के साथ क्या कर सकते हैं कि संभव है amया applyहै, लेकिन मैं यह नहीं मिल सकता है। यदि आप अपने आप को बहुत कुछ बदलते हुए डुप्लिकेट पाते हैं, तो सबमॉड्यूल का उपयोग करके एक बेहतर समाधान हो सकता है, या आपकी पसंद की भाषा कोड साझा करने के लिए प्रदान करती है (उदाहरण के लिए रूबी में आप एक रत्न के रूप में डुप्लिकेट कोड निकाल सकते हैं)।
जॉर्जियो

1
यह वास्तव में प्रलेखन-संबंधित (स्रोत फ़ाइलें XMLs हैं)। Submodules वास्तव में एक विकल्प नहीं हैं क्योंकि मुझे अपने मौजूदा बुनियादी ढांचे में उनके लिए एक मजबूत मामला बनाना होगा।
Mart1n

52

एक सरल समाधान है जिसमें मैनुअल पैच संपादन शामिल नहीं है और न ही बाहरी स्क्रिप्ट।

पहली रिपॉजिटरी में (यह कमिट की एक सीमा भी निर्यात कर सकता है, -1यदि आप केवल एक कमिट का चयन करना चाहते हैं तो उपयोग करें):

git format-patch --relative <committish> --stdout > ~/patch

दूसरे भंडार में:

git am --directory blue/red/ ~/patch

इसके बजाय का उपयोग करने का --relativeमें git format-patch, एक और समाधान का उपयोग करने के लिए है -p<n>विकल्प में git amपट्टी करने के लिए nके रूप में एक में उल्लेख किया है, पैच के पथ से निर्देशिका एक ऐसी ही सवाल का जवाब

यह भी git format-patch --relative <committish>बिना चलाने के लिए संभव है --stdout, और यह .patchफ़ाइलों का एक सेट उत्पन्न करेगा । इन फ़ाइलों को तो सीधे खिलाया जा सकता है git amके साथ git am --directory blue/red/ path/to/*.patch


9
यह अभी भी इस तथ्य पर निर्भर करता है कि फ़ाइल नाम समान हैं, है ना?
Mart1n

3
यह ध्यान दिया जाना चाहिए कि --directoryविकल्प रेपो रूट के सापेक्ष निर्देशिका के पूर्ण पथ को निर्दिष्ट करने के लिए आवश्यक है; कुछ ऐसा है --directory=./जबकि रेपो में एक उपनिर्देशिका में chdir'd काम नहीं करेगा।
रीड करें

1
का उपयोग करने में --3wayमदद करता है does not exist in index:git am --3way --directory (relative-path) (patch)
ब्रेंट बर्नबर्न

-kकमिट मैसेज की पहली लाइन को स्ट्रिप न करने के लिए दोनों कमांड में की का प्रयोग करें ।
रुविम

का उपयोग करते हुए --3wayन केवल के साथ मदद करता है त्रुटियों "सूचकांक में मौजूद नहीं है" (@nobar द्वारा उठाई बाहर के रूप में), लेकिन यह भी सफाई से संभाल मर्ज संघर्ष करने के लिए आप की अनुमति देता है। विवादित फ़ाइलों को अछूता छोड़ने के बजाय, एक संघर्ष खंड जोड़ा जाता है जिसे तब हल किया जा सकता है।
डैनियल वुल्फ

11

एक स्क्रिप्ट के साथ मेरे अपने प्रश्न का उत्तर देना जो बस यही करता है: https://github.com/mprpic/apply-patch-pile-ile

पैच फ़ाइल को मैन्युअल रूप से संशोधित करने के बजाय, यह उपयोगकर्ता को लक्ष्य फ़ाइल के लिए संकेत देता है, पैच को संशोधित करता है और इसे उस रेपो पर लागू करता है जो आप वर्तमान में कर रहे हैं।


5

@Georgebrock द्वारा जवाब पर निर्माण, यहाँ एक समाधान मैं इस्तेमाल किया है:

सबसे पहले, पैच फ़ाइलों को हमेशा की तरह बनाएं (जैसे। git format-patch commitA..commitB)।

फिर सुनिश्चित करें कि आपका लक्ष्य भंडार साफ है (इसमें कोई बदली हुई या बिना पड़ी फाइलें नहीं होनी चाहिए) और इस तरह पैच लागू करें:

cd second-repo
git am ~/00*.patch

प्रत्येक पैच फ़ाइल के लिए आपको "त्रुटि: XYZ इंडेक्स में मौजूद नहीं है" जैसी त्रुटि मिलेगी। अब आप इस पैच फ़ाइल को मैन्युअल रूप से लागू कर सकते हैं:

patch --directory blue/red < ~/0001-*.patch
git add -a
git am --continue

आपको प्रत्येक पैच फ़ाइल के लिए ये तीन चरण करने होंगे।

यह किसी विशेष git format-patchआदेश की आवश्यकता के बिना या पैच फ़ाइलों को संपादित किए बिना मूल प्रतिबद्ध संदेश आदि को संरक्षित करेगा ।


1
अच्छा जवाब, मुझे लगता है कि यह "गैर-मानक" पैच हेरफेर के लिए सबसे अच्छा आधार है। मैं इसे 3 चरणों में करता हूं। (1) पाठ के लिए प्रतिबद्ध - git format-patch -1 commitA --stdout > thing.diff; (2) पैच फ़ाइल को तब तक संपादित करें जब तक यह वह नहीं करेगा जो मुझे चाहिए; (३) पाठ ऐसा करने के लिए git am --3way thing.diff जिसका लाभ यह है कि आप पैच के उन हिस्सों को स्वीकार कर सकते हैं जो सफाई से लागू होते हैं, और gitउन हिस्सों के लिए मानक संघर्ष समाधान प्रक्रिया का उपयोग नहीं करते हैं जो नहीं करते हैं।
वी आर ऑल मोनिका

2

मैं समझता हूं कि दो फाइलें आपकी स्थिति में बिल्कुल समान हैं, इस प्रकार पैच के सफल होने की संभावना है।

हालाँकि, यदि आप पैच को एक समान लागू करना चाहते हैं, लेकिन ठीक उसी फ़ाइल में नहीं, या आप एक इंटरैक्टिव पैचिंग करना चाहते हैं, तो आप तीन तरह के मर्ज का उपयोग करेंगे।

आप फ़ाइल संशोधित कहो A, आइए निरूपित A~1पिछले संस्करण के रूप में है, और आप के बीच अंतर को लागू करना चाहते A~1करने के लिए Aफ़ाइल के लिए B

एक तीन रास्ता मर्ज टूल खोलें, उदाहरण के लिए बियॉन्ड तुलना, बाएं पैनल का मार्ग है A, मध्य पैनल सामान्य पूर्वज है इसलिए पथ है A~1, दाएं पैनल का पथ है B। फिर, कम पैनल से पता चलता है के बीच अंतर को लागू करने के परिणाम A~1के लिए Aफ़ाइल के लिए B

निम्नलिखित आंकड़ा विचार दिखाता है।

यहां छवि विवरण दर्ज करें


0

FYI करें: मुझे हाल ही में Github से एक पैच डाउनलोड करने और इसे एक स्थानीय फ़ाइल (जो एक नए स्थान पर "ओवरराइड" था) में लागू करने की कोशिश करने में समस्याएँ हुईं।

git amपैच को लागू नहीं किया जाएगा क्योंकि फ़ाइल "इंडेक्स में नहीं" या "गंदा" है। लेकिन, मैंने पाया कि साधारण patchकमांड पैच को लागू कर सकता है । इसने मुझे फ़ाइल का नाम पैच करने के लिए संकेत दिया।

वैसे भी हो गया काम ...

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