Git: एक विद्रोही शाखा खींचना




push rebase (2)

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

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

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

अगर मैं "A" नाम की शाखा की अपनी कॉपी पर काम कर रहा हूँ, तो इसके बजाय मेरे पास यह होगा:

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

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

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

और फिर A1 और A2 को पूरी तरह से छोड़ देता है, क्योंकि संशोधित नए A1 'और 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 से पहले ए 1, ए 2, ए 3, आदि की पहचान नहीं की।

यदि दूसरा दृष्टिकोण सफल होता है, तो मैं इसके साथ समाप्त होता हूं:

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

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

(अगर मेरे ए 3 को ए 3 बनने के लिए संशोधन की आवश्यकता है, तो इंटरएक्टिव रीबेस और "जीट एम" विधि दोनों को मेरे द्वारा काम करने की आवश्यकता होगी, बिल्कुल)।

निश्चित रूप से यह केवल git merge करना संभव है (जैसा कि गैरी फिक्सलर द्वारा उत्तर में है), लेकिन यह एक मर्ज कमिट (बिना नंबर के नीचे "एम" बना देगा) और ए 1 और ए 2 को दृश्यमान रखता है, जो दे रहा है:

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

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

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

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

और फिर, अगर old_A को पूरी तरह से छोड़ दिया जा सकता है:

$ git branch -D old_A

या, समान रूप से, शाखा को हटाने के साथ शुरू करें, फिर new_A से A का नाम बदलें।

(संपादित करें: new_S शाखा पर A3, आदि को पुन: पेश करने के लक्ष्य के लिए git rebase --onto प्रलेखन भी देखें।)

मुझे अपनी स्थिति का वर्णन करने दें:

श्री ब्लोंड और मि। ऑरेंज शाखा ए पर काम कर रहे हैं जो कि मास्टर ब्रांच से बाहर एम 1 पर शाखाएं हैं। ब्रांच A में 2 कमिट हैं: A1 और A2।

M1  
   \
    \
     A1 - A2

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

M1  - M2 - M3
   \
    \
     A1 - A2

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

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

अब ए 1 `और ए 2` रिबूट किए गए कमिट हैं जो स्थानीय रूप से मिस्टर ब्लॉन्ड में मौजूद हैं, और ए 1 और ए 2 दूर से मौजूद हैं। श्री ब्लोंड ने अपने बदलावों और "इतिहास को फिर से लिखने" के लिए बल का उपयोग करते हुए अपने कमिट्स को आगे बढ़ाया । अब दूरस्थ रिपॉजिटरी इस तरह दिखता है:

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

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

M1  - M2 - M3
   \
    \
     A1 - A2

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

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


मैं कॉन्फ़िगरेशन उद्देश्यों के लिए दो आभासी मशीनों पर समवर्ती रूप से विकसित करता हूं। नतीजतन, मैं अक्सर एक मशीन पर रिबेट करता हूं और बिना किसी कठिनाई के दूसरे पर दिखाई देने वाले परिवर्तनों की आवश्यकता होती है।

मान लीजिए कि मेरी शाखा का नाम feature/my-feature-branch । पहले वीएम पर रिबास खत्म करने के बाद, मैं दूसरे पर एक जीआईटी प्राप्त करता हूं। निम्न संदेश प्रकट होता है:

$ git status
On branch feature/my-feature-branch
Your branch and 'origin/feature/my-feature-branch' have diverged,
and have 21 and 24 different commits each, respectively.
  (use "git pull" to merge the remote branch into yours)

ठीक है, एक पुल पुलिंग मत करो, क्योंकि तब आप काफी हद तक उपद्रव के बाद एक व्यर्थ मर्ज कमिटमेंट के साथ समाप्त होते हैं।

इसके बजाय, भागो

git rebase -i origin/feature/my-feature-branch

एक बार जब पाठ संपादक पॉप अप हो जाता है, तो सभी कमिट्स को हटा दें, और इसे निम्नलिखित के साथ बदलें (यह बनाता है ताकि रिबास बिना किसी कमिट के पूरा हो जाए)।

exec echo test

यदि आपके पास कमिट हैं जिन्हें रखने की आवश्यकता है, तो उन्हें यहां लागू किया जा सकता है। या तो मामले में, रिबास पूरा हो जाएगा, और अब दोनों मशीनें फिर से सिंक में हैं, जैसा कि इसका सबूत है:

$ git pull
Already up-to-date.
$ git push
Everything up-to-date




pull