git: एक रेपो में दूसरे रेपो में किए गए परिवर्तनों को लागू करें


115

मैं एक है repo1और repo2स्थानीय मशीन पर। वे बहुत समान हैं, लेकिन उत्तरार्द्ध किसी तरह की अन्य शाखा है ( repo1अब इसे बनाए नहीं रखा गया है)।

/path/to/repo1 $ git log HEAD~5..HEAD~4
<some_sha> Add: Introduce feature X

में किए गए परिवर्तनों को कैसे लागू <some_sha>किया repo1जाए repo2?

क्या मुझे कुछ पैच तैयार करने की आवश्यकता है, या क्या cherry-pickरेपो के बीच कुछ करना संभव है ?

कैसे के बारे में एक ही है, लेकिन करने की सीमा के लिए?


2
क्या आप केवल repo1 से repo2 तक नहीं खींच सकते?
18

थोड़े अधिक विशिष्ट मामले के लिए, जहाँ आप किसी एक रिपॉजिटरी में स्थानांतरित की गई फ़ाइल या फ़ाइलों में परिवर्तन लागू करना चाहते हैं, यहाँ देखें: stackoverflow.com/questions/3491270/…
ब्रह्मा स्नाइडर

जवाबों:


31

हैक के रूप में, आप GitTips पृष्ठ पर दो अलग-अलग रिपॉजिटरी में कमिट्स की तुलना करने के लिए नुस्खा संशोधित करने का प्रयास कर सकते हैं , अर्थात:

GIT_ALTERNATE_OBJECT_DIRECTORIES=../repo/.git/objects \
git cherry-pick $(git --git-dir=../repo/.git rev-parse --verify <commit>)

जहाँ ../repoअन्य रिपॉजिटरी के लिए रास्ता है।

आधुनिक गिट के साथ आप चेरी-पिक के साथ कई संशोधनों और संशोधन श्रेणियों का उपयोग कर सकते हैं ।

$(git --git-dir=../repo/.git rev-parse --verify <commit>) अनुवाद करने के लिए यहाँ है <commit>(उदाहरण के लिए HEAD, या v0.2, या master~2, जो दूसरी भंडार आप से कॉपी में मान रहे हैं) के लिए प्रतिबद्ध का SHA-1 पहचानकर्ता में। यदि आप किसी परिवर्तन के SHA-1 को जानते हैं जिसे आप चुनना चाहते हैं, तो यह आवश्यक नहीं है।

नोट करें कि Git स्रोत रिपॉजिटरी से ऑब्जेक्ट्स को कॉपी करना छोड़ सकता है, क्योंकि यह नहीं जानता कि वैकल्पिक ऑब्जेक्ट रिपॉजिटरी केवल एक ऑपरेशन के लिए अस्थायी है। आपको दूसरी रिपॉजिटरी से वस्तुओं को कॉपी करने की आवश्यकता हो सकती है:

GIT_ALTERNATE_OBJECT_DIRECTORIES=../repo/.git/objects git repack -a -d -f

यह उन वस्तुओं को मूल भंडार में दूसरे भंडार से उधार लेता है

टेस्ट नहीं हुआ।


एक ऐसा घिनौना उपाय नहीं है कि वह उत्तर का पालन करे :

  • दूसरे रिपॉजिटरी पर जाएं, जहां से आप कमिट्स कॉपी करना चाहते हैं, और उन कमेंट्स से पैच जनरेट करना चाहते हैं, जिन्हें आप चाहते हैं git format-patch
  • वैकल्पिक रूप से, अपने रिपॉजिटरी में पैच (0001- * आदि) कॉपी करें
  • git am --3wayपैच लगाने के लिए उपयोग करें

1
अच्छा काम करता है। अगर आपको कमिटमेंट में समस्या है तो 'जीआईटी रीसेट हेड' करें; git add। '
गुमिक

5
यह बहुत बढ़िया है - आप कमिट की एक श्रृंखला कैसे करेंगे? बस sha1 ... sha2?
hvgotcodes

मुझे भी मिलता है fatal: unable to read tree ...लेकिन git reset HEAD^सब कुछ ठीक होने के बाद
jmarceli

@hvgotcodes ने मेरे लिए बस सीमा पार करके काम किया <commit>लेकिन rev-parse --verifyकमांड को यह पसंद नहीं है क्योंकि यह केवल एकल प्रतिबद्ध मूल्यों को स्वीकार करता है। लेकिन जैसा cherry-pickकि एकल और श्रेणी दोनों प्रतिबद्ध मूल्यों को स्वीकार करता है, मैं पूछता हूं: क्यों rev-parseआवश्यक है?
Chuim

1
@Chuim: git rev-parseयदि आप एक का उल्लेख करना चाहते हैं अन्य भंडार है, जैसे अपने रेफरी आधारित नाम से प्रतिबद्ध की जरूरत है master, HEAD^^, या ऐसा ही कुछ; Rev-parse इसे सार्वभौमिक SHA-1 पहचानकर्ता में बदल देता है।
जैकब नारबस्की

207

आप शायद उपयोग करना चाहते हैं git format-patchऔर फिर git amउस पैच को अपने भंडार में लागू करना चाहते हैं ।

/path/to/1 $ git format-patch sha1^..sha1
/path/to/1 $ cd /path/to/2
/path/to/2 $ git am -3 /path/to/1/0001-…-….patch

या, एक पंक्ति में:

/path/to/2 $ git --git-dir=/path/to/1/.git format-patch --stdout sha1^..sha1 | git am -3

9
यह समाधान प्रत्यक्ष चेरी-पिकिंग GIT_ALTERNATE_OBJECT_DIRECTORIES(जो कि मेरे भंडार को भ्रष्ट करेगा) के स्वीकृत उत्तर की तुलना में सरल और सुरक्षित साबित हुआ ।
चुइम

2
जब संघर्ष होते हैं तो यह काम नहीं करेगा क्योंकि यह दूसरी शाखा पर आने वाले कामों को खोजने में विफल रहता है।
रोजर

2
कमांड में जोड़ने --ignore-whitespaceसे git amकोई भी विवाद हल हो सकता है और 3-वे मर्ज करने की आवश्यकता से बच सकते हैं
ह्यूगथ

97

आप कर सकते हैं cherry-pickयदि आप दूसरे रेपो को रिमोट के रूप में पहले (और फिर fetch) में जोड़ते हैं ।


11
यह वास्तव में इसे करने का उचित तरीका है।
विल्बर्ट

5
यह मेरे लिए भी सही तरीका लगता है। और मैंने अभी इसका इस्तेमाल किया है और इसने मेरे लिए अच्छा काम किया है।
रिकी नेल्सन

11
मैं बल्कि कहूंगा: git fetch [remote-name]दूसरे रेपो में और फिर git cherry-pick [sha1]

5
इस दृष्टिकोण ने मेरे लिए बहुत काम किया, धन्यवाद। चूंकि दूसरा रेपो भी स्थानीय था, बस इसे रिमोट के रूप में जोड़ते समय एक फाइल यूआरआई का उपयोग करना था।
palimpsestor

2
मेरे मामले में, मेरे पास एक विशाल रिमोट गिट रिपॉजिटरी के दो क्लोन हैं (समानांतर काम करने की अनुमति देने के लिए), जिसका अर्थ है कि इसका सभी इतिहास पहले से ही डाउनलोड किया हुआ है और मेरे एचडी में दो बार संग्रहीत है। अगर मुझे प्रत्येक को दूसरे के रिमोट के रूप में जोड़ना होगा, तो इससे एक ही इतिहास की दो अतिरिक्त प्रतियां बन सकेंगी और इससे पहले कि मैं सक्षम हो जाऊं, उनके बीच समकालिकता की आवश्यकता होगी cherry-pick। तो भले ही यह "सही" तरीके से महसूस हो सकता है, यह हमेशा सबसे व्यावहारिक नहीं है।
चुइम

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