2013-05-27 8 views
32

पुलिंग मुझे मेरी स्थिति का वर्णन करते हैं:Git: एक रिबेस शाखा

श्री गोरा और श्री ऑरेंज शाखा एक उस पर मास्टर शाखा से बाहर शाखाओं प्रतिबद्ध एम 1 पर काम कर रहे हैं। शाखा ए में 2 काम हैं: ए 1 और ए 2।

M1 
    \ 
    \ 
    A1 - A2 

इस बीच, श्री ऑरेंज ने मास्टर शाखा, एम 2 और एम 3 पर 2 और प्रतिबद्धताओं को प्रतिबद्ध और धक्का दिया।

M1 - M2 - M3 
    \ 
    \ 
    A1 - A2 

श्री गोरा रिमोट से खींचती है, और थोड़ी देर के मास्टर शाखा पर rebase करने का फैसला करता बाद:

M1 - M2 - M3 
    \   \ 
    \   \ 
    A1 - A2 A1` - A2` 

अब A1` और A2` रिबेस प्रतिबद्ध है कि श्री गोरा के पर स्थानीय रूप से मौजूद हैं, और ए 1 और ए 2 दूरस्थ रूप से मौजूद हैं। मिस्टर ब्लॉन्ड ने अपने बदलावों को मजबूर करने और इतिहास को फिर से लिखने के लिए -f का उपयोग करके अपनी प्रतिबद्धताओं को धक्का दिया। अब रिमोट रिपोजिटरी इस तरह दिखता है:

M1 - M2 - M3 
      \ 
       \ 
       A1` - A2` 

लेकिन श्री ऑरेंज ने भी एक शाखा पर काम किया। उनके स्थानीय भंडार अभी भी इस तरह दिखता है:

M1 - M2 - M3 
    \ 
    \ 
    A1 - A2 

क्या श्री ऑरेंज क्रम में करने के लिए दूरदराज के भंडार में एक शाखा के साथ सिंक्रनाइज़ करने की आवश्यकता है?

एक सामान्य पुल काम नहीं करेगा। पुल-एफ स्थानीय रूप से रिमोट से परिवर्तन को मजबूर करेगा? मुझे पता है कि ए के स्थानीय संस्करण को हटाने और रिमोट रिपोजिटरी से इसे फिर से लाने से यह चाल चल जाएगी लेकिन यह हासिल करने का एक अच्छा तरीका प्रतीत नहीं होता है।

उत्तर

21

मेरी सिफारिश (या, "अगर मैं श्रीमान ऑरेंज था तो मैं क्या करूंगा") git fetch से शुरू होता है। अब मेरे पास यह मेरे रेपो में होगा, जो श्री ब्लॉन्ड ने अपने रिबेस के बाद और "गिट पुश-एफ" चलाने से ठीक पहले किया था।

M1 - M2 - M3 
    \   \ 
    \   \ 
    A1 - A2 A1' - A2' 

एक महत्वपूर्ण अंतर यह है, मैं ए 2 फिरना की ओर इशारा करते अपने स्थानीय लेबल A होगा, और दूरदराज के लेबल remotes/origin/A ए 2 की ओर इशारा करते '(श्री गोरा यह दूसरी तरह के आसपास, स्थानीय लेबल A की ओर इशारा करते था ए 2 'और remotes/origin/A ए 2 को इंगित करता है)।

मैं नामित शाखा के अपने प्रति पर काम किया गया है 'ए' मैं इस बजाय होगा:

M1 ---- M2 ---- M3 
    \    \ 
    \    \ 
    A1 - A2 - A3 A1' - A2' 

(अपने स्थानीय लेबल ए 3 के बजाय ए 2 की ओर इशारा करते के साथ; या A4 या A5 , आदि, इस पर निर्भर करता है कि मैंने कितने बदलाव किए हैं।) अब मुझे बस ए 2 पर अपने ए 3 (और यदि आवश्यक हो, आदि) को दोबारा करना है। एक स्पष्ट सीधा रास्ता:

$ git branch -a 
    master 
* A 
    remotes/origin/master 
    remotes/origin/A 
$ git branch new_A remotes/origin/A 
$ git rebase -i new_A 

और फिर छोड़ revs A1 और A2 पूरी तरह से, के बाद से संशोधित लोगों A1 के रूप में new_A 'और A2' में हैं। या:

$ git checkout -b new_A remotes/origin/A 
$ git format-patch -k --stdout A3..A | git am -3 -k 

(git am -3 -k विधि git-format-patch मैनुअल पेज में वर्णित है)।

ये पता लगाना है कि मैं क्या है कि श्री गोरा से पहले वह अपने rebase, यानी, A1, A2, A3, आदि

की पहचान दूसरा दृष्टिकोण सफल रहा अंत है, तो किया नहीं किया है की आवश्यकता होती है:

M1 ---- M2 ---- M3 
    \    \ 
    \    \ 
    A1 - A2 - A3 A1' - A2' - A3' 

जहाँ मेरे शाखा का नाम ए 3 के लिए new_A अंक '(अपने मौजूदा A शाखा अभी भी पुराने ए 3 के लिए अंक)। यदि मैं पहले दृष्टिकोण का उपयोग करता हूं और यह सफल होता है, तो मैं एक ही चीज़ के साथ समाप्त होता हूं, यह सिर्फ मेरी मौजूदा शाखा का नाम A अब ए 3 को इंगित करेगा (और मेरे पास ए 1-ए 2-ए 3 के साथ पुरानी शाखा का कोई नाम नहीं है, यहां तक ​​कि हालांकि यह अभी भी मेरे रेपो में है; इसे खोजने के लिए इसे रीफ्लॉग या इसी तरह से जाना आवश्यक है)।

बेशक

(मेरी A3 जरूरतों ए 3 ', दोनों इंटरैक्टिव रिबेस और "Git बजे" विधि निश्चित रूप से मेरे द्वारा काम करते हैं, की आवश्यकता होगी बनने के लिए। संशोधन हैं) यह भी संभव करने के लिए सिर्फ git merge (के रूप में गैरी Fixler द्वारा जवाब में), लेकिन यह किसी मर्ज के लिए प्रतिबद्ध ("एम" कोई संख्या के साथ, नीचे) और revs A1 रखने और A2 दिखाई पैदा करेगा, दे रही है:

M1 ---- M2 ---- M3 
    \    \ 
    \    \ 
    A1 - A2 - A3 A1' - A2' -- M 
       \_______________/ 

आप मूल A1 संरक्षित करने के लिए चाहते हैं और ए 2, यह एक अच्छी बात है; अगर आप उनसे छुटकारा पाना चाहते हैं, तो यह एक बुरी चीज है। तो "क्या करना है" इस पर निर्भर करता है कि "आप परिणाम क्या चाहते हैं"।

जोड़ने के लिए संपादित करें: मुझे प्रारूप-पैच विधि बेहतर पसंद है क्योंकि यह मेरे पुराने ए शाखा नाम को छोड़ देता है जबकि मैं सुनिश्चित करता हूं कि सब कुछ अच्छा है।

$ git branch -m A old_A 
$ git branch -m new_A A 

और फिर, अगर old_A पूरी तरह से छोड़ दिया जा सकता है:: यह मान लिया जाये कि सब काम करता है और अच्छा है, यहाँ पिछले कुछ कदम है

$ git branch -D old_A 

या, समतुल्य रूप, शुरू शाखा के साथ हटाने के लिए, तो ए के new_A नाम बदलने

(संपादित करें: यह भी देख git rebase --onto प्रलेखन, ए 3, आदि, रिबेसिंग new_A शाखा पर के लक्ष्य के लिए।)

30

श्री ऑरेंज अपने परिवर्तनों को खोने मन नहीं करता है, तो वह सर्वर से है, तो प्राप्त कर सके git checkout A2 अपने स्थानीय A2 शाखा पर प्राप्त करने के लिए, तो उसका A2 को पुनर्स्थापित करने के लिए git reset --hard origin/A2 (दूरस्थ मानते हुए "मूल" नाम दिया गया है) जहां रिमोट का A2 है।

यदि वह परिवर्तन खोने से चिंतित है, तो वह उन्हें हल करने के लिए सर्वर के परिवर्तनों को विलय कर सकता है (अपने A2 शाखा से, और फिर से मान लिया जाता है कि रिमोट को "मूल" नाम दिया गया है) git merge origin/A2 के साथ। यह एक नई प्रतिबद्धता बनाएगा जो कि उनके और रिमोट की A2 शाखाओं के शीर्ष पर है, दोनों एक साथ विलय के परिवर्तन के साथ। फिर इसे रिमोट पर वापस धकेल दिया जा सकता है।

+1

नोट: '--' और 'hard' के बीच कोई सफेद जगह नहीं है - मुझे थोड़ी देर लग गई, क्योंकि उत्तर दो स्क्रीन के बीच मेरी स्क्रीन पर लपेटा गया था :) – qbolec

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