(संपादित करें, 30 नवंबर 2016: भी Why is git rebase discarding my commits? को this answer देखना अब यह कांटा सूत्री विकल्प की वजह से लगभग निश्चित है कि है।।)
वहाँ मैनुअल और pull
आधारित git rebase
(कम अब 2.7 की तुलना में वहाँ Git git merge-base
में --fork-point
विकल्प predating के संस्करणों में थे) के बीच कुछ मतभेद हैं। और, मुझे संदेह है कि आपके स्वचालित संरक्षित-विलय शामिल हो सकते हैं। यह सुनिश्चित करना थोड़ा मुश्किल है लेकिन तथ्य यह है कि आपकी स्थानीय शाखा आपकी अन्य स्थानीय शाखा का पालन करती है जो कि पुनः प्राप्त हो रही है, काफी सुझावशाली है। इस बीच, पुराने git pull
स्क्रिप्ट को हाल ही में सी में भी लिखा गया था, इसलिए यह देखना मुश्किल है कि यह क्या करता है (हालांकि आप पर्यावरण परिवर्तनीय GIT_TRACE
को 1
पर सेट कर सकते हैं ताकि गिट आपको कमांड दिखाए क्योंकि यह आंतरिक रूप से चलता है)।
किसी भी मामले में, वहाँ दो या तीन प्रमुख आइटम यहाँ (आप कैसे गिनती के आधार पर मैं इसे 3 में बना देंगे और इन अलग,) कर रहे हैं:
git pull
रन git fetch
, तो या तो git merge
या git rebase
प्रति निर्देश, लेकिन जब यह git rebase
चलाता है तो यह "अपस्ट्रीम रीबेस से पुनर्प्राप्त" करने के लिए नई फोर्क-पॉइंट मशीनरी का उपयोग करता है।
जब git rebase
कोई तर्क नहीं है तो इसमें एक विशेष मामला है जो फोर्क-पॉइंट मशीनरी का आह्वान करता है। तर्कों के साथ चलने पर, फोर्क-पॉइंट मशीनरी को तब तक अक्षम कर दिया जाता है जब तक कि --fork-point
के साथ स्पष्ट रूप से अनुरोध नहीं किया जाता है।
जब git rebase
को विलय को संरक्षित करने के लिए निर्देश दिया जाता है, तो यह इंटरैक्टिव रीबेस कोड (गैर-इंटरैक्टिव) का उपयोग करता है। मुझे यकीन नहीं है कि यह वास्तव में यहां मायने रखता है (इसलिए ऊपर "शामिल हो सकता है)। आम तौर पर यह विलय को दूर करता है और केवल इंटरैक्टिव रीबेस स्क्रिप्ट में उन्हें संरक्षित करने के लिए कोड होता है (यह कोड वास्तव में विलय करता है क्योंकि उनके साथ सौदा करने का कोई अन्य तरीका नहीं है)।
यहां सबसे महत्वपूर्ण वस्तु (निश्चित रूप से) कांटा बिंदु कोड है। यह कोड प्रतिबद्ध ग्राफ के भाग को चित्रित करके दिखाए गए मामलों को संभालने के लिए रीफ्लॉग का उपयोग करता है। करता
... - A - B - C - D - E <-- origin/foo
\
I - J - K <-- foo
जहां A
और B
हैं आप था जब आप अपने शाखा (ताकि B
merge- है शुरू कर दिया:
एक सामान्य (जरूरत नहीं कांटा बिंदु सामान) rebase मामले में आप कुछ इस तरह है आधार), C
E
git fetch
के माध्यम से रिमोट से उठाए गए नए काम हैं, और I
K
के माध्यम से आपकी खुद की प्रतिबद्धताएं हैं। रीबेस कोड I
K
के माध्यम से प्रतिलिपि बनाता है, पहली प्रति को E
पर जोड़ता है, दूसरा प्रतिलिपि I
, और तीसरा से प्रति-0 -।
Git बाहर या आंकड़े के लिए इस्तेमाल किया, वैसे भी जोgit rev-list origin/foo..foo
उपयोग करते हुए, यानी, अपने वर्तमान शाखा (foo
) के नाम का उपयोग K
खोजने के लिए और पीछे की ओर काम करने के लिए नकल करने के लिए प्रतिबद्ध है, और इसकी नदी के ऊपर के नाम (origin/foo
) E
खोजने के लिए और पीछे की ओर काम करें। पीछे की ओर मार्च मर्ज आधार पर रुक जाता है, इस मामले B
में, और की नकल की परिणाम इस प्रकार है:
... - A - B - C - D - E <-- origin/foo
\ \
\ I' - J' - K' <-- foo
\
I - J - K [[email protected]{1}: reflog for foo]
इस विधि के साथ समस्या तब होती है जब upstream- origin/foo
यहाँ-है ही रिबेस। आइए, उदाहरण के लिए, origin
पर किसी ने बल-धक्का दिया ताकि B
को एक नई प्रति B'
द्वारा अलग-अलग प्रतिबद्ध शब्दों के साथ प्रतिस्थापित किया गया हो (और शायद एक अलग पेड़ भी हो, लेकिन, हमें आशा है कि कुछ भी नहीं जो हमारे I
-through- K
को प्रभावित करता है)।प्रारंभिक बिंदु अब इस तरह दिखता है:
B' - C - D - E <-- origin/foo
/
... - A - B <-- [origin/[email protected]{n}]
\
I - J - K <-- foo
git rev-list origin/foo..foo
का उपयोग करना, हम चुनेंगे करता B
, I
, J
, और K
कॉपी करने के लिए, और E
हमेशा की तरह के बाद उन पर पेस्ट करने की कोशिश; लेकिन हम B
की प्रतिलिपि बनाने के लिए नहीं चाहते हैं क्योंकि यह वास्तव में origin
से आया है और इसकी अपनी प्रति B'
से प्रतिस्थापित किया गया है।
origin
के लिए रीफ्लॉग को देखने के लिए फोर्क पॉइंट कोड क्या होता है यह देखने के लिए कि B
कुछ समय तक पहुंच योग्य था या नहीं। यही कारण है, यह नहीं की जाँच करता है बस origin/master
, लेकिन यह भी origin/[email protected]{1}
(E
और B'
वापस करने के लिए और फिर A
स्कैनिंग खोजने) (B
के लिए सीधे ओर इशारा करते हुए, शायद, आप कितनी बार git fetch
चलाने के आधार पर), origin/[email protected]{2}
, और इतने पर। कोई भी foo
पर पहुंचता है जो से पहुंच योग्य हैorigin/[email protected]{n}
ग्राफ में सबसे कम आम पूर्वज नोड खोजने में विचार के लिए शामिल किया गया है (यानी, वे सभी मर्ज बेस बनने के विकल्प के रूप में माना जाता है जो git merge-base
प्रिंट आउट करता है)।
(यहां एक प्रकार का दोष दिखने लायक है: यह स्वचालित फोर्क पॉइंट डिटेक्शन केवल उन चीजों को ढूंढ सकता है जो रिफ्लॉग प्रविष्टि बनाए रखा गया है, जो इस मामले में 30 दिनों तक डिफ़ॉल्ट है। हालांकि, यह विशेष रूप से नहीं है आपकी समस्या के लिए प्रासंगिक)
आपके मामले में, आप तीन शाखा के नाम (और इसलिए तीन reflogs) शामिल है:।
origin/master
, जोसे अद्यतन किया जाता है(का पहला कदम अपने git pull
जबकि शाखा master
)
master
है, जो (सामान्य प्रतिबद्ध के माध्यम से) दोनों आप से अद्यतन किया जाता है और git rebase
(अपने git pull
के दूसरे चरण के), और
feature
, जो दोनों के द्वारा अद्यतन किया जाता है आप (सामान्य प्रतिबद्धताओं के माध्यम से) और git rebase
(आपके दूसरेgit pull
का दूसरा चरण: आप अपने आप से "लांच" करते हैं, एक नो-ऑप, फिर master
पर रीबेस करें)।
दोनों rebases --preserve-merges
(इसलिए गैर बातचीत इंटरैक्टिव मोड) और --onto new-tipfork-point
, जहां fork-point
आईडी प्रतिबद्ध के साथ चलाए जा रहे हैं git merge-base --fork-point upstream-name HEAD
चलाकर पाया जाता है। के लिए दूसरा रिबेस master
(refs/heads/master
) है upstream-name
पहले रिबेस के लिएorigin/master
(अच्छी तरह से, refs/remotes/origin/master
) और upstream-name
है।
यह सभी जस्ट वर्क होना चाहिए।अपने पूरी प्रक्रिया के शुरू में ग्राफ प्रतिबद्ध हैं कि तुम क्या वर्णन किया है की तरह कुछ है:
... - A - B <-- master, origin/master
\
I - J - K <-- feature
तो पहले fetch
कुछ करता में लाता है और नई टिप करने के लिए origin/master
बिंदु बनाता है:
C - D - E <-- origin/master
/
... - A - B <-- master, origin/[email protected]{1}
\
I - J - K <-- feature
और पहली रिबेस तो कॉपी करने के लिए कुछ भी नहीं पाता है (master
के मर्ज आधार और B
- B
= कांटा सूत्री (मास्टर, मूल/गुरु) अभी B
-is तो नकल की कोई बात नहीं है), दे रही है:
C - D - E <-- master, origin/master
/
... - A - B <-- [email protected]{1}, origin/[email protected]{1}
\
I - J - K <-- feature
दूसरा fetch स्वयं से है और एक नो-ऑप/पूरी तरह से छोड़ दिया गया है, इसे दूसरे रिबेस में इनपुट के रूप में छोड़ दिया गया है। --onto
लक्ष्य master
जो प्रतिबद्ध E
और HEAD
(feature
) और master
का कांटा सूत्री भी B
प्रतिबद्ध है, E
हमेशा की तरह के बाद कॉपी करने के लिए I
के माध्यम से K
करता छोड़ने है।
अगर कुछ प्रतिबद्धताओं को छोड़ दिया जा रहा है, तो इस प्रक्रिया में कुछ गलत हो रहा है, लेकिन मैं नहीं देख सकता।
आपको रिमोट ट्रैकिंग शाखा 'मूल/मास्टर' को खुद को रिबेस नहीं करना चाहिए, बल्कि आप उस रिमोट की अपनी (ट्रैकिंग) प्रति को प्रभावित किए बिना आगे लाने की कोशिश कर रहे हैं। मैंने सही आमंत्रणों के लिए मैनुअल की जांच नहीं की है, लेकिन शायद उस शाखा को एक नए अस्थायी नाम के तहत चेकआउट करें, और उस रीबेस को जो आपके वर्तमान हेड पर अस्थायी शाखा है। –
मुझे लगता है कि यहां कुछ भ्रम है। मैं 'उत्पत्ति/मास्टर' का पुन: उपयोग नहीं कर रहा हूं, लेकिन मौजूदा शाखा 'मास्टर' को 'मूल/मास्टर' पर पुनर्जीवित कर रहा हूं। मेरी समझ के मुताबिक, अनिवार्य रूप से 'मूल/मास्टर 'की नोक पर' हेड 'लाया जाना चाहिए, और फिर से काम करना चाहिए जो' मास्टर 'की नोक पर शाखा में वापस आ गया था। अनिवार्य रूप से, 'मास्टर' पर नए कामों को दोबारा लिखना जैसे कि वे 'उत्पत्ति/मास्टर' के परिवर्तनों के बाद हुआ। – ashays
गिट का आपका (स्थानीय) संस्करण क्या है? मैं पूछता हूं क्योंकि मुझे याद है (कुछ हद तक अस्पष्ट और अभी तक जांचने के लिए वापस नहीं गए हैं) कि कई 2.x रिलीज के लिए 'गिट पुल' में एक स्वचालित फोर्क पॉइंट रीबेस बग था और संस्करण को जानना थोड़ा आसान हो सकता है। – torek