कभी-कभी यह प्रभावी रूप से असंभव है (कुछ अपवादों के साथ जहां आप अतिरिक्त डेटा रखने के लिए भाग्यशाली हो सकते हैं) और यहां समाधान काम नहीं करेंगे।
Git रेफरी इतिहास (जिसमें शाखाएँ शामिल हैं) को संरक्षित नहीं करता है। यह केवल प्रत्येक शाखा (प्रमुख) के लिए वर्तमान स्थिति को संग्रहीत करता है। इसका अर्थ है कि आप समय के साथ कुछ शाखा इतिहास खो सकते हैं। जब भी आप उदाहरण के लिए शाखा करते हैं, यह तुरंत खो जाता है कि कौन सी शाखा मूल थी। सभी एक शाखा है:
git checkout branch1 # refs/branch1 -> commit1
git checkout -b branch2 # branch2 -> commit1
आप मान सकते हैं कि पहली कमिटेड शाखा है। यह मामला है, लेकिन यह हमेशा ऐसा नहीं है। उपरोक्त ऑपरेशन के बाद सबसे पहले आपको या तो शाखा में आने से रोकना नहीं है। इसके अतिरिक्त, गिट टाइमस्टैम्प विश्वसनीय होने की गारंटी नहीं है। यह तब तक नहीं है जब तक आप दोनों के लिए प्रतिबद्ध नहीं हैं कि वे वास्तव में संरचनात्मक रूप से शाखाएं बन जाएं।
जबकि आरेखों में हम संख्या की अवधारणा करते हैं, git के पास अनुक्रम की कोई वास्तविक अवधारणा नहीं है जब प्रतिबद्ध पेड़ की शाखाएं। इस मामले में आप मान सकते हैं कि संख्याएँ (आदेश का संकेत) टाइमस्टैम्प द्वारा निर्धारित की जाती हैं (यह देखना मजेदार हो सकता है कि कैसे git UI चीजों को संभालती है जब आप सभी टाइमस्टैम्प को उसी पर सेट करते हैं)।
यह वैचारिक रूप से मानव की अपेक्षा है:
After branch:
C1 (B1)
/
-
\
C1 (B2)
After first commit:
C1 (B1)
/
-
\
C1 - C2 (B2)
यह वही है जो आपको वास्तव में मिलता है:
After branch:
- C1 (B1) (B2)
After first commit (human):
- C1 (B1)
\
C2 (B2)
After first commit (real):
- C1 (B1) - C2 (B2)
आप B1 को मूल शाखा मान लेंगे, लेकिन यह केवल एक मृत शाखा हो सकती है (किसी ने चेकआउट किया था, लेकिन इसके लिए प्रतिबद्ध नहीं था)। यह तब तक नहीं है जब तक आप दोनों के लिए प्रतिबद्ध नहीं हो जाते हैं कि आपको गिट के भीतर एक वैध शाखा संरचना मिल जाती है:
Either:
/ - C2 (B1)
-- C1
\ - C3 (B2)
Or:
/ - C3 (B1)
-- C1
\ - C2 (B2)
आप हमेशा से जानते हैं कि C1 C2 और C3 से पहले आया था, लेकिन आप कभी भी मज़बूती से नहीं जानते कि C2 C3 से पहले आया था या C3 C2 से पहले आया था (क्योंकि आप उदाहरण के लिए अपने वर्कस्टेशन पर समय सेट कर सकते हैं)। बी 1 और बी 2 भी भ्रामक है क्योंकि आप यह नहीं जान सकते कि कौन सी शाखा पहले आई थी। आप कई मामलों में इस पर बहुत अच्छा और आमतौर पर सटीक अनुमान लगा सकते हैं। यह रेस ट्रैक जैसा है। सभी चीजें आम तौर पर कारों के बराबर होती हैं तो आप यह मान सकते हैं कि एक कार जो एक गोद में आती है पीछे एक गोद शुरू हुई। हमारे पास ऐसे सम्मेलन भी हैं जो बहुत विश्वसनीय हैं, उदाहरण के लिए मास्टर लगभग हमेशा सबसे लंबे समय तक रहने वाली शाखाओं का प्रतिनिधित्व करेंगे, हालांकि दुख की बात है कि मैंने ऐसे मामले देखे हैं जहां यह मामला नहीं है।
यहाँ दिया गया उदाहरण एक इतिहास संरक्षण उदाहरण है:
Human:
- X - A - B - C - D - F (B1)
\ / \ /
G - H ----- I - J (B2)
Real:
B ----- C - D - F (B1)
/ / \ /
- X - A / \ /
\ / \ /
G - H ----- I - J (B2)
यहां वास्तविक भी भ्रामक है क्योंकि हम मनुष्य इसे बाएं से दाएं पढ़ते हैं, जड़ से पत्ती (रेफ)। Git ऐसा नहीं करता है। जहाँ हम करते हैं (A-> B) हमारे सिर में git करता है (A <-B या B-> A)। यह इसे रेफ से रूट तक पढ़ता है। रेफरी कहीं भी हो सकते हैं लेकिन कम से कम सक्रिय शाखाओं के लिए, लीफ्स होते हैं। एक रेफरी एक कमिट की ओर इशारा करता है और कहता है कि उनके माता-पिता की तरह ही उनके बच्चों के लिए है। जब कोई कमिट मर्ज होता है तो उसके एक से अधिक माता-पिता होते हैं। पहला अभिभावक हमेशा मूल प्रतिबद्ध होता है जिसे विलय कर दिया गया था। अन्य माता-पिता हमेशा ऐसे होते हैं जो मूल प्रतिबद्ध में विलय कर दिए गए थे।
Paths:
F->(D->(C->(B->(A->X)),(H->(G->(A->X))))),(I->(H->(G->(A->X))),(C->(B->(A->X)),(H->(G->(A->X)))))
J->(I->(H->(G->(A->X))),(C->(B->(A->X)),(H->(G->(A->X)))))
यह बहुत कुशल प्रतिनिधित्व नहीं है, बल्कि सभी रास्तों की अभिव्यक्ति प्रत्येक रेफ (बी 1 और बी 2) से ले सकती है।
Git का आंतरिक संग्रहण इस तरह दिखता है (ऐसा नहीं है कि A माता-पिता के रूप में दो बार दिखाई देता है):
F->D,I | D->C | C->B,H | B->A | A->X | J->I | I->H,C | H->G | G->A
यदि आप एक कच्चा गिट प्रतिबद्ध करते हैं तो आपको शून्य या अधिक मूल फ़ील्ड दिखाई देंगे। यदि शून्य हैं, तो इसका मतलब कोई माता-पिता नहीं है और प्रतिबद्ध एक जड़ है (आप वास्तव में कई जड़ें हो सकते हैं)। यदि एक है, तो इसका मतलब है कि कोई मर्ज नहीं था और यह रूट कमिट नहीं है। यदि एक से अधिक है, तो इसका मतलब है कि कमिट एक मर्ज का परिणाम है और पहले मर्ज होने के बाद माता-पिता के सभी।
Paths simplified:
F->(D->C),I | J->I | I->H,C | C->(B->A),H | H->(G->A) | A->X
Paths first parents only:
F->(D->(C->(B->(A->X)))) | F->D->C->B->A->X
J->(I->(H->(G->(A->X))) | J->I->H->G->A->X
Or:
F->D->C | J->I | I->H | C->B->A | H->G->A | A->X
Paths first parents only simplified:
F->D->C->B->A | J->I->->G->A | A->X
Topological:
- X - A - B - C - D - F (B1)
\
G - H - I - J (B2)
जब दोनों ए हिट करते हैं तो उनकी श्रृंखला समान होगी, इससे पहले उनकी श्रृंखला पूरी तरह से अलग होगी। पहली दो अन्य प्रतिबद्धताओं में सामान्य पूर्वज सामान्य पूर्वज हैं और वे किस स्थान से निकले हैं। वहाँ प्रतिबद्धताओं, शाखा और रेफ के बीच कुछ भ्रम हो सकता है। आप वास्तव में एक प्रतिबद्ध विलय कर सकते हैं। यह वही है जो वास्तव में विलय करता है। रेफरी बस एक कमिट की ओर इशारा करता है और ब्रांच। रेफरी / रेफ्स / हेड्स में रेफरी से ज्यादा कुछ नहीं होता है। फोल्डर लोकेशन यह निर्धारित करता है कि रेफ एक ब्रांच है बजाय टैग के कुछ और।
जहां आप इतिहास को खो देते हैं वह यह है कि मर्ज परिस्थितियों के आधार पर दो में से एक काम करेगा।
विचार करें:
/ - B (B1)
- A
\ - C (B2)
इस स्थिति में या तो दिशा में एक मर्ज पहले माता-पिता के साथ एक नई प्रतिबद्धता पैदा करेगा, क्योंकि वर्तमान चेक आउट शाखा द्वारा बताए गए कमिट के साथ और दूसरा माता-पिता उस शाखा के सिरे के रूप में जो आप अपनी वर्तमान शाखा में विलय कर चुके हैं। इसे एक नई प्रतिबद्धता बनानी होगी क्योंकि दोनों शाखाओं में अपने सामान्य पूर्वजों के साथ बदलाव होंगे जिन्हें संयुक्त होना चाहिए।
/ - B - D (B1)
- A /
\ --- C (B2)
इस बिंदु पर डी (बी 1) में अब दोनों शाखाओं (स्वयं और बी 2) से परिवर्तन के सेट हैं। हालाँकि दूसरी शाखा में बी 1 से परिवर्तन नहीं है। यदि आप बी 1 से बी 2 में बदलावों को मर्ज करते हैं ताकि उन्हें समकालित किया जाए, तो आप कुछ इस तरह की उम्मीद कर सकते हैं (आप गिट मर्ज को इस तरह से करने के लिए बाध्य कर सकते हैं - हालांकि-एफएफ के साथ):
Expected:
/ - B - D (B1)
- A / \
\ --- C - E (B2)
Reality:
/ - B - D (B1) (B2)
- A /
\ --- C
आपको वह मिल जाएगा, भले ही बी 1 में अतिरिक्त कमिट हों। जब तक बी 2 में परिवर्तन नहीं होते हैं जो कि बी 1 के पास नहीं है, दोनों शाखाओं को मिला दिया जाएगा। यह एक तेज़ फ़ॉरवर्ड करता है जो एक रिबेस (विद्रोह भी खाता है या लीनियर हिस्ट्री) की तरह होता है, सिवाय एक रिबेज़ के विपरीत, क्योंकि केवल एक ब्रांच में बदलाव होता है, इसमें एक ब्रांच से दूसरे के ऊपर एक चेंजसेट अप्लाई नहीं करना पड़ता है।
From:
/ - B - D - E (B1)
- A /
\ --- C (B2)
To:
/ - B - D - E (B1) (B2)
- A /
\ --- C
यदि आप बी 1 पर काम करना बंद कर देते हैं तो लंबे समय में इतिहास को संरक्षित करने के लिए चीजें काफी हद तक ठीक हैं। केवल बी 1 (जो मास्टर हो सकता है) आमतौर पर बी 2 के इतिहास में बी 2 के स्थान को सफलतापूर्वक आगे बढ़ाएगा, यह उस बिंदु का सफलतापूर्वक प्रतिनिधित्व करता है जिसे इसे बी 1 में विलय कर दिया गया था। यह वह है जो आपको बी से ए की शाखा में करने की उम्मीद करता है, फिर आप ए को बी में विलय कर सकते हैं जैसे कि आप जैसे बदलाव जमा करते हैं, वैसे बी को ए में वापस विलय करते समय, यह उम्मीद नहीं है कि आप बी और आगे काम करेंगे। । यदि आप तेजी से आगे विलय करने के बाद अपनी शाखा पर काम कर रहे हैं, तो आप उस शाखा में काम कर रहे हैं जो आपके बी के पिछले इतिहास को हर बार मिटा रही है। आप वास्तव में तेजी से आगे स्रोत के लिए प्रतिबद्ध करने के बाद फिर शाखा के लिए हर बार एक नई शाखा बना रहे हैं।
0 1 2 3 4 (B1)
/-\ /-\ /-\ /-\ /
---- - - - -
\-/ \-/ \-/ \-/ \
5 6 7 8 9 (B2)
1 से 3 और 5 से 8 संरचनात्मक शाखाएं हैं जो यदि आप 4 या 9 के लिए इतिहास का अनुसरण करते हैं तो दिखाते हैं। यह जानने का कोई तरीका नहीं है कि इस अनाम और अप्रकाशित संरचनात्मक शाखाओं में से कौन सी नाम और संदर्भ शाखाओं के साथ संबंधित हैं संरचना का अंत। आप इस ड्राइंग से मान सकते हैं कि 0 से 4 बी 1 से संबंधित है और 4 से 9 बी 2 से संबंधित है, लेकिन 4 और 9 के अलावा पता नहीं चल सकता है कि कौन सी शाखा किस शाखा से संबंधित है, मैंने इसे बस एक तरह से तैयार किया है जो देता है उस का भ्रम। 0 बी 2 से संबंधित हो सकता है और 5 बी 1 से संबंधित हो सकता है। इस मामले में 16 अलग-अलग कब्जे हैं जिनमें से प्रत्येक संरचनात्मक शाखा का नाम दिया गया है।
इस के आसपास काम करने वाली कई तरह की गिट स्ट्रेटेजी हैं। आप मर्ज मर्ज को कभी भी तेजी से आगे नहीं बढ़ने के लिए मजबूर कर सकते हैं और हमेशा मर्ज ब्रांच बना सकते हैं। शाखा इतिहास को संरक्षित करने का एक भयानक तरीका टैग और / या शाखाएं हैं (टैग वास्तव में अनुशंसित हैं) आपके चयन के कुछ सम्मेलन के अनुसार। जिस शाखा में आप विलय कर रहे हैं, मैं उस खाली डमी की सिफारिश नहीं करूंगा। एक बहुत ही आम सम्मेलन एक एकीकरण शाखा में विलय नहीं करना है जब तक आप अपनी शाखा को वास्तव में बंद नहीं करना चाहते हैं। यह एक ऐसी प्रथा है जिसका लोगों को पालन करने का प्रयास करना चाहिए अन्यथा आप शाखाओं के होने के बिंदु के आसपास काम कर रहे हैं। हालांकि वास्तविक दुनिया में आदर्श हमेशा व्यावहारिक नहीं होता है, सही काम करना हर स्थिति के लिए व्यवहार्य नहीं होता है। अगर तुम क्या हो '