Git को फोर्स ओवरराइट के साथ मर्ज किया जाता है


100

मेरे पास एक शाखा है जिसे demoमुझे masterशाखा के साथ विलय करने की आवश्यकता है । मैं निम्नलिखित आदेशों के साथ वांछित परिणाम प्राप्त कर सकता हूं:

git pull origin demo
git checkout master
git pull origin master
git merge demo
git push origin master

मेरी एकमात्र चिंता यह है कि यदि कोई मर्ज समस्याएँ हैं , तो मैं मर्ज प्रॉम्प्ट दिए बिना शाखा gitमें परिवर्तन को लिखना चाहता हूं master। इसलिए मूल रूप से demoशाखा में परिवर्तन स्वचालित रूप से masterशाखा में परिवर्तन को अधिलेखित कर देना चाहिए ।

मैंने आसपास देखा कि कई विकल्प हैं लेकिन मैं विलय के साथ मौके नहीं लेना चाहता।


git push -f origin master
MD XF

4
@MDXF: हो सकता है कि मैं गलत हूं, लेकिन क्या मुझे कमांड के -fसाथ विकल्प का उपयोग नहीं करना चाहिए mergeऔर pushकमांड के साथ नहीं
ओपनस्टैक

आप दोनों की कोशिश कर सकते हैं और देख सकते हैं कि आपके लिए क्या काम करता है
MD XF

फोर्स ओवरराइट के समाधान के लिए नीचे दिए गए लिंक देखें: stackoverflow.com/a/42454737/984471
मनोहर रेड्डी पोरडे

जवाबों:


99

वास्तव में इस उत्तर से संबंधित नहीं है, लेकिन मैं खाई हूँ git pull, जो सिर्फ git fetchउसके बाद चलती है git merge। आप तीन मर्ज कर रहे हैं, जो आपके गिट रन को तीन लाने के लिए चल रहा है, जब एक भ्रूण आपको चाहिए होगा। अत:

git fetch origin   # update all our origin/* remote-tracking branches

git checkout demo         # if needed -- your example assumes you're on it
git merge origin/demo     # if needed -- see below

git checkout master
git merge origin/master

git merge -X theirs demo   # but see below

git push origin master     # again, see below

ट्रिकिएस्ट मर्ज को नियंत्रित करना

यहां सबसे दिलचस्प हिस्सा है git merge -X theirs। के रूप में root545 उल्लेख किया , -Xविकल्प मर्ज रणनीति को भेजी जाती हैं, और दोनों डिफ़ॉल्ट recursiveरणनीति और वैकल्पिक resolveरणनीति ले -X oursया -X theirs(एक या दूसरे, लेकिन दोनों नहीं)। यह समझने के लिए कि वे क्या करते हैं, हालांकि, आपको यह जानने की जरूरत है कि गिट कैसे पाता है, और व्यवहार करता है, संघर्षों को मर्ज करता है

एक मर्ज संघर्ष कुछ फ़ाइल 1 के भीतर हो सकता है जब आधार संस्करण दोनों वर्तमान (स्थानीय, HEAD, या --ours) संस्करण से भिन्न होता है और--theirs उसी फ़ाइल का दूसरा (दूरस्थ या दूरस्थ ) संस्करण भी कहा जाता है । अर्थात्, मर्ज ने तीन संशोधनों (तीन कमिट) की पहचान की है: आधार, हमारा और उनका। "बेस" संस्करण हमारी कमिट और उनकी कमिट के बीच मर्ज बेस से है , जैसा कि कमिट ग्राफ में पाया गया है (इस पर बहुत अधिक, अन्य स्टैकऑवरफ्लो पोस्टिंग देखें)। Git ने तब दो बदलाव किए हैं: "हमने क्या किया" और "उन्होंने क्या किया"। ये परिवर्तन (सामान्य रूप से) एक लाइन-बाय-लाइन पर पाए जाते हैं, विशुद्ध रूप से टेक्स्टुअलआधार। Git को फ़ाइल सामग्री की कोई वास्तविक समझ नहीं है; यह केवल पाठ की प्रत्येक पंक्ति की तुलना कर रहा है।

ये परिवर्तन वे हैं जो आप git diffआउटपुट में देखते हैं , और हमेशा की तरह, उनके संदर्भ भी हैं। यह संभव है कि जिन चीज़ों को हमने बदला है, वे उन चीज़ों से अलग-अलग रेखाओं पर हैं जिन्हें उन्होंने बदल दिया, ताकि परिवर्तन ऐसा लगे कि वे टकराए नहीं, लेकिन संदर्भ भी बदल गया है (उदाहरण के लिए, हमारे परिवर्तन फ़ाइल के ऊपर या नीचे होने के कारण, ताकि फ़ाइल हमारे संस्करण में चले, लेकिन उनके में, उन्होंने ऊपर या नीचे अधिक पाठ भी जोड़ा है)।

परिवर्तन पर होते हैं तो अलग अलग लाइनों के लिए उदाहरण के लिए, हम बदल colorकरने के लिए colourलाइन 17 पर और वे बदल जाते हैं fredकरने के लिए barneyलाइन पर 71 तो कोई विरोधाभास नहीं होगा: Git बस ले जाता है दोनों बदल जाता है। यदि परिवर्तन उसी तर्ज पर होते हैं, लेकिन समान परिवर्तन होते हैं , तो Git परिवर्तन की एक प्रति लेता है । केवल यदि परिवर्तन समान लाइनों पर हैं, लेकिन अलग-अलग परिवर्तन हैं, या संदर्भ के विशेष मामले में, क्या आपको संशोधित या संशोधित संघर्ष मिलता है।

-X oursऔर -X theirsहमारा, या उनकी: विकल्प कैसे इस विरोध को हल करने के लिए, बस दो परिवर्तनों में से एक को चुनकर Git बताओ। जब से तुम ने कहा कि आप विलय कर रहे हैं demo(उनकी) में master(हमारा) और से परिवर्तन चाहते हैं demo, तो आप चाहते हैं -X theirs

-Xहालांकि, ब्लाइंडली लगाना खतरनाक है। सिर्फ इसलिए कि हमारे परिवर्तनों ने लाइन-बाय-लाइन आधार पर संघर्ष नहीं किया, इसका मतलब यह नहीं है कि हमारे परिवर्तन वास्तव में संघर्ष नहीं करते हैं! चर घोषणाओं वाली भाषाओं में एक क्लासिक उदाहरण होता है। आधार संस्करण एक अप्रयुक्त चर घोषित कर सकता है:

int i;

हमारे संस्करण में, हम अप्रयुक्त चर को हटाते हैं ताकि संकलक चेतावनी चली जाए - और उनके संस्करण में, वे iलूप काउंटर के रूप में उपयोग करते हुए कुछ पंक्तियों को बाद में जोड़ते हैं । यदि हम दो परिवर्तनों को जोड़ते हैं, तो परिणामी कोड अब संकलित नहीं होता है। -Xविकल्प के बाद से परिवर्तन पर हैं यहाँ कोई मदद नहीं है अलग लाइनों

यदि आपके पास एक स्वचालित परीक्षण सूट है, तो मर्ज करने के बाद परीक्षण चलाने के लिए सबसे महत्वपूर्ण बात है। आप ऐसा करने के बाद कर सकते हैं, और बाद में ज़रूरत पड़ने पर चीजों को ठीक कर सकते हैं; या आप यह कर सकते से पहले करने से, जोड़कर --no-commitकरने के लिए git mergeआदेश। हम इस सभी विवरणों को अन्य पोस्टिंग के लिए छोड़ देंगे।


1 आप "फ़ाइल-वाइड" ऑपरेशन के संबंध में भी विरोध प्राप्त कर सकते हैं, उदाहरण के लिए, शायद हम एक फ़ाइल में एक शब्द की वर्तनी को ठीक करते हैं (ताकि हमारे पास एक बदलाव हो), और वे पूरी फ़ाइल को हटा दें (ताकि उनके पास एक हो हटाना)। -Xतर्क की परवाह किए बिना, Git इन संघर्षों को अपने दम पर हल नहीं करेगा ।


कम मर्ज और / या होशियार मर्ज और / या रिबास का उपयोग करना

हमारे दोनों कमांड सीक्वेंस में तीन मर्ज हैं। पहला origin/demoस्थानीय में लाना है demo(आपका उपयोग करता है git pull, यदि आपका Git बहुत पुराना है, तो अद्यतन करने में विफल रहेगा, origin/demoलेकिन उसी अंत में उत्पादन करेगा)। दूसरा लाना origin/masterहै master

यह मेरे लिए स्पष्ट नहीं है कि कौन अपडेट कर रहा है demoऔर / या master। यदि आप अपनी स्वयं की demoशाखा पर अपना कोड लिखते हैं , और अन्य लोग कोड लिख रहे हैं और इसे demoशाखा पर धकेल रहे हैं origin, तो इस पहले चरण के विलय से टकराव हो सकता है, या वास्तविक विलय हो सकता है। अधिक बार नहीं, काम को संयोजित करने के लिए (बजाय, यह स्वाद और राय का मामला है) मर्ज करने के बजाय, रिबास का उपयोग करना बेहतर है। यदि हां, तो आप git rebaseइसके बजाय उपयोग करना चाह सकते हैं । दूसरी ओर, यदि आप अपने स्वयं प्रतिबद्ध के किसी भी कभी नहीं पर demo, आप भी नहीं है की जरूरत है एक demoशाखा। वैकल्पिक रूप से, यदि आप इसे बहुत अधिक स्वचालित करना चाहते हैं, लेकिन यह ध्यान से जांचने में सक्षम हों कि आपके और अन्य लोगों द्वारा किए गए काम हैं, तो आप उपयोग करना चाहते हैंgit merge --ff-only origin/demo: यह यदि संभव हो तो demoअपडेट से मिलान करने के लिए आपके फास्ट-फॉरवर्ड करेगा origin/demo, और बस एकमुश्त विफल हो सकता है यदि नहीं (जिस बिंदु पर आप परिवर्तनों के दो सेटों का निरीक्षण कर सकते हैं, और एक वास्तविक मर्ज या उपयुक्त के रूप में एक रिबेस चुन सकते हैं)।

यह वही तर्क पर लागू होता है master, यद्यपि आप मर्ज कर रहे हैं पर master है, तो आप निश्चित रूप से एक की क्या ज़रूरत है master। हालांकि, यह भी संभावना है कि आप विलय को विफल करना चाहते हैं यदि यह तेजी से आगे गैर-मर्ज के रूप में नहीं किया जा सकता है, तो शायद यह भी होना चाहिए git merge --ff-only origin/master

मान लीजिए कि आप कभी भी अपना काम नहीं करते हैं demo। इस मामले में हम नाम को demoपूरी तरह से खोद सकते हैं :

git fetch origin   # update origin/*

git checkout master
git merge --ff-only origin/master || die "cannot fast-forward our master"

git merge -X theirs origin/demo || die "complex merge conflict"

git push origin master

यदि आप अपनी शाखा कर रहे हैं demo, तो यह मददगार नहीं है; आप मौजूदा मर्ज को रख सकते हैं (लेकिन हो सकता है --ff-onlyकि आप जो व्यवहार चाहते हैं उसके आधार पर जोड़ें ), या इसे रिबेस करने के लिए स्विच करें। ध्यान दें कि सभी तीन विधियां विफल हो सकती हैं: मर्ज एक संघर्ष के साथ विफल हो सकता है, मर्ज --ff-onlyतेजी से अग्रेषित करने में सक्षम नहीं हो सकता है, और रिबास एक संघर्ष के साथ विफल हो सकता है (रीबेस द्वारा काम करता है, संक्षेप में, चेरी-पिकिंग कमिट्स, जो मर्ज का उपयोग करता है मशीनरी और इसलिए एक मर्ज संघर्ष हो सकता है)।


19

मेरे पास एक समान मुद्दा था, जहां मुझे किसी भी फाइल को प्रभावी ढंग से बदलने की आवश्यकता थी जिसमें एक अलग शाखा के साथ परिवर्तन / संघर्ष था।

मुझे जो समाधान मिला वह उपयोग करना था git merge -s ours branch

ध्यान दें कि विकल्प है -sऔर नहीं -X। एक शीर्ष स्तर मर्ज रणनीति -sके oursरूप में उपयोग को दर्शाता है, मर्ज रणनीति -Xके oursविकल्प को लागू करेगा recursive, जो कि इस मामले में मैं (या हम) नहीं चाहता।

चरण, oldbranchवह शाखा कहां है जिसके साथ आप ओवरराइट करना चाहते हैं newbranch

  • git checkout newbranch उस शाखा की जाँच करें जिसे आप रखना चाहते हैं
  • git merge -s ours oldbranch पुरानी शाखा में विलीन हो जाता है, लेकिन हमारी सभी फाइलों को सुरक्षित रखता है।
  • git checkout oldbranch उस शाखा की जाँच करें जिसे आप अधिलेखित करना चाहते हैं
  • get merge newbranch नई शाखा में विलय हो जाता है, पुरानी शाखा को अधिलेखित कर देता है

नोट: यहां किसी भी अन्य समाधान ने मेरे लिए काम नहीं किया, इसलिए मैं अपना उत्तर पोस्ट कर रहा हूं।
Niall Mccormack

1
यह मेरे लिए काम नहीं किया। इसने संघर्ष को हल किया (विवादित फ़ाइलों को हल किया) लेकिन फ़ाइल को मर्ज नहीं किया गया है। और न ही विलय कर सकते हैं।
c-

यदि कोई ऐसा होता है, जहां आपको "यह मर्ज आवश्यक है, तो यह बताने के लिए कि कृपया एक संदेश लिखें"
11

17

यह मर्ज दृष्टिकोण संघर्ष या अन्य बकवास के बारे में शिकायत किए बिना, masterजो कुछ भी है feature, में चिपकाता है जिसके ऊपर एक प्रतिबद्ध करेगा ।

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

कुछ भी छूने से पहले

git stash
git status # if anything shows up here, move it to your desktop

अब मास्टर तैयार करो

git checkout master
git pull # if there is a problem in this step, it is outside the scope of this answer

featureसभी तैयार हो जाओ

git checkout feature
git merge --strategy=ours master

मारने के लिए जाओ

git checkout master
git merge --no-ff feature

1
खत्म करने के लिए धक्का धक्का
कोच

git-scm.com/docs/git-merge#Documentation/git-merge.txt-ours। यह तब काम करता था जब कमिट्स का सफाई से विलय नहीं होता था। लेकिन स्रोत के उद्धरण के लिए यह दृष्टिकोण हमेशा काम नहीं करेगा Changes from the other tree that do not conflict with our side are reflected in the merge result। यह मेरे लिए काम नहीं करता था, क्योंकि मैंने अपनी शाखा में साफ-सुथरे तरीके से विलय किया था, जिसे ओवरराइट किया जा रहा था। क्या कोई और तरीका है?
निहारघाट

11

आप git मर्ज में "हमारा" विकल्प आज़मा सकते हैं,

git मर्ज शाखा -X हमारा

यह विकल्प हमारे संस्करण के पक्ष में सफाई से स्वतः हल होने के लिए विरोधी हॉक को रोकता है। दूसरे पेड़ से परिवर्तन जो हमारे पक्ष के साथ संघर्ष नहीं करते हैं, मर्ज के परिणाम परिलक्षित होते हैं। एक बाइनरी फ़ाइल के लिए, पूरी सामग्री हमारी तरफ से ली गई है।


3
यह पीछे की ओर होगा, क्योंकि ओपी ने कहा कि वह चाहता है कि demoसंस्करण को पसंद किया जाए, भले ही वह विलय कर रहा हो master। वहाँ -X theirsभी है, लेकिन यह स्पष्ट नहीं है कि यह वही है जो ओपी वास्तव में चाहता है।
torek

आपने पूरे तरीके से नहीं पढ़ा है। आपका नोट बताता है कि विकल्प के oursसाथ बैकएंड पर उपयोग करने पर क्या होता -sहै। जब इसका उपयोग किया oursजाता है -X: यह दूसरे पेड़ पर किए गए सभी कामों का खुलासा करता है, हमारे इतिहास को घोषित करता है जिसमें यह सब होता है। source
जिमासून

2

जब मैंने उपयोग करने की कोशिश की -X theirsऔर अन्य संबंधित कमांड स्विच मैंने मर्ज किए गए कमिट किए। मैं शायद इसे सही ढंग से नहीं समझ रहा था। विकल्प को समझने में एक आसान बस शाखा को हटाना है फिर इसे ट्रैक करना है।

git branch -D <branch-name>
git branch --track <branch-name> origin/<branch-name>

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

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