एक रिपॉजिटरी से दूसरे में गिट पैच कैसे लागू करें?


80

मेरे पास दो रिपॉजिटरी हैं, एक लाइब्रेरी के लिए मुख्य रेपो है, और दूसरा उस लाइब्रेरी का उपयोग करने वाला प्रोजेक्ट है।

यदि मैं अधीनस्थ परियोजना में एक तय कर लेता हूं, तो मैं उस पैच को अपस्ट्रीम में लागू करना आसान तरीका चाहूंगा।

फ़ाइल का स्थान प्रत्येक रिपॉजिटरी में अलग है।

  • मुख्य रेपो: www.playdar.org/static/playdar.js
  • परियोजना: playlick.com/lib/playdar.js

मैंने git format-patch -- lib/playdar.jsplaylick प्रोजेक्ट पर उपयोग करने की कोशिश की , और फिर git amमुख्य playdar रेपो पर, लेकिन पैच फ़ाइल में भिन्न फ़ाइल स्थानों ने एक त्रुटि खड़ी की।

क्या किसी दिए गए फ़ाइल से किसी अन्य फ़ाइल में किसी अन्य मनमानी फ़ाइल पर पैच लागू करने का एक आसान तरीका है?

बोनस अंक के लिए, क्या होगा यदि आप जिस फाइल को पैच को लागू करना चाहते हैं वह एक गिट रिपॉजिटरी में नहीं है?


समान: प्रश्न: stackoverflow.com/questions/3367254/…
19

जवाबों:


117

तो मैन्युअल रूप से संपादित पैच फ़ाइल प्रश्न या अव्यवहार्य से बाहर है, यह मानक विकल्प (उपलब्ध में से किया जा सकता git apply, git format-patchऔर GNU patch)।

  1. -p<n>nपैच में पथ से अग्रणी निर्देशिकाओं को निकालता है ।

  2. प्रसंस्करण के बाद -p, --directory=<root>पहले जोड़ता rootलागू करने से पहले पैच में रास्तों में से प्रत्येक के लिए।

उदाहरण

तो, आपके उदाहरण के लिए, एक पैच लेने के लिए जो मूल रूप से चालू था static/playdar.jsऔर इसे लागू करने के लिए lib/playdar.js, आप दौड़ेंगे:

$ cat patch_file | git am     \ 
          -p1                 \ # remove 1 leading directory ('static/')
         --directory='lib/'     # prepend 'lib/'

1
इस शीर्ष उत्तर बनाने का कोई मौका? यह एक पैच फ़ाइल को मैन्युअल रूप से संपादित करने से कहीं अधिक आसान है।
वेस्टन

निश्चित रूप से, यह एक बेहतर / आसान उत्तर है, हालांकि @ araqnid का उत्तर अभी भी जानना अच्छा है।
जेम्स वीयर

पहली कोशिश के बिना निर्देशिका को समायोजित करने के लिए प्रासंगिक --directory: stackoverflow.com/questions/24121709/…
Ioannis Filippidis

38

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

उदाहरण के लिए, इसने कुछ इस तरह से उत्पादन किया होगा:

diff --git a/lib/playdar.js b/lib/playdar.js
index 1234567..89abcde
-- a/lib/playdar.js
++ b/lib/playdar.js

आपको बस इतना करना है कि इसके माध्यम से पैच lib/playdar.jsको बदलना हैstatic/playdar.jsgit am"

पैच लोग हैं, जो नहीं है के लिए मानक जीएनयू पैच उपयोगिता द्वारा पठनीय होना चाहिए git--- लेकिन नहीं चला format-patchके साथ -M, -C, उस मामले में नाम बदलने पैच का उत्पादन करने के लिए आदि विकल्पों क्योंकि उनके लिए समर्थन सार्वभौमिक नहीं है।


1
बाद में इस पृष्ठ को फिर से देखना ... यह पिछले "विजेता" की तुलना में पूछे गए प्रश्न का बेहतर उत्तर है जो सबमॉड्यूल्स का सुझाव देता है।
जेम्स वीयर

4

मान लें कि दोनों परियोजनाएं गिट परियोजनाएं हैं, तो ऐसा लगता है कि सबमॉड्यूल आपके लिए एकदम सही होगा। यह एक git प्रोजेक्ट को गतिशील रूप से किसी अन्य git प्रोजेक्ट से लिंक करने की अनुमति देता है, अनिवार्य रूप से एक git रेपो को एक अन्य git रेपो के अंदर बेक करते हुए, दोनों का अपना अलग जीवन होता है।

दूसरे शब्दों में, "मुख्य रेपो" को "प्रोजेक्ट" में एक सबमॉड्यूल के रूप में जोड़ें। जब भी आप "मुख्य रेपो" में नया सामान बनाते हैं, तो आप git pullउन्हें "प्रोजेक्ट" में वापस भेज देते हैं।


हम्म, सबमॉड्यूल डॉक्स के माध्यम से पढ़ने के बाद, यह "एक आसान तरीका" जैसा नहीं लगता है, हालांकि यह अच्छी तरह से सबसे मजबूत हो सकता है। ऐसा लगता है कि मुझे एक सबमॉड्यूल बनाना होगा जिसमें केवल playdar.jsफाइल हो, जिसमें दोनों अन्य प्रोजेक्ट्स शामिल हों (मुझे प्रोजेक्ट www.playdar.orgमें बाकी सब कुछ नहीं चाहिए playlick.com) मैं अब ईमानदारी से काम करने के लिए पैच फ़ाइलों को मैन्युअल रूप से संपादित करने का सहारा ले सकता हूं । या दोनों के बीच पेस्ट कॉपी करना जारी रखें। चीयर्स।
जेम्स वीयर

यहाँ एक स्पष्ट और पूरी तरह से ट्यूटोरियल है और इस सवाल पर ठोकर खाने वाले किसी अन्य व्यक्ति के लिए गिट सबमॉड्यूल के
जेम्स वीयर

2

हेनरिक के उत्तर को पूरा करने के लिए , और बोनस बिंदु के लिए जाने के लिए

क्या होगा यदि आप जिस फ़ाइल को पैच को लागू करना चाहते हैं वह गिट रिपॉजिटरी में नहीं है?

यदि आपके पास एक गिट रिपॉजिटरी से आने वाले पैच के लिए फ़ाइल उम्मीदवार की निर्देशिकाओं तक पहुंच है, तो आप पहले निर्देशिकाओं / फाइलों के उस पेड़ को एक गिट रिपॉजिटरी में बदल सकते हैं! (' git init': एक गिट रिपॉजिटरी एक रूट निर्देशिका के भीतर सिर्फ एक है। सब के बाद)।
फिर आप उस रेपो को अपने मुख्य प्रोजेक्ट के लिए सबमॉडल के रूप में सेट करेंगे।


2

का उपयोग --relativeकरने का विकल्प format-patchअमूर्त सुधार कर सकते हैं (भंडार है जहाँ से पैच जनरेट किया गया था के बारे में अप्रासंगिक विवरण को छिपाना)।

[repository-with-changes]
git format-patch --relative=(path-to-library) (base-commit-for-patch) ## 'HEAD~1'

मैंने --3wayपैच लगाने के दौरान ( does not exist in indexत्रुटि से बचने के लिए ) आवेदन करना आवश्यक पाया है - आपका माइलेज अलग-अलग हो सकता है। उपयोग करना --directory=(...)केवल तभी आवश्यक है जब आपका लक्ष्य पथ रिपॉजिटरी का मूल न हो।

[repository-to-update]
git am --3way --directory=(path-to-library) (patch-file)

  • format-patch 'आधार' के बाद से वर्तमान शाखा के प्रति प्रति एक पैच फ़ाइल बनाएगा।

  • --relativeविकल्प के लिए प्रलेखन कुछ मामलों में गायब लगता है , लेकिन यह वैसे भी काम करता प्रतीत होता है (संस्करण 2.7.4 के रूप में)।



1

आप अस्थायी रूप से मुख्य भंडार को हटा सकते हैं (नाम बदल सकते हैं)।

cd to/main/project
mv .git .git_
cd to/sub/project
git apply patchname
cd -
mv .git_ .git

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