2015-02-20 13 views
6

प्रतिबद्ध एक विषय शाखा पर काम खत्म करने के बाद, मैं विषय शाखा मास्टर में निम्नलिखित की तरह विलय कर दिया:Git: रिबेसिंग एक विरोध हुआ मर्ज

  o---*---o---o topic 
     /   \ 
o---o---o---*---o---o---+ master 

The '*' के साथ चिह्नित करता है एक ही कोड को संशोधित किया है, इसलिए नेतृत्व विलय विलय प्रतिबद्धता में हल किए गए संघर्षों को मर्ज करने के लिए ('+' के साथ चिह्नित)।

जब मैं विलय कर दिया और संघर्ष का समाधान हो, मेरे सहकर्मी नई प्रतिबद्ध धक्का दिया गुरु ('एन' के रूप में चिह्नित), निम्नलिखित इतिहास में जिसके परिणामस्वरूप:

  o---*---o---o topic 
     /   \ 
o---o---o---*---o---o---+ master 
        \ 
        n---n origin/master 

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

  1. फेंक दूर अपने काम, मूल/मास्टर के लिए मास्टर रीसेट और मर्ज फिर से करना। मैं इससे बचना चाहता हूं क्योंकि मुझे फिर से संघर्षों को हल करना होगा।

  2. मूल/मास्टर और पुश पर मास्टर रीबेज करें। यहां मेरी समस्या आती है: यह रीबेस करना (-p स्विच का उपयोग करते समय भी) आसानी से काम नहीं करता है, विलय प्रतिबद्धता फिर से एक ही संघर्ष दिखाती है, भले ही नई प्रतिबद्धता ('एन') ने विषय शाखा द्वारा छूए कुछ भी नहीं बदला । इसलिए मैं रिबेस के दौरान फिर से विवादों को सुलझाने के होगा और हल करने के लिए बिना विकल्प 1.

साथ के रूप में एक ही परिणाम होता है मैं प्राप्त करने के लिए मर्ज के लिए प्रतिबद्ध '+' रिबेसिंग है चाहेंगे फिर से विरोध करता है:

  o---*---o---o-------- topic 
     /     \ 
o---o---o---*---o---o---n---n---+ master & origin/master 

संपादित करें:

rerere स्विच सक्षम है, लेकिन किसी भी तरह से मदद करने के लिए नहीं मालूम था; क्या मुझे अपनी समस्या को ठीक करने के लिए config.rerere को सही करने के लिए कुछ और करना है?

संपादित करें 2:

विलय मूल/मास्टर भी (के रूप में टिप्पणियाँ और एक जवाब में प्रस्तावित) काम करेगा लेकिन बदसूरत इतिहास का एक प्रकार है जो मैं करने के लिए नेतृत्व करेंगे करने के लिए मर्ज-लिखें ('+') डी केवल एक विलय प्रतिबद्ध होने से बचने के लिए पसंद है।

+0

आप इसे नए मास्टर के विलय से पहले मूल/मास्टर को भी पीछे छोड़ सकते हैं। – ScayTrase

+0

@ScayTrase यह संभव होगा, लेकिन एक तरह का बदसूरत इतिहास का कारण बन जाएगा; मैं केवल एक विलय प्रतिबद्धता के साथ स्वच्छ समाधान पसंद करूंगा केवल – rhabarbersaft

+0

दुर्भाग्यवश, इसमें से कोई वास्तविक तरीका नहीं है: इससे कोई फर्क नहीं पड़ता कि आप अपने दो विकल्पों में से कौन से विकल्प चुनते हैं, आपको सबसे अधिक बार फिर से संघर्षों को हल करना होगा। यदि आप उम्मीद करते हैं कि आप भविष्य में एक ही स्थिति में खुद को पा लेंगे, तो आपको शायद ['rerere'] सक्रिय करने पर विचार करना चाहिए (http://stackoverflow.com/questions/25670519/git-rebase-preserve-merges-fails/ 25671230 # 25671230)। – Jubobs

उत्तर

0

क्या होगा यदि आप मास्टर के शीर्ष पर विषय rebase, तो मास्टर पिछले करने के लिए रीसेट करने और दूरदराज से खींच, ताकि आप इस होगा:

  o---*---o---o 
     /   \ 
o---o---o---*---o---o---+ topic 
        \ 
        n---n master & origin/master 

और फिर आप मास्टर में विषय विलय, इसके परिणामस्वरूप (नया विलय प्रतिबद्ध '#' के साथ चिह्नित):

  o---*---o----o 
     /   \ 
o---o---o---*---o---o----+ topic 
        \  \ 
        n--n--# master 

क्या इससे विवाद पैदा होते हैं? क्या यह आपके लिए काम करेगा?

+0

मैं इस' बदसूरत 'इतिहास को रोकना चाहता हूं और केवल एक विलय प्रतिबद्धता – rhabarbersaft

1

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

चूंकि आप जानते हैं कि आपके सहयोगी के परिवर्तनों ने उन समस्याओं को प्रभावित नहीं किया है जिन्हें आपने हल किया था। आप एक नई शाखा बना सकते हैं (हम इसे conflict-fix) अपने वर्तमान मास्टर ऑफ मास्टर से कॉल कर सकते हैं। अपनी शाखा रीसेट करें और मर्ज फिर से करें।

git mergetool या जो भी संपादक आप उपयोग करते हैं, उसका उपयोग करने के बजाय। आप git checkout conflict-fix -- <file names> का उपयोग कर फ़ाइल को अपनी दूसरी शाखा से मास्टर में ला सकते हैं। git add फाइलें और विलय को पूरा करने के लिए प्रतिबद्ध हैं। फिर आप conflict-fix शाखा को हटा सकते हैं।

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

संपादित

मैं git rerere साथ पूरी तरह से परिचित नहीं हूँ, लेकिन है कि काम किया जाना चाहिए था। हालांकि आपकी टिप्पणी के आधार पर, आपको रीबेज करने की आवश्यकता नहीं है। आप अभी भी विलय प्रतिबद्धता को पूर्ववत कर चुके हैं, git fetch अपडेट और मर्ज फिर से प्रदर्शन किया। आपको केवल git rerere कमांड को कॉल करना होगा और यह आपके लिए फ़ाइलों में संघर्षों का समाधान करेगा। अपने पेड़ इस तरह लग रही के साथ:

  o---*---o---A topic 
     /   \ 
o---o---o---*---o---o---+ master 
       \ 
        n---n origin/master 

आप निम्न करना होगा:

git reset --hard A 
git checkout master 
git pull 
git merge topic 
git rerere 
//Fix other conflicts 
git push 

और आप के साथ खत्म करना चाहिए:

  o---*---o---o-------- topic 
     /     \ 
o---o---o---*---o---o---n---n---+ master & origin/master 

कुछ भी rebase की कोई जरूरत नहीं होनी चाहिए।

http://git-scm.com/docs/git-rerere

+0

है यह बढ़िया काम करता है। लेकिन: यदि उत्पत्ति/मास्टर ने एक ही फ़ाइल में परिवर्तन किया है जो विवादों ('*' में संशोधित) का कारण बनता है लेकिन अन्य लाइनों पर (अतिरिक्त विलय विवादों की ओर अग्रसर नहीं होता है), तो मैं उन परिवर्तनों को वापस कर दूंगा यदि मैं केवल 'संघर्ष-फिक्स' चेकआउट करता हूं 'विरोधी फाइलों के विचलन। इसलिए मैं अभी भी गिट के साथ एक समाधान की खोज कर रहा हूं जो मैंने पहले विलय में किए गए संघर्ष समाधान को फिर से लागू कर रहा है (और मैंने सोचा कि 'rerere' ऐसा करेगा) – rhabarbersaft

+0

दुर्भाग्यवश' rerere' इस मामले में काम नहीं करता है, बस कोशिश की यह सुनिश्चित करने के लिए फिर से। यह पहली बार विलय करते समय 'रिकॉर्ड किया गया संकल्प ...' कहता है लेकिन प्रस्तावित के रूप में फिर से विलय करते समय कुछ भी नहीं करता है। – rhabarbersaft

0

rerere तरीका यह किया जा रहा है इस तरह के एक परेशानी से बचने के लिए है, लेकिन यह आप मदद नहीं करता है अगर आपने इसे सक्षम करने से पहले आप पहले मर्ज किया था नहीं था। आप यह जान सकते हैं कि यह सक्षम है या नहीं, क्योंकि यह 'रिकॉर्डिंग प्रीमेज'

के बारे में संदेश देगा, मैंने हाल ही में इस में भाग लिया क्योंकि मेरे पास एक नई विकास मशीन थी और बदसूरत विलय से पहले पुन: सक्षम करने के लिए भूल गई थी। इस परिदृश्य के लिए केवल एक महान गिट समाधान नहीं है, लेकिन निम्नलिखित स्थिति में सबसे आसान वसूली निम्न है जिसके साथ मैं आ सकता हूं।

  1. सुनिश्चित करें कि आपके कार्यशील निर्देशिका वास्तव में मर्ज परिणाम (Git रीसेट प्रमुख --hard) ही है और यह आपके मर्ज से स्रोत पेड़ कॉपी प्रतिबद्ध कहीं सुरक्षित
  2. किसी भी मर्ज किए गए प्रतिबद्ध करने से पहले अपने स्थानीय शाखा रीसेट (Git रीसेट --hard मास्टर ~ या Git रीसेट HEAD ~ n जहां n आप कितनी दूर वापस जाने की जरूरत है)
  3. Git खींच
  4. Git मर्ज विषय
  5. प्रतिलिपि स्रोत अपने काम पेड़ ओवरराइटिंग में वापस फ़ाइलें।
  6. Git mergetool
  7. प्रतिबद्ध (किसी भी संशोधित संघर्ष बनाम नष्ट कर दिया संभाल करने) और धक्का

जब से हम Gerrit साथ काम कर रहे थे मैं भी सुनिश्चित करें कि बदलें-ईद एक ही था मेरे पिछले मर्ज के रूप में इतना प्रतिबद्ध मैं सत्यापित कर सकता था कि कुछ भी गलत नहीं हुआ था।

संबंधित मुद्दे