Git में किसी विशिष्ट कमिट को कैसे मर्ज करें


1034

मैंने GitHub में एक भंडार से एक शाखा ली है और मेरे लिए कुछ विशिष्ट किया है। अब मैंने पाया कि मूल भंडार में एक अच्छी विशेषता थी जो कि थी HEAD

मैं इसे पिछले कमिट के बिना ही मर्ज करना चाहता हूं। मुझे क्या करना चाहिए? मुझे पता है कि सभी कमिट को कैसे मर्ज किया जाता है:

git branch -b a-good-feature
git pull repository master
git checkout master
git merge a-good-feature
git commit -a
git push

यदि आप इसे github के संबंध में करने का प्रयास कर रहे हैं, तो यह लेख आपको इसके माध्यम से बताएगा। markosullivan.ca/how-to-handle-a-pull-request-from-github
johndpope

जवाबों:


1173

' git cherry-pick' यहाँ आपका उत्तर होना चाहिए।

मौजूदा प्रतिबद्ध द्वारा शुरू किए गए परिवर्तन को लागू करें।

इस पोस्ट में चेरी-पिकिंग के परिणाम के बारे में बोल्डन के जवाब को पढ़ना न भूलें :
"एक शाखा से सभी को खींचो, निर्दिष्ट दूसरे पर धक्का दें" , जहां:

A-----B------C
 \
  \
   D

हो जाता है:

A-----B------C
 \
  \
   D-----C'

इस प्रतिबद्ध के साथ समस्या यह है कि गिट उनके सामने सभी इतिहास को शामिल करने के लिए प्रतिबद्ध मानते हैं

जहां C 'की एक अलग SHA-1आईडी है।
इसी तरह, चेरी को एक शाखा से दूसरी शाखा में ले जाने के लिए मूल रूप से एक पैच उत्पन्न करना शामिल है, फिर इसे लागू करना, इस प्रकार उस तरह से इतिहास को खोना।

कमिट आईडी के इस बदलाव से अन्य चीजों के बीच जीआईटी की विलय की कार्यक्षमता टूट जाती है (हालांकि यदि संयम से इस्तेमाल किया जाता है, तो ऐसे आंकड़े हैं जो इस पर पेपर करेंगे)।
हालांकि इससे भी महत्वपूर्ण बात यह है कि यह कार्यात्मक निर्भरता को नजरअंदाज करता है - यदि C वास्तव में B में परिभाषित फ़ंक्शन का उपयोग करता है, तो आप कभी नहीं जान पाएंगे


1
@ openid000: "अधिक महीन दाने वाली शाखाएँ": जो वास्तव में वही है जो उनके उत्तर में सुझाई गई थी।
VonC

8
नोट: "गिट रीबेस" भी SHA-1 को बदलता है। "Git rebase बनाम git मर्ज ( stackoverflow.com/questions/804115/git-rebase-vs-git-merge ) और" git वर्कफ़्लो "( stackoverflow.com/questions/45792727-… ) उन मामलों के लिए भी देखें जहाँ" git rebase "वैध है।
वॉनसी

1
"ठीक दाने वाली शाखाओं", "चेरी-पिक" और "रिबास" के बीच, फिर आपके पास गिट के साथ शाखाओं में कोड के प्रबंधन के लिए सभी संभावनाएं होंगी।
VonC

@VonC "ठीक दाने वाली शाखाएँ" हाँ। मेरी दो शाखाएँ थीं और मैंने एक शाखा में एक विशेष विज़ुअलाइज़ेशन मॉड्यूल में अपग्रेड किया था। यह मॉड्यूल अन्य सभी कोड से स्वतंत्र था, इसलिए चेरी-पिक अन्य शाखाओं में भी इन परिवर्तनों को लागू करने के लिए सुविधाजनक था
चीकू

1
लेकिन ध्यान दें कि जब आप विलय करते हैं, तो कमिट सी और सी दोनों प्रतिबद्ध इतिहास में प्रबल होंगे।
राहुल शाह

738

आप अपनी वर्तमान शाखा के लिए एकल प्रतिबद्ध लागू करने के लिए गिट चेरी-पिक का उपयोग कर सकते हैं।

उदाहरण: git cherry-pick d42c389f


68
चेरी लेने पर आपकी पूर्व पोस्ट के लिए +1 ( stackoverflow.com/questions/880957/… )। मैंने अपने स्वयं के उत्तर में इसके एक उद्धरण की प्रतिलिपि बनाने के लिए स्वतंत्रता ली।
वॉनक

4
शायद git cherry-pick d42cया git cherry-pick d42c3 काम आएगा। गिट स्मार्ट है। ;)
गनियस

2
घातक: बुरा संशोधन
Ievgen Naida

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

1
दुर्भाग्य से यह सवाल का जवाब नहीं देता है: यह वास्तव में एक मर्ज नहीं बनाता है। कोई पुश्तैनी इशारा नहीं है d42c389f। हो सकता है कि ओपी एक बनाने के बारे में परवाह नहीं है मर्ज असल, लेकिन अंतर बात कभी कभी होता है।
लार्स

29

आइए एक उदाहरण लें और समझने की कोशिश करें:

मेरे पास एक शाखा है, जो मास्टर का कहना है , X <प्रतिबद्ध-आईडी> की ओर इशारा करता है, और मेरे पास Y <sha1> की ओर इशारा करते हुए एक नई शाखा है।

जहां Y <प्रतिबद्ध-आईडी> = <मास्टर> शाखा शुरू होती है - कुछ कमिट्स

अब Y ब्रांच के लिए कहें कि मुझे मास्टर ब्रांच और नई ब्रांच के बीच कमिट्स को गैप-ऑफ करना है। नीचे वह प्रक्रिया है जिसका हम अनुसरण कर सकते हैं:

चरण 1:

git checkout -b local origin/new

जहां स्थानीय शाखा नाम है। कोई भी नाम दिया जा सकता है।

चरण 2:

  git merge origin/master --no-ff --stat -v --log=300

मास्टर ब्रांच से नई ब्रांच में कमिट्स मर्ज करें और साथ ही एक मैसेज के साथ लॉग मैसेज की एक कमिट कमिटमेंट बनाएं जिसमें से ज्यादातर <n> एक्चुअल कमिट्स जो मर्ज किए जा रहे हैं।

Git मर्ज के बारे में अधिक जानकारी और मापदंडों के लिए, कृपया यहां देखें:

git merge --help

इसके अलावा, अगर आपको किसी विशिष्ट कमेट को मर्ज करने की आवश्यकता है, तो आप इसका उपयोग कर सकते हैं:

git cherry-pick <commit-id>

क्या आपने Yअपने 3 डी वाक्य की परिभाषा बदल दी है ? "मेरे पास Y की ओर इशारा करने वाली एक नई शाखा है" बनाम "अब Y शाखा के लिए कहें", ऐसा लगता है कि Y एक कमिट हुआ करता था और फिर यह एक शाखा बन गई
प्यूरफैन

मैं उस शाखा के एक निश्चित कमिट बिंदु से कैसे कर सकता हूं जिसे मैं विलय करना चाहता हूं
कुलभूषण सिंह

3

मेरे उपयोग के मामले में हमें CI सीडी की समान आवश्यकता थी। हमने विकसित और मास्टर शाखाओं के साथ गिट प्रवाह का उपयोग किया। डेवलपर्स एक सुविधा शाखा से पुल अनुरोध के माध्यम से सीधे विकसित होने या बदलने के लिए विलय करने के लिए स्वतंत्र हैं। हालांकि, मास्टर के लिए हम जेनकींस के माध्यम से स्वचालित तरीके से विकसित शाखा से केवल स्थिर मर्ज करते हैं।

इस मामले में चेरी-पिक करना एक अच्छा विकल्प नहीं है। हालाँकि हम कमिट-आईडी से एक स्थानीय-शाखा बनाते हैं, फिर उस स्थानीय-शाखा को मास्टर करने और mvan क्लीन वेरिफिकेशन करने के लिए मर्ज करते हैं (हम मावेन का उपयोग करते हैं)। यदि सफलता है तो स्थानीय संस्करण के साथ मावेन रिलीज प्लगइन का उपयोग करके नेक्सस के लिए उत्पादन संस्करण विरूपण साक्ष्य जारी करें = सही विकल्प और पुशचेंज = गलत। अंत में जब सब कुछ सफल हो जाता है तो परिवर्तनों और मूल को टैग करें।

एक नमूना कोड स्निपेट:

यदि आप मैन्युअल रूप से किया जाता है, तो आप मास्टर पर हैं। हालांकि, जेनकिंस पर, जब आप रेपो की जांच करते हैं तो आप डिफ़ॉल्ट शाखा पर होंगे (यदि कॉन्फ़िगर किया गया है)।

git pull  // Just to pull any changes.
git branch local-<commitd-id> <commit-id>  // Create a branch from the given commit-id
git merge local-<commit-id>  // Merge that local branch to master.
mvn clean verify   // Verify if the code is build able
mvn <any args> release:clean release:prepare release:perform // Release artifacts
git push origin/master  // Push the local changes performed above to origin.
git push origin <tag>  // Push the tag to origin

यह आपको एक निडर मर्ज या संघर्ष नरक के साथ एक पूर्ण नियंत्रण देगा।

यदि कोई बेहतर विकल्प है तो सलाह देने के लिए स्वतंत्र महसूस करें।


3

प्रमुख उत्तर यह बताते हैं कि किसी विशिष्ट समिति से वर्तमान शाखा में परिवर्तनों को कैसे लागू किया जाए । यदि आप "मर्ज कैसे करें" से इसका मतलब है, तो वे चेरी-पिक का उपयोग करें जैसा कि वे सुझाव देते हैं।

लेकिन अगर आप वास्तव में एक मर्ज चाहते हैं , यानी आप दो माता - पिता के साथ एक नई प्रतिबद्धता चाहते हैं - वर्तमान शाखा पर मौजूदा कमिटमेंट, और जिस कमिटमेंट से आप बदलाव लागू करना चाहते थे - तब एक चेरी-पिक वह पूरा नहीं करेगी।

सही मर्ज का इतिहास होना वांछनीय हो सकता है, उदाहरण के लिए, यदि आपकी निर्माण प्रक्रिया नवीनतम टैग (उपयोग git describe) के आधार पर स्वचालित रूप से संस्करण स्ट्रिंग सेट करने के लिए गिट वंश का लाभ लेती है ।

चेरी-पिक के बजाय, आप एक वास्तविक कर सकते हैं git merge --no-commit, और फिर किसी भी परिवर्तन को हटाने के लिए इंडेक्स को मैन्युअल रूप से समायोजित कर सकते हैं जो आप नहीं चाहते हैं।

मान लीजिए कि आप शाखा में हैं Aऔर आप शाखा की नोक पर कमेट को मर्ज करना चाहते हैं B:

git checkout A
git merge --no-commit B

अब आप दो अभिभावकों के साथ कमिटमेंट बनाने के लिए तैयार हैं, वर्तमान टिप कमेंट Aऔर B। हालाँकि, आप अपनी इच्छा से अधिक परिवर्तन लागू कर सकते हैं, जिसमें B शाखा में पहले से किए गए परिवर्तन शामिल हैं। आपको इन अवांछित परिवर्तनों को पूर्ववत करने की आवश्यकता है, फिर प्रतिबद्ध करें।

(वर्किंग डायरेक्टरी की स्थिति और इंडेक्स को वापस मर्ज करने से पहले सेट करने का एक आसान तरीका हो सकता है, ताकि आपके पास एक क्लीन स्लेट हो, जिस पर आप पहली बार में जो कमिटमेंट चाहते थे उसे चेरी-पिक कर सकें। लेकिन ... मुझे नहीं पता कि उस साफ स्लेट को कैसे हासिल किया जाए git checkout HEADऔर git reset HEADदोनों इस विधि के उद्देश्य को हराकर मर्ज की स्थिति को दूर करेंगे।)

इसलिए अवांछित परिवर्तनों को मैन्युअल रूप से पूर्ववत करें। उदाहरण के लिए, आप कर सकते थे

git revert --no-commit 012ea56

प्रत्येक अवांछित प्रतिबद्ध के लिए 012ea56

जब आप चीजों को समायोजित करना समाप्त कर लें, तो अपनी प्रतिबद्धता बनाएं:

git commit -m "Merge in commit 823749a from B which tweaked the timeout code"

अब आपके पास केवल वही परिवर्तन है जो आप चाहते थे, और पूर्वजों के पेड़ से पता चलता है कि आप तकनीकी रूप से बी से विलय कर चुके हैं।

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