<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Version Control on kenji.blog</title><link>http://kenji.blog/hi/tags/version-control/</link><description>Recent content in Version Control on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>hi</language><copyright>kenjinote</copyright><lastBuildDate>Sun, 13 Sep 2026 09:00:00 +0900</lastBuildDate><atom:link href="http://kenji.blog/hi/tags/version-control/index.xml" rel="self" type="application/rss+xml"/><item><title>【Git कमांड】rebase और merge के बीच का अंतर, और व्यवहार में इनका सही उपयोग कैसे करें</title><link>http://kenji.blog/hi/p/git-rebase-vs-merge-practical-guide/</link><pubDate>Sun, 13 Sep 2026 09:00:00 +0900</pubDate><guid>http://kenji.blog/hi/p/git-rebase-vs-merge-practical-guide/</guid><description>&lt;img src="http://kenji.blog/p/git-rebase-vs-merge-practical-guide/img/eyecatch.jpg" alt="Featured image of post 【Git कमांड】rebase और merge के बीच का अंतर, और व्यवहार में इनका सही उपयोग कैसे करें" />&lt;h1 id="1-परचय-merge-य-rebase-हमश-एक-बहस-क-वषय-कय-ह">1. परिचय: &amp;ldquo;merge या rebase&amp;rdquo; हमेशा एक बहस का विषय क्यों है?
&lt;/h1>&lt;p>Git आधुनिक सॉफ़्टवेयर विकास में एक अपरिहार्य वर्ज़न कंट्रोल सिस्टम है। जब कई डेवलपर्स एक साथ कोडबेस में परिवर्तन करते हैं, तो Git का शक्तिशाली ब्रांच मॉडल अपनी ताकत दिखाता है। हालाँकि, टीम डेवलपमेंट में &amp;ldquo;क्या &lt;code>merge&lt;/code> या &lt;code>rebase&lt;/code> का उपयोग करना चाहिए&amp;rdquo; यह चर्चा हमेशा शुरुआती लोगों से लेकर अनुभवी डेवलपर्स तक को परेशान करने वाले विषयों में से एक रही है।&lt;/p>
&lt;p>इस लेख में, हम Git की आंतरिक संरचना, जैसे DAG (Directed Acyclic Graph) और कमिट हैश के गणितीय गुणों से शुरू करते हुए, &lt;code>git merge&lt;/code> और &lt;code>git rebase&lt;/code> के मैकेनिज़्म के बीच के अंतर को गहराई से समझेंगे। इसके अलावा, हम व्यावहारिक वर्कफ़्लो के साथ विस्तार से बताएंगे कि वास्तविक काम में इनका सही तरीके से उपयोग कैसे किया जाए। केवल कमांड्स के परिचय से आगे बढ़कर, बैकग्राउंड में Git किस तरह की गणनाएँ कर रहा है, यह समझने से आपका कॉन्फ्लिक्ट (टकराव) का डर खत्म हो जाएगा और आप एक साफ़ और ट्रैक करने योग्य इतिहास (history) बना सकेंगे।&lt;/p>
&lt;hr>
&lt;h1 id="2-git-क-आतरक-सरचन-कमट-हश-और-ऑबजकट-मडल">2. Git की आंतरिक संरचना: कमिट हैश और ऑब्जेक्ट मॉडल
&lt;/h1>&lt;p>Git इतिहास को कैसे इंटीग्रेट (एकीकृत) करता है, इसे समझने के लिए पहले यह जानना ज़रूरी है कि Git डेटा को कैसे सेव करता है। Git केवल फ़ाइल में बदलावों के अंतर (पैच) को सेव नहीं करता है, बल्कि यह किसी विशिष्ट समय पर पूरे फ़ाइल सिस्टम के स्नैपशॉट को सेव करता है।&lt;/p>
&lt;h2 id="21-कमट-हश-क-करपटगरफक-गण">2.1 कमिट हैश के क्रिप्टोग्राफ़िक गुण
&lt;/h2>&lt;p>Git का प्रत्येक कमिट इसके कंटेंट के आधार पर कैलकुलेट किए गए SHA-1 (Secure Hash Algorithm 1) हैश फ़ंक्शन द्वारा 40-अंकीय हेक्साडेसिमल संख्या से विशिष्ट रूप से पहचाना जाता है। कमिट ऑब्जेक्ट में निम्नलिखित तत्व (elements) होते हैं:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Tree ऑब्जेक्ट का पॉइंटर&lt;/strong>: उस समय के डायरेक्टरी स्ट्रक्चर और फ़ाइल (Blob) का स्नैपशॉट।&lt;/li>
&lt;li>&lt;strong>पैरेंट कमिट का पॉइंटर&lt;/strong>: एक या अधिक पैरेंट कमिट्स के हैश मान (पहले कमिट का कोई पैरेंट नहीं होता है, और मर्ज कमिट के 2 या अधिक पैरेंट होते हैं)।&lt;/li>
&lt;li>&lt;strong>लेखक की जानकारी (Author)&lt;/strong>: वह व्यक्ति जिसने कोड लिखा है और उसका समय।&lt;/li>
&lt;li>&lt;strong>कमिटर की जानकारी (Committer)&lt;/strong>: वह व्यक्ति जिसने कमिट बनाया/लागू किया है और उसका समय।&lt;/li>
&lt;li>&lt;strong>कमिट मैसेज&lt;/strong>: बदलाव के उद्देश्य को स्पष्ट करने वाला टेक्स्ट।&lt;/li>
&lt;/ol>
&lt;p>गणितीय रूप से व्यक्त करें, तो कमिट ऑब्जेक्ट $C$ के लिए हैश मान $H(C)$ को इस प्रकार परिभाषित किया गया है:&lt;/p>
$$
H(C) = \text{SHA-1}( \text{tree} \parallel \text{parent} \parallel \text{author} \parallel \text{committer} \parallel \text{message} )
$$&lt;p>यहाँ, $\parallel$ डेटा के संयोजन को दर्शाता है। हैश फ़ंक्शन की विशेषताओं के कारण, भले ही कमिट मैसेज में एक अक्षर बदल दिया जाए, या पैरेंट कमिट अलग हो, पूरी तरह से अलग हैश मान उत्पन्न होता है। दूसरे शब्दों में, &lt;strong>कमिट अपरिवर्तनीय (Immutable) होते हैं&lt;/strong>। बाद में जिस &lt;code>rebase&lt;/code> का वर्णन &amp;ldquo;इतिहास को फिर से लिखने&amp;rdquo; के रूप में किया गया है, वह वास्तव में &amp;ldquo;एक नया कमिट बना रहा है जिसकी सामग्री समान है लेकिन हैश मान अलग है।&amp;rdquo;&lt;/p>
&lt;p>हैश स्पेस का आकार $2^{160}$ है, और टकराव की संभावना (Collision) (यह संभावना कि विभिन्न कमिट्स का हैश मान समान होगा) $P$ को बर्थडे पैराडॉक्स (Birthday Paradox) थ्योरी का उपयोग करके इस प्रकार अनुमानित किया जा सकता है ($n$ कमिट्स की संख्या है):&lt;/p>
$$
P(\text{collision}) \approx 1 - \exp\left(-\frac{n^2}{2 \times 2^{160}}\right)
$$&lt;p>यह संभावना बहुत ही कम है, और व्यावहारिक रूप से यह लगभग असंभव है कि Git का कमिट हैश आपस में टकराए।&lt;/p>
&lt;hr>
&lt;h1 id="3-गरफ-थयर-और-dag-git-इतहस-क-गणतय-मडल">3. ग्राफ़ थ्योरी और DAG: Git इतिहास का गणितीय मॉडल
&lt;/h1>&lt;p>Git के कमिट इतिहास को ग्राफ़ थ्योरी में &amp;ldquo;डायरेक्टेड एसाइक्लिक ग्राफ़ (Directed Acyclic Graph, DAG)&amp;rdquo; के रूप में मॉडल किया गया है।&lt;/p>
&lt;h2 id="31-dag-डयरकटड-एसइकलक-गरफ-कय-ह">3.1 DAG (डायरेक्टेड एसाइक्लिक ग्राफ़) क्या है?
&lt;/h2>&lt;p>ग्राफ़ $G = (V, E)$ में, $V$ कमिट्स (Vertices) का सेट है, और $E$ कमिट्स के बीच पैरेंट-चाइल्ड संबंध को दर्शाने वाले डायरेक्टेड एजेज़ (Directed Edges) का सेट है। Git में, एजेज़ की दिशा &amp;ldquo;चाइल्ड कमिट से पैरेंट कमिट&amp;rdquo; की ओर होती है। ऐसा इसलिए है क्योंकि नए कमिट पिछले कमिट का पॉइंटर रखते हैं।&lt;/p>
&lt;pre class="mermaid">
graph BT
A[&amp;#34;कमिट A (प्रारंभिक)&amp;#34;]
B[&amp;#34;कमिट B&amp;#34;]
C[&amp;#34;कमिट C (Main)&amp;#34;]
D[&amp;#34;कमिट D (Feature)&amp;#34;]
E[&amp;#34;कमिट E (Merge)&amp;#34;]
B --&amp;gt; A
C --&amp;gt; B
D --&amp;gt; B
E --&amp;gt; C
E --&amp;gt; D
&lt;/pre>
&lt;p>DAG की सबसे बड़ी विशेषता यह है कि &amp;ldquo;इसमें कोई चक्र (Cycle) नहीं होता है&amp;rdquo;। इस वजह से, कमिट इतिहास को पीछे ट्रेस करने वाला एल्गोरिदम कभी भी अनंत लूप में नहीं फँसता है, और यह निश्चित रूप से अंत (प्रारंभिक कमिट) तक पहुँच सकता है।&lt;/p>
&lt;h2 id="32-टपलजकल-सरट-और-इतहस-क-करम">3.2 टोपोलॉजिकल सॉर्ट और इतिहास का क्रम
&lt;/h2>&lt;p>जब Git के &lt;code>git log&lt;/code> कमांड आदि का उपयोग करके इतिहास प्रदर्शित किया जाता है, तो DAG को टोपोलॉजिकल सॉर्ट (Topological Sort) एल्गोरिदम का उपयोग करके एक 1-आयामी (1-dimensional) सूची के रूप में क्रमित किया जाता है। DAG में किसी भी डायरेक्टेड एज $u \to v$ ($u$, $v$ का चाइल्ड है) के लिए, यह इस तरह से पुनर्व्यवस्थित होता है कि सूची में $u$, $v$ से पहले आए।&lt;/p>
&lt;hr>
&lt;h1 id="4-git-merge-क-मकनजम-और-परकर">4. git merge का मैकेनिज़्म और प्रकार
&lt;/h1>&lt;p>ब्रांच के बदलावों को इंटीग्रेट करने के लिए सबसे बुनियादी कमांड &lt;code>git merge&lt;/code> है। हालाँकि, वर्तमान स्थिति के आधार पर, Git स्वचालित रूप से अलग-अलग मर्ज रणनीतियों का चयन करता है।&lt;/p>
&lt;h2 id="41-fast-forward-मरज---ff">4.1 Fast-Forward मर्ज (&amp;ndash;ff)
&lt;/h2>&lt;p>यदि लक्ष्य (जैसे: &lt;code>main&lt;/code>) ब्रांच सोर्स (जैसे: &lt;code>feature&lt;/code>) ब्रांच का प्रत्यक्ष पूर्वज (direct ancestor) है, तो Git &amp;ldquo;Fast-Forward&amp;rdquo; (तेज़ी से आगे बढ़ाना) मर्ज को निष्पादित करता है। यह एक ऐसा ऑपरेशन है जो नया कमिट नहीं बनाता है, बल्कि यह बस ब्रांच पॉइंटर को आगे बढ़ाता है।&lt;/p>
&lt;pre class="mermaid">
gitGraph
commit id: &amp;#34;A&amp;#34;
commit id: &amp;#34;B&amp;#34;
branch feature
checkout feature
commit id: &amp;#34;C&amp;#34;
commit id: &amp;#34;D&amp;#34;
checkout main
merge feature
&lt;/pre>
&lt;p>Fast-Forward मर्ज इतिहास को एक सीधी रेखा में रखता है, लेकिन इसका एक नुकसान यह है कि &amp;ldquo;कौन से कमिट्स का समूह एक फीचर (feature) के विकास के रूप में एक साथ था&amp;rdquo;, इसका संदर्भ (Context) खो जाता है।&lt;/p>
&lt;h2 id="42-non-fast-forward-मरज---no-ff">4.2 Non-Fast-Forward मर्ज (&amp;ndash;no-ff)
&lt;/h2>&lt;p>यदि आप स्पष्ट रूप से &lt;code>git merge --no-ff&lt;/code> निर्दिष्ट करते हैं, तो भले ही Fast-Forward संभव हो, यह हमेशा एक नया &amp;ldquo;मर्ज कमिट&amp;rdquo; बनाएगा। मर्ज कमिट 2 पैरेंट्स वाला एक विशेष कमिट होता है।&lt;/p>
&lt;pre class="mermaid">
gitGraph
commit id: &amp;#34;A&amp;#34;
commit id: &amp;#34;B&amp;#34;
branch feature
checkout feature
commit id: &amp;#34;C&amp;#34;
commit id: &amp;#34;D&amp;#34;
checkout main
commit id: &amp;#34;Main Work 1&amp;#34;
merge feature type: NORMAL
&lt;/pre>
&lt;p>इस पद्धति का लाभ यह है कि फीचर ब्रांच का अस्तित्व और इतिहास DAG पर स्पष्ट रूप से रहता है। जब कोई समस्या उत्पन्न होती है, तो आप &lt;code>git revert -m 1 &amp;lt;मर्ज कमिट का हैश&amp;gt;&lt;/code> चलाकर पूरे फीचर को एक ही बार में सुरक्षित रूप से पूर्ववत (रिवर्ट) कर सकते हैं।&lt;/p>
&lt;h2 id="43-3-व-मरज-3-way-merge-एलगरदम">4.3 3-वे मर्ज (3-Way Merge) एल्गोरिदम
&lt;/h2>&lt;p>जब लक्ष्य ब्रांच और सोर्स ब्रांच दोनों के अपने स्वयं के कमिट होते हैं, तो Git 3-वे मर्ज निष्पादित करता है। इस समय, Git DAG को खोजता है और दोनों ब्रांचों के &amp;ldquo;न्यूनतम सामान्य पूर्वज (Lowest Common Ancestor, LCA)&amp;rdquo; का पता लगाता है।&lt;/p>
&lt;p>LCA खोजने के लिए एल्गोरिदम की कम्प्यूटेशनल जटिलता (Computational Complexity) $T_{\text{LCA}}$ को वर्टिसेस की संख्या $|V|$ और एजेज़ की संख्या $|E|$ के सापेक्ष रैखिक समय (Linear Time) में निष्पादित किया जा सकता है:&lt;/p>
$$
T_{\text{LCA}} = \mathcal{O}(|V| + |E|)
$$&lt;p>Git तीन चीजों की तुलना करता है: &amp;ldquo;LCA की स्थिति&amp;rdquo;, &amp;ldquo;वर्तमान ब्रांच की स्थिति&amp;rdquo;, और &amp;ldquo;दूसरी ब्रांच की स्थिति&amp;rdquo;, और यदि परिवर्तनों में कोई टकराव (conflict) नहीं होता है, तो यह स्वचालित रूप से एक मर्ज कमिट उत्पन्न करता है।&lt;/p>
&lt;hr>
&lt;h1 id="5-git-rebase-क-मकनजम-और-इतहस-क-पनरनरमण">5. git rebase का मैकेनिज़्म और इतिहास का पुनर्निर्माण
&lt;/h1>&lt;p>जबकि &lt;code>git merge&lt;/code> इतिहास को &amp;ldquo;एकीकृत (Integrate)&amp;rdquo; करता है, &lt;code>git rebase&lt;/code> इतिहास का &amp;ldquo;पुनर्निर्माण (Rebuild)&amp;rdquo; करता है।&lt;/p>
&lt;h2 id="51-rebase-क-पछ-क-करयपरणल">5.1 Rebase के पीछे की कार्यप्रणाली
&lt;/h2>&lt;p>जब आप &lt;code>feature&lt;/code> ब्रांच को &lt;code>main&lt;/code> ब्रांच में रिबेस करते हैं (&lt;code>git rebase main&lt;/code>), तो आंतरिक कार्यप्रणाली इस प्रकार होती है:&lt;/p>
&lt;ol>
&lt;li>&lt;code>feature&lt;/code> ब्रांच और &lt;code>main&lt;/code> ब्रांच के सामान्य पूर्वज (LCA) का पता लगाएं।&lt;/li>
&lt;li>LCA से लेकर &lt;code>feature&lt;/code> ब्रांच के शीर्ष तक के कमिट्स के अंतर को एक अस्थायी क्षेत्र (Temporary Area) में सेव करें।&lt;/li>
&lt;li>&lt;code>feature&lt;/code> ब्रांच के पॉइंटर को &lt;code>main&lt;/code> ब्रांच के शीर्ष (Tip) पर ले जाएं।&lt;/li>
&lt;li>सहेजे गए अंतरों को एक-एक करके नए बेस (&lt;code>main&lt;/code> के शीर्ष) पर क्रमिक रूप से लागू (Cherry-Pick) करें, और नए कमिट्स बनाएं।&lt;/li>
&lt;/ol>
&lt;pre class="mermaid">
graph TD
A[&amp;#34;कमिट A&amp;#34;] --&amp;gt; B[&amp;#34;कमिट B&amp;#34;]
B --&amp;gt; C[&amp;#34;कमिट C (Main)&amp;#34;]
B --&amp;gt; D[&amp;#34;कमिट D (पुराना फीचर)&amp;#34;]
D -.-&amp;gt; E[&amp;#34;कमिट D&amp;#39; (नया फीचर)&amp;#34;]
C --&amp;gt; E
style D stroke-dasharray: 5 5, fill: #f9f9f9, color: #999
&lt;/pre>
&lt;p>यहाँ सबसे महत्वपूर्ण बात यह है कि रिबेस द्वारा उत्पन्न कमिट $D'$, मूल कमिट $D$ से &lt;strong>एक अलग पैरेंट कमिट होने के कारण, पूरी तरह से अलग हैश मान रखता है&lt;/strong> (ऊपर उल्लिखित हैश फ़ंक्शन परिभाषा $H(C)$ देखें)।&lt;/p>
&lt;h2 id="52-इटरएकटव-रबस-interactive-rebase">5.2 इंटरएक्टिव रिबेस (Interactive Rebase)
&lt;/h2>&lt;p>&lt;code>git rebase -i&lt;/code> (या &lt;code>--interactive&lt;/code>) का उपयोग करके, आप अपनी इच्छानुसार कमिट इतिहास में हेरफेर कर सकते हैं। स्थानीय (Local) इतिहास को व्यवस्थित करने के लिए यह सबसे शक्तिशाली टूल है।&lt;/p>
&lt;ul>
&lt;li>&lt;code>pick&lt;/code> : कमिट को वैसे ही अपनाएं।&lt;/li>
&lt;li>&lt;code>reword&lt;/code> : केवल कमिट मैसेज को संशोधित करें।&lt;/li>
&lt;li>&lt;code>edit&lt;/code> : कमिट के कंटेंट को संशोधित करने के लिए रुकें।&lt;/li>
&lt;li>&lt;code>squash&lt;/code> : इस कमिट को पिछले कमिट के साथ मिलाएँ, और संदेशों को भी जोड़ें।&lt;/li>
&lt;li>&lt;code>fixup&lt;/code> : &lt;code>squash&lt;/code> के समान, लेकिन इस कमिट के मैसेज को हटा दें।&lt;/li>
&lt;li>&lt;code>drop&lt;/code> : कमिट को पूरी तरह से हटा दें।&lt;/li>
&lt;/ul>
&lt;p>गणितीय दृष्टिकोण से देखें तो, यदि किसी ब्रांच में $N$ कमिट हैं, तो रिबेस के क्रम को बदलकर उत्पन्न किए जा सकने वाले रैखिक इतिहास के रूपों (Permutations) $P$ की गणना इस प्रकार है:&lt;/p>
$$
P = N!
$$&lt;p>Git डेवलपर्स को $N!$ तरीकों की स्वतंत्रता देता है, जिससे वे अपने इतिहास को एक तार्किक और सुंदर स्थिति में रख सकते हैं।&lt;/p>
&lt;hr>
&lt;h1 id="6-रबस-क-सनहर-नयम-the-golden-rule-of-rebase">6. रिबेस का सुनहरा नियम (The Golden Rule of Rebase)
&lt;/h1>&lt;p>&lt;code>rebase&lt;/code> बहुत शक्तिशाली है, लेकिन इसका एक निरपेक्ष नियम (Absolute Rule) है:&lt;/p>
&lt;blockquote>
&lt;p>&lt;strong>&amp;ldquo;सार्वजनिक (Public) किए गए इतिहास पर कभी भी रिबेस (Rebase) न करें&amp;rdquo;&lt;/strong>
&lt;em>(Never rebase public history)&lt;/em>&lt;/p>
&lt;/blockquote>
&lt;h2 id="61-सरवजनक-इतहस-क-रबस-कय-नह-करन-चहए">6.1 सार्वजनिक इतिहास को रिबेस क्यों नहीं करना चाहिए?
&lt;/h2>&lt;p>Git एक डिस्ट्रिब्यूटेड (Distributed) सिस्टम है। आपने जो कमिट &lt;code>origin/main&lt;/code> पर पुश किए हैं, उन्हें अन्य डेवलपर्स के स्थानीय रिपॉजिटरी में भी क्लोन (प्रतिलिपि) किया गया है। अगर आप पहले से ही पुश किए गए कमिट्स को रिबेस करके इतिहास को फिर से लिखते हैं और &lt;code>git push --force&lt;/code> का उपयोग करके इसे जबरन ओवरराइट करते हैं, तो क्या होगा?&lt;/p>
&lt;p>अन्य डेवलपर्स के स्थानीय (Local) DAG और रिमोट (Remote) DAG मौलिक रूप से अलग हो जाएंगे। जब अन्य डेवलपर &lt;code>git pull&lt;/code> निष्पादित करते हैं, तो Git अलग-अलग इतिहास वाले कमिट्स को जबरन मर्ज करने का प्रयास करेगा, जिससे भारी मात्रा में कॉन्फ्लिक्ट्स और डुप्लिकेट कमिट्स (समान परिवर्तन लेकिन अलग-अलग हैश वाले कमिट) उत्पन्न होंगे, और रिपॉजिटरी में अफरा-तफरी मच जाएगी।&lt;/p>
&lt;p>यह एक सख्त नियम है कि रिबेस केवल &lt;strong>&amp;ldquo;उन स्थानीय ब्रांचों पर किया जाना चाहिए जिन्हें अभी तक किसी के साथ साझा नहीं किया गया है&amp;rdquo;&lt;/strong>।&lt;/p>
&lt;hr>
&lt;h1 id="7-कनफलकट-टकरव-क-समधन-और-git-rebase---continue">7. कॉन्फ्लिक्ट (टकराव) का समाधान और git rebase &amp;ndash;continue
&lt;/h1>&lt;p>जब कई लोग एक ही फ़ाइल के एक ही हिस्से में बदलाव करते हैं, तो कॉन्फ्लिक्ट होता है। &lt;code>merge&lt;/code> और &lt;code>rebase&lt;/code> में कॉन्फ्लिक्ट को हल करने की प्रक्रिया अलग-अलग होती है।&lt;/p>
&lt;h2 id="71-merge-म-कनफलकट-क-समधन">7.1 Merge में कॉन्फ्लिक्ट का समाधान
&lt;/h2>&lt;p>&lt;code>git merge&lt;/code> के मामले में, कॉन्फ्लिक्ट का समाधान &lt;strong>केवल एक बार&lt;/strong> होता है। आप अंतिम मर्ज कमिट बनाने से ठीक पहले सभी टकराव वाले हिस्सों को एक ही बार में ठीक करते हैं।&lt;/p>
&lt;h2 id="72-rebase-म-कनफलकट-क-समधन">7.2 Rebase में कॉन्फ्लिक्ट का समाधान
&lt;/h2>&lt;p>&lt;code>git rebase&lt;/code> के मामले में, कमिट्स को एक-एक करके फिर से लागू करने की प्रकृति के कारण, &lt;strong>प्रत्येक कमिट पर कॉन्फ्लिक्ट होने की संभावना&lt;/strong> होती है।&lt;/p>
&lt;p>यदि रिबेस के दौरान कोई कॉन्फ्लिक्ट होता है, तो Git प्रक्रिया को रोक देगा। समाधान का प्रवाह (Flow) इस प्रकार है:&lt;/p>
&lt;ol>
&lt;li>एडिटर या IDE (जैसे VS Code) खोलें और कॉन्फ्लिक्ट मार्कर्स (&lt;code>&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&lt;/code> , &lt;code>======&lt;/code>, और &lt;code>&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&lt;/code>) को मैन्युअल रूप से ठीक करें।&lt;/li>
&lt;li>संशोधित फ़ाइल को इंडेक्स में जोड़ें:
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">git add &amp;lt;संशोधित_फ़ाइल&amp;gt;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;/li>
&lt;li>बिना कोई कमिट बनाए रिबेस प्रक्रिया फिर से शुरू करें:
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">git rebase --continue
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;/li>
&lt;/ol>
&lt;p>यदि आप रिबेस को रद्द करना चाहते हैं और मूल स्थिति में वापस लौटना चाहते हैं, तो यह कमांड चलाएँ:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">git rebase --abort
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>(* यदि आपको कॉन्फ्लिक्ट को हल करने की आवश्यकता नहीं है और आप उस कमिट को पूरी तरह से छोड़ना चाहते हैं, तो &lt;code>git rebase --skip&lt;/code> का उपयोग करें।)&lt;/p>
&lt;hr>
&lt;h1 id="8-वयवहरक-रप-स-सह-उपयग-वरकफल-परकटस">8. व्यावहारिक रूप से सही उपयोग (वर्कफ़्लो प्रैक्टिस)
&lt;/h1>&lt;p>तो, वास्तविक विकास के वातावरण में आपको &lt;code>merge&lt;/code> और &lt;code>rebase&lt;/code> का उपयोग कैसे करना चाहिए? यहाँ हम सबसे मानक (Standard) और सुरक्षित दृष्टिकोण प्रस्तुत कर रहे हैं।&lt;/p>
&lt;h2 id="81-परदशय-1-सथनय-करय-इतहस-क-वयवसथत-करन-rebase-क-उपयग">8.1 [परिदृश्य 1] स्थानीय कार्य इतिहास को व्यवस्थित करना (Rebase का उपयोग)
&lt;/h2>&lt;p>मान लीजिए कि किसी फीचर ब्रांच में विकास के दौरान बहुत सारे छोटे-छोटे कमिट्स (&amp;ldquo;Typo फिक्स&amp;rdquo;, &amp;ldquo;अस्थायी सेव&amp;rdquo;, आदि) जमा हो गए हैं। पुल रिक्वेस्ट (PR) सबमिट करने से पहले, इन कमिट्स को सार्थक इकाइयों में व्यवस्थित करने के लिए इंटरएक्टिव रिबेस का उपयोग करें।&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># फीचर ब्रांच में रहते हुए निष्पादित करें&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">git rebase -i HEAD~5
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># (एडिटर खुलेगा, जहाँ आप squash और fixup का उपयोग करके इतिहास को साफ़ कर सकते हैं)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>इससे, आप एक सुंदर कमिट इतिहास बना सकते हैं जिससे समीक्षकों (Reviewers) के लिए आपके इरादे को समझना आसान हो जाएगा।&lt;/p>
&lt;h2 id="82-परदशय-2-नवनतम-main-बरच-क-सथ-अपडट-रहन-rebase-क-उपयग">8.2 [परिदृश्य 2] नवीनतम main ब्रांच के साथ अपडेट रहना (Rebase का उपयोग)
&lt;/h2>&lt;p>यदि विकास में अधिक समय लग रहा है, और अन्य लोगों के परिवर्तन लगातार &lt;code>main&lt;/code> ब्रांच में मर्ज किए जा रहे हैं, तो आपकी &lt;code>feature&lt;/code> ब्रांच पुरानी हो जाएगी। इस स्थिति में, आप अपनी &lt;code>feature&lt;/code> ब्रांच को नवीनतम &lt;code>main&lt;/code> ब्रांच में रिबेस करके इसे अपडेट कर सकते हैं।&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># main की नवीनतम जानकारी प्राप्त करें&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">git fetch origin
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># फीचर ब्रांच को नवीनतम main के शीर्ष पर स्थानांतरित करें&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">git rebase origin/main
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>इससे इतिहास एक सीधी रेखा बन जाता है, जिससे भविष्य में मर्ज करते समय कॉन्फ्लिक्ट्स को रोका जा सकता है। इसके अलावा, यह अनावश्यक मर्ज कमिट्स (&amp;ldquo;Merge branch &amp;lsquo;main&amp;rsquo; into feature&amp;rdquo;) उत्पन्न होने से भी रोकता है।&lt;/p>
&lt;h2 id="83-परदशय-3-परण-हए-फचर-क-एककत-करन-merge-क-उपयग">8.3 [परिदृश्य 3] पूर्ण हुए फीचर को एकीकृत करना (Merge का उपयोग)
&lt;/h2>&lt;p>यह वह चरण है जब &lt;code>feature&lt;/code> ब्रांच में विकास पूरा हो चुका है, और आप अंततः इसे &lt;code>main&lt;/code> ब्रांच में एकीकृत (Integrate) कर रहे हैं। यहाँ, हम &lt;strong>&lt;code>git merge --no-ff&lt;/code>&lt;/strong> का उपयोग करेंगे (यह GitHub जैसे प्लेटफ़ॉर्म पर पुल रिक्वेस्ट में &amp;ldquo;Create a merge commit&amp;rdquo; चुनने के समान है)।&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">git checkout main
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">git merge --no-ff feature -m &lt;span class="s2">&amp;#34;Merge feature: यूज़र लॉगिन फीचर का कार्यान्वयन&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">git push origin main
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>इससे, &lt;code>main&lt;/code> ब्रांच के DAG पर एक ऐतिहासिक नोड (मर्ज कमिट) बन जाएगा जो यह दर्शाएगा कि &amp;ldquo;यहाँ एक फीचर मर्ज किया गया था&amp;rdquo;। जब आप बाद में इतिहास को देखेंगे, तो फीचर के आधार पर कोड को ट्रैक करना आसान होगा।&lt;/p>
&lt;hr>
&lt;h1 id="9-नषकरष-सरश">9. निष्कर्ष (सारांश)
&lt;/h1>&lt;p>Git ऑपरेशन्स में &amp;ldquo;सब कुछ Merge के साथ करना&amp;rdquo; या &amp;ldquo;सब कुछ Rebase के साथ सीधा करना&amp;rdquo; जैसे चरम (Extreme) दृष्टिकोणों के अपने-अपने फायदे और नुकसान हैं।&lt;/p>
&lt;p>वास्तविक अभ्यास में सबसे अच्छी प्रथा (Best Practice) यह हाइब्रिड (Hybrid) दृष्टिकोण है: &lt;strong>&amp;ldquo;अपने स्थानीय निजी इतिहास को खूबसूरती से व्यवस्थित करने के लिए rebase का उपयोग करें, और सार्वजनिक एकीकरण इतिहास के संदर्भ को बनाए रखने के लिए merge &amp;ndash;no-ff का उपयोग करें।&amp;rdquo;&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>&lt;strong>स्थानीय (व्यक्तिगत कार्यक्षेत्र - Local)&lt;/strong>: अनावश्यक कमिट्स को खत्म करने के लिए &lt;code>rebase&lt;/code> का उपयोग करें, और नवीनतम मेनलाइन के साथ अपडेट रहकर एक सीधा इतिहास बनाए रखें।&lt;/li>
&lt;li>&lt;strong>ग्लोबल (साझा कार्यक्षेत्र - Global)&lt;/strong>: फीचर ब्रांच के अस्तित्व को मर्ज कमिट के रूप में DAG में दर्ज करने के लिए &lt;code>merge --no-ff&lt;/code> का उपयोग करें, ताकि इसे रिवर्ट या ट्रैक करना आसान हो।&lt;/li>
&lt;/ul>
&lt;p>DAG की संरचना और हैश फ़ंक्शन्स के तंत्र जैसी गणितीय और संरचनात्मक पृष्ठभूमि को समझकर, Git कमांड्स का उपयोग केवल याद रखने से &amp;ldquo;इरादे के साथ इतिहास डिजाइन करने&amp;rdquo; में बदल जाता है। रिबेस के सुनहरे नियम का पालन करते हुए, स्थिति के अनुसार सबसे उपयुक्त कमांड चुनें, और एक साफ़ कमिट इतिहास बनाएँ जिसे पूरी टीम के लिए पढ़ना और मेंटेन करना आसान हो।&lt;/p></description></item><item><title>Git शुरुआती लोगों द्वारा की जाने वाली आम गलतियाँ और समाधान कमांड (कन्फ्लिक्ट रिज़ॉल्यूशन आदि)</title><link>http://kenji.blog/hi/p/git-beginners-mistakes-and-solutions/</link><pubDate>Sat, 12 Sep 2026 17:00:00 +0900</pubDate><guid>http://kenji.blog/hi/p/git-beginners-mistakes-and-solutions/</guid><description>&lt;img src="http://kenji.blog/p/git-beginners-mistakes-and-solutions/img/eyecatch.jpg" alt="Featured image of post Git शुरुआती लोगों द्वारा की जाने वाली आम गलतियाँ और समाधान कमांड (कन्फ्लिक्ट रिज़ॉल्यूशन आदि)" />&lt;h1 id="git-शरआत-लग-दवर-क-जन-वल-आम-गलतय-और-समधन-कमड-कनफलकट-रजलयशन-आद">Git शुरुआती लोगों द्वारा की जाने वाली आम गलतियाँ और समाधान कमांड (कन्फ्लिक्ट रिज़ॉल्यूशन आदि)
&lt;/h1>&lt;h2 id="1-परचय-हम-git-म-गलतय-कय-करत-ह">1. परिचय: हम Git में गलतियाँ क्यों करते हैं?
&lt;/h2>&lt;p>सॉफ्टवेयर विकास में, Git हवा और पानी की तरह अपरिहार्य हो गया है। हालाँकि, कई शुरुआती लोगों (और कभी-कभी अनुभवी लोगों) के लिए, Git एक &amp;ldquo;डरावने जादुई ब्लैक बॉक्स&amp;rdquo; की तरह महसूस हो सकता है। कमिट्स का गायब होना, अनजाने में गलत ब्रांच में भारी बदलाव पुश कर देना, या स्क्रीन पर ऐसे कन्फ्लिक्ट एरर मैसेज आना जिन्हें आपने पहले कभी नहीं देखा&amp;hellip;। जब आप इस तरह के &amp;ldquo;Git ट्रैप&amp;rdquo; में फँसते हैं, तो आपका काम पूरी तरह से रुक जाता है, और सबसे खराब स्थिति में, आप इस डर से घबरा जाते हैं कि कहीं आप अपने सोर्स कोड को नष्ट तो नहीं कर देंगे।&lt;/p>
&lt;p>Git इतना कठिन और गलतियों का कारण क्यों है? इसका सबसे बड़ा कारण यह है कि &amp;ldquo;हम Git के अंदर क्या हो रहा है, यह समझे बिना केवल बाहरी कमांड्स को याद करके उनका उपयोग करते हैं।&amp;rdquo; Git एक डिस्ट्रीब्यूटेड वर्जन कंट्रोल सिस्टम (DVCS) के रूप में एक मजबूत डिज़ाइन फिलॉसफी पर आधारित है, लेकिन इसका इंटरफ़ेस (CLI) हमेशा सहज नहीं होता है।&lt;/p>
&lt;p>इस लेख में, हम उन &amp;ldquo;गलतियों (सामान्य गलतियों)&amp;rdquo; को कई मामलों में वर्गीकृत करेंगे जिनका अक्सर Git शुरुआती लोग सामना करते हैं, और प्रत्येक के लिए विशिष्ट समाधान कमांड प्रदान करेंगे। हालाँकि, यह सिर्फ कमांड्स की एक सूची (चीट शीट) नहीं होगी। &amp;ldquo;वह गलती क्यों होती है&amp;rdquo; और &amp;ldquo;उस कमांड को चलाने पर Git के अंदर डेटा कैसे चलता है&amp;rdquo;, इस पर हम 10,000 से अधिक वर्णों के साथ गहराई से चर्चा करेंगे, जिसमें &lt;code>.git&lt;/code> डायरेक्टरी की संरचना, बैकग्राउंड में चल रहे Diff एल्गोरिदम की गणितीय पृष्ठभूमि और Mermaid आरेख शामिल होंगे।&lt;/p>
&lt;p>जब आप इस लेख को पढ़ना समाप्त कर लेंगे, तो आप &amp;ldquo;Git डरावना है&amp;rdquo; की भावना से मुक्त हो जाएंगे, और इसके बजाय यह आश्वस्त महसूस करेंगे कि &amp;ldquo;Git से अधिक विश्वसनीय कोई साथी नहीं है।&amp;rdquo; तो चलिए Git की गहरी दुनिया में गोता लगाते हैं।&lt;/p>
&lt;hr>
&lt;h2 id="2-git-क-गहरई-git-डयरकटर-क-आतरक-सरचन-क-समझन">2. Git की गहराई: &lt;code>.git&lt;/code> डायरेक्टरी की आंतरिक संरचना को समझना
&lt;/h2>&lt;p>कई समस्या-समाधान (troubleshooting) को आसान बनाने का पहला कदम यह जानना है कि Git डेटा कैसे स्टोर करता है। आपके प्रोजेक्ट की रूट डायरेक्टरी में मौजूद छिपा हुआ फ़ोल्डर &lt;code>.git&lt;/code>, Git का हृदय है। Git केवल फ़ाइल के अंतर (पैच) को क्रम में रिकॉर्ड करने वाला सिस्टम नहीं है, बल्कि यह डेटा को &lt;strong>स्नैपशॉट के स्ट्रीम&lt;/strong> के रूप में प्रबंधित करता है।&lt;/p>
&lt;h3 id="21-ऑबजकट-मडल-blob-tree-commit">2.1 ऑब्जेक्ट मॉडल: Blob, Tree, Commit
&lt;/h3>&lt;p>Git रिपॉजिटरी की स्थिति को दर्शाने के लिए मुख्य रूप से 3 ऑब्जेक्ट्स का उपयोग करता है। ये ऑब्जेक्ट्स &lt;code>.git/objects&lt;/code> में सेव किए जाते हैं।&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Blob (Binary Large Object)&lt;/strong>
यह वह ऑब्जेक्ट है जो फ़ाइल की सामग्री को ही सेव करता है। फ़ाइल का नाम और अनुमतियों की जानकारी इसमें शामिल नहीं होती है। शुद्ध बाइट अनुक्रम को zlib के साथ संपीड़ित किया जाता है और SHA-1 हैश मान (40-वर्ण हेक्साडेसिमल) द्वारा पहचाना जाता है।&lt;/li>
&lt;li>&lt;strong>Tree&lt;/strong>
यह एक ऑब्जेक्ट है जो डायरेक्टरी की संरचना को दर्शाता है। Tree ऑब्जेक्ट में अन्य Tree ऑब्जेक्ट्स (सबडायरेक्टरी) या Blob ऑब्जेक्ट्स (फ़ाइलें) के पॉइंटर्स (SHA-1 हैश मान), साथ ही उनके फ़ाइल नाम और एक्सेस अनुमतियां शामिल होती हैं। यह UNIX डायरेक्टरी की तरह काम करता है।&lt;/li>
&lt;li>&lt;strong>Commit&lt;/strong>
यह किसी विशिष्ट समय पर संपूर्ण रिपॉजिटरी के शीर्ष-स्तरीय Tree ऑब्जेक्ट के लिए एक पॉइंटर, मेटाडेटा (निर्माता, कमिट तिथि, और कमिट संदेश), और पिछले कमिट (पैरेंट कमिट) के लिए एक पॉइंटर रखता है।&lt;/li>
&lt;/ol>
&lt;pre class="mermaid">
graph TD
Commit1[&amp;#34;कमिट (Hash: 9f8a)&amp;#34;] --&amp;gt; Tree1[&amp;#34;ट्री (Hash: 4b82)&amp;#34;]
Tree1 --&amp;gt; Blob1[&amp;#34;ब्लॉब (Hash: 8d7e) : index.js&amp;#34;]
Tree1 --&amp;gt; Tree2[&amp;#34;ट्री (Hash: 3a2c) : src/&amp;#34;]
Tree2 --&amp;gt; Blob2[&amp;#34;ब्लॉब (Hash: 5f1b) : app.js&amp;#34;]
&lt;/pre>
&lt;h3 id="22-head-और-सदरभ-refs-क-वसतवकत">2.2 HEAD और संदर्भ (Refs) की वास्तविकता
&lt;/h3>&lt;p>Git में काम करते समय आप अक्सर &lt;code>HEAD&lt;/code> शब्द देखते हैं। यह एक &lt;strong>सिम्बॉलिक रेफरेंस (Symbolic Reference)&lt;/strong> है जो उस ब्रांच (या कमिट) को इंगित करता है जिसे आपने वर्तमान में चेक आउट किया है।
यदि आप टेक्स्ट एडिटर में &lt;code>.git/HEAD&lt;/code> फ़ाइल खोलते हैं, तो आपको निम्न स्ट्रिंग दिखाई देगी:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl">ref: refs/heads/main
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>इसका अर्थ है, &amp;ldquo;वर्तमान स्थिति &lt;code>main&lt;/code> ब्रांच के सिरे पर है।&amp;rdquo; और यदि आप &lt;code>.git/refs/heads/main&lt;/code> खोलते हैं, तो वहां एक 40-वर्ण का SHA-1 हैश लिखा होता है, जो नवीनतम Commit ऑब्जेक्ट को इंगित करता है।
Git ब्रांच केवल हल्के पॉइंटर्स (फ़ाइलें) हैं जो विशिष्ट कमिट्स को इंगित करते हैं। केवल इस तथ्य को जानने से यह डर दूर हो जाता है कि &amp;ldquo;अगर मैं ब्रांच को हटा दूं तो क्या सारी फ़ाइलें गायब हो जाएंगी?&amp;rdquo;&lt;/p>
&lt;hr>
&lt;h2 id="3-गणत-स-git-क-समझन-diff-एलगरदम-और-हश-फकशन">3. गणित से Git को समझना: Diff एल्गोरिदम और हैश फ़ंक्शन
&lt;/h2>&lt;p>जब Git कन्फ्लिक्ट का पता लगाता है या फ़ाइलों के बीच अंतर दिखाता है, तो आंतरिक रूप से अत्यधिक उन्नत एल्गोरिदम काम कर रहे होते हैं।&lt;/p>
&lt;h3 id="31-myers-क-diff-एलगरदम">3.1 Myers का Diff एल्गोरिदम
&lt;/h3>&lt;p>Git का डिफ़ॉल्ट अंतर पहचान (difference detection) एल्गोरिदम Eugene W. Myers द्वारा विकसित किया गया था। जब दो टेक्स्ट फ़ाइलें $A$ और $B$ होती हैं, तो $A$ को $B$ में बदलने के लिए &amp;ldquo;न्यूनतम संपादन चरण (सम्मिलन और विलोपन)&amp;rdquo; खोजने की समस्या को ग्राफ सिद्धांत में सबसे छोटे पथ की समस्या (shortest path problem) के रूप में तैयार किया जा सकता है।&lt;/p>
&lt;p>मान लें कि स्ट्रिंग की लंबाई क्रमशः $N, M$ है, और कुल $V = N + M$ है। Myers का एल्गोरिदम संपादन दूरी (Edit Distance) $D$ की खोज करता है। इस एल्गोरिदम की समय जटिलता (time complexity) निम्नलिखित समीकरण द्वारा व्यक्त की जाती है:&lt;/p>
$$ \mathcal{O}(V \cdot D) $$&lt;p>यहाँ, यदि फ़ाइलों के बीच का अंतर छोटा है (यानी, $D$ छोटा है), तो एल्गोरिदम बहुत तेजी से $\mathcal{O}(V)$ पर चलता है। हालाँकि, यदि फ़ाइलें पूरी तरह से अलग हैं, तो $D \approx V$, और सबसे खराब स्थिति की जटिलता (worst-case complexity) $\mathcal{O}(V^2)$ हो जाती है।&lt;/p>
&lt;h3 id="32-patience-diff-और-histogram-diff">3.2 Patience Diff और Histogram Diff
&lt;/h3>&lt;p>हालांकि Myers का एल्गोरिदम उत्कृष्ट है, यह ऐसे अंतर उत्पन्न कर सकता है जो मनुष्यों के लिए सहज (अर्थपूर्ण) नहीं हैं, जैसे कि जब कार्यों या वर्गों के क्रम को बहुत बदल दिया जाता है। इसे हल करने के लिए, Git &lt;code>Patience Diff&lt;/code> और &lt;code>Histogram Diff&lt;/code> लागू करता है।&lt;/p>
&lt;p>Patience Diff &amp;ldquo;उन अद्वितीय पंक्तियों पर ध्यान केंद्रित करता है जो दोनों फ़ाइलों में केवल एक बार दिखाई देती हैं&amp;rdquo; और उनके सबसे लंबे सामान्य अनुवर्ती (Longest Common Subsequence: LCS) को ढूंढता है। अद्वितीय तत्वों की संख्या को $U$ मानकर, LCS की गणना निम्नलिखित जटिलता के साथ हल की जा सकती है:&lt;/p>
$$ \mathcal{O}(U \log U) $$&lt;p>जब आपको लगता है कि कन्फ्लिक्ट को हल करना मुश्किल है, तो एक तरीका &lt;code>git diff --histogram&lt;/code> का उपयोग करना है, या इस एल्गोरिदम को मर्ज रणनीति के रूप में निर्दिष्ट करना है (&lt;code>git merge -s recursive -X histogram&lt;/code>)।&lt;/p>
&lt;h3 id="33-sha-1-और-टककर-क-सभवन-collision-probability">3.3 SHA-1 और टक्कर की संभावना (Collision Probability)
&lt;/h3>&lt;p>Git सभी ऑब्जेक्ट्स को SHA-1 हैश मानों के साथ प्रबंधित करता है। हैश स्पेस का आकार $2^{160}$ है। जन्मदिन के विरोधाभास (Birthday Paradox) का उपयोग करके हैश टक्कर (विभिन्न सामग्री का समान हैश मान होना) होने की संभावना का अनुमान लगाते हुए, 50% की टक्कर संभावना $p$ होने के लिए आवश्यक ऑब्जेक्ट्स की संख्या $k$ इस प्रकार है:&lt;/p>
$$ k \approx \sqrt{2 \ln(2)} \cdot 2^{80} \approx 1.2 \times 2^{80} $$&lt;p>यह एक खगोलीय संख्या है, और सामान्य सॉफ्टवेयर विकास में अनजाने में होने वाली टक्कर की संभावना वस्तुतः शून्य है। इसलिए, Git हैश मान को &amp;ldquo;पूर्ण अद्वितीय ID&amp;rdquo; के रूप में भरोसा करके काम करता है।&lt;/p>
&lt;hr>
&lt;h2 id="4-कस-सटड-1-गलत-बरच-म-कमट-कर-दय">4. केस स्टडी 1: गलत ब्रांच में कमिट कर दिया!
&lt;/h2>&lt;p>&lt;strong>【स्थिति】&lt;/strong>
यह महसूस किए बिना कि मैं &lt;code>main&lt;/code> ब्रांच पर काम कर रहा हूँ, मैंने नई सुविधा के लिए तेज़ी से कोड लिख दिया, और यहां तक कि &lt;code>git commit&lt;/code> भी कर दिया। मुझे &lt;code>feature/login&lt;/code> नाम से एक ब्रांच बनानी चाहिए थी और वहां काम करना चाहिए था!&lt;/p>
&lt;h3 id="समधन-git-reset-और-बरच-बनन">समाधान: &lt;code>git reset&lt;/code> और ब्रांच बनाना
&lt;/h3>&lt;p>Git में, कमिट स्वतंत्र ऑब्जेक्ट हैं, और ब्रांच केवल पॉइंटर्स हैं। इसलिए, आप &amp;ldquo;एक नई ब्रांच बनाकर और फिर वर्तमान ब्रांच के पॉइंटर को पीछे हटाकर&amp;rdquo; इसे तुरंत हल कर सकते हैं।&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;span class="lnt">8
&lt;/span>&lt;span class="lnt">9
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 1. वर्तमान कमिट (गलती से बनाया गया कमिट) को इंगित करने वाली एक नई ब्रांच बनाएँ&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ git branch feature/login
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 2. main ब्रांच के पॉइंटर को 1 कमिट पहले (HEAD~1) रिवाइंड करें&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># --keep का उपयोग करके, आप कार्यशील डायरेक्टरी में बिना कमिट किए गए परिवर्तनों को बनाए रखते हुए सुरक्षित रूप से रीसेट कर सकते हैं।&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ git reset --keep HEAD~1
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 3. सही ब्रांच पर स्विच करें&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ git checkout feature/login
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="आरख-अदर-कय-हआ">आरेख: अंदर क्या हुआ?
&lt;/h3>&lt;p>आइए इस दौरान ब्रांच पॉइंटर्स की गति की कल्पना करने के लिए Mermaid के &lt;code>gitGraph&lt;/code> का उपयोग करें।&lt;/p>
&lt;pre class="mermaid">
gitGraph
commit id: &amp;#34;प्रारंभिक कमिट&amp;#34;
commit id: &amp;#34;बग फिक्स&amp;#34;
commit id: &amp;#34;गलत कमिट&amp;#34; type: HIGHLIGHT
branch feature/login
checkout feature/login
checkout main
&lt;/pre>
&lt;p>प्रारंभ में, &lt;code>main&lt;/code> और &lt;code>HEAD&lt;/code> &amp;ldquo;गलत कमिट&amp;rdquo; को इंगित कर रहे थे, लेकिन &lt;code>git branch feature/login&lt;/code> के साथ, वहां एक नया पॉइंटर बनाया गया है। उसके बाद, &lt;code>git reset&lt;/code> के माध्यम से केवल &lt;code>main&lt;/code> पॉइंटर &amp;ldquo;बग फिक्स&amp;rdquo; स्थिति में वापस आ जाता है। कोई भी ऑब्जेक्ट वास्तव में डिलीट नहीं हुआ है।&lt;/p>
&lt;hr>
&lt;h2 id="5-कस-सटड-2-पश-कए-गए-कमट-क-रदद-करन-चहत-ह">5. केस स्टडी 2: पुश किए गए कमिट को रद्द करना चाहता हूँ!
&lt;/h2>&lt;p>&lt;strong>【स्थिति】&lt;/strong>
मैंने आधी रात के जोश में बग से भरा कोड कमिट किया, और इसे &lt;code>git push origin main&lt;/code> के साथ रिमोट रिपॉजिटरी में भी पब्लिश कर दिया। मुझे एक गंभीर बग का एहसास हुआ और मैं पीला पड़ गया।&lt;/p>
&lt;h3 id="समधन-1-इतहस-क-रदद-करन-क-लए-git-revert-अनशसत-और-सरकषत">समाधान 1: इतिहास को रद्द करने के लिए &lt;code>git revert&lt;/code> (अनुशंसित और सुरक्षित)
&lt;/h3>&lt;p>टीम डेवलपमेंट में, &lt;code>git reset&lt;/code> आदि के साथ पहले से ही पुश किए गए कमिट्स के इतिहास के साथ छेड़छाड़ करना सख्त मना है। यह अन्य डेवलपर्स के स्थानीय रिपॉजिटरी के साथ असंगत हो जाएगा। सही तरीका यह है कि &lt;strong>&amp;ldquo;गलत कमिट के परिवर्तनों को पूरी तरह से रद्द करने के लिए एक नया विपरीत कमिट बनाएँ।&amp;rdquo;&lt;/strong> यही &lt;code>git revert&lt;/code> है।&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># नवीनतम कमिट को रद्द करने के लिए एक कमिट बनाएँ&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ git revert HEAD
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">[&lt;/span>main 7f3a8b2&lt;span class="o">]&lt;/span> Revert &lt;span class="s2">&amp;#34;गलत कमिट का संदेश&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="m">1&lt;/span> file changed, &lt;span class="m">1&lt;/span> insertion&lt;span class="o">(&lt;/span>+&lt;span class="o">)&lt;/span>, &lt;span class="m">10&lt;/span> deletions&lt;span class="o">(&lt;/span>-&lt;span class="o">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># रिमोट पर पुश करें&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ git push origin main
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;pre class="mermaid">
gitGraph
commit id: &amp;#34;कमिट A&amp;#34;
commit id: &amp;#34;कमिट B (गलती)&amp;#34;
commit id: &amp;#34;कमिट B को Revert करें&amp;#34; type: REVERSE
&lt;/pre>
&lt;p>इतिहास आगे बढ़ता रहता है, केवल कोड की स्थिति वापस आ जाती है।&lt;/p>
&lt;h3 id="समधन-2-इतहस-क-सथ-छडछड-करन-क-लए-git-push---force-with-lease">समाधान 2: इतिहास के साथ छेड़छाड़ करने के लिए &lt;code>git push --force-with-lease&lt;/code>
&lt;/h3>&lt;p>यदि आपने अभी-अभी किसी ऐसी ब्रांच में पुश किया है जिसका उपयोग केवल आप करते हैं, तो इतिहास को फिर से लिखना स्वीकार्य है।&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># स्थानीय रूप से कमिट को रीसेट करें और ठीक करें&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ git reset --hard HEAD~1
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ git add .
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ git commit -m &lt;span class="s2">&amp;#34;Correct implementation&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># रिमोट इतिहास को जबरन ओवरराइट करें&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ git push origin feature/login --force-with-lease
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>&lt;code>--force-with-lease&lt;/code> एक सुरक्षित फोर्स पुश है जो गलती से किसी और के काम को ओवरराइट करने से रोकता है।&lt;/p>
&lt;hr>
&lt;h2 id="6-कस-सटड-3-कम-क-बच-म-कस-अनय-बरच-पर-सवच-करन-चहत-ह-stash-क-जद">6. केस स्टडी 3: काम के बीच में किसी अन्य ब्रांच पर स्विच करना चाहता हूँ (Stash का जादू)
&lt;/h2>&lt;p>&lt;strong>【स्थिति】&lt;/strong>
&lt;code>feature/A&lt;/code> ब्रांच पर एक नई सुविधा लागू करते समय, सोर्स कोड अभी भी आधी-अधूरी स्थिति में है जहां यह संकलित (compile) भी नहीं होगा। अचानक, मेरे बॉस ने मुझे निर्देश दिया, &amp;ldquo;&lt;code>main&lt;/code> ब्रांच के प्रोडक्शन वातावरण में एक आपातकालीन बग है, कृपया इसे अभी ठीक करें!&amp;rdquo;&lt;/p>
&lt;h3 id="समधन-git-stash-क-सथ-आशरय-लन">समाधान: &lt;code>git stash&lt;/code> के साथ आश्रय लेना
&lt;/h3>&lt;p>&lt;code>git stash&lt;/code> एक ऐसा कमांड है जो बिना कमिट किए गए परिवर्तनों को अस्थायी क्षेत्र में सेव करता है।&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 1. काम प्रगति पर है उसे सेव करें&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ git stash push -m &lt;span class="s2">&amp;#34;WIP: feature A partially implemented&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 2. main ब्रांच पर स्विच करने में सक्षम&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ git checkout main
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># ...(आपातकालीन बग फिक्स करें, कमिट करें और पुश करें)...&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 3. काम पूरा होने पर मूल ब्रांच पर वापस आएं&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ git checkout feature/A
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 4. सेव किए गए परिवर्तनों को पुनर्स्थापित करें&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ git stash pop
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>जब आप &lt;code>git stash&lt;/code> चलाते हैं, तो Git आंतरिक रूप से दो विशेष कमिट ऑब्जेक्ट बनाता है और उन्हें &lt;code>refs/stash&lt;/code> नामक संदर्भ में सहेजता है। दूसरे शब्दों में, Stash अंततः &amp;ldquo;बिना नाम का एक अस्थायी कमिट&amp;rdquo; है।&lt;/p>
&lt;hr>
&lt;h2 id="7-कस-सटड-4-detached-head-अवसथ-क-डर">7. केस स्टडी 4: &amp;ldquo;Detached HEAD&amp;rdquo; अवस्था का डर
&lt;/h2>&lt;p>&lt;strong>【स्थिति】&lt;/strong>
मैं अतीत में एक विशिष्ट बिंदु पर कोड की जांच करना चाहता था, इसलिए मैंने &lt;code>git checkout 9f8a7b6&lt;/code> चलाया। तब &lt;code>You are in 'detached HEAD' state.&lt;/code> प्रदर्शित हुआ। मैंने वैसे ही कमिट किया, लेकिन जब मैंने ब्रांच स्विच की तो कमिट गायब हो गया!&lt;/p>
&lt;h3 id="detached-head-क-ततर">Detached HEAD का तंत्र
&lt;/h3>&lt;p>आमतौर पर &lt;code>HEAD&lt;/code> एक ब्रांच की ओर इशारा करता है जैसे &lt;code>refs/heads/main&lt;/code>। हालाँकि, यदि आप सीधे किसी विशिष्ट कमिट को चेक आउट करते हैं, तो &lt;code>HEAD&lt;/code> सीधे कमिट ऑब्जेक्ट की ओर इशारा करेगा। इसे &lt;strong>Detached HEAD (अलग हुआ HEAD)&lt;/strong> कहा जाता है।&lt;/p>
&lt;pre class="mermaid">
graph TD
A[&amp;#34;कमिट A&amp;#34;] --&amp;gt; B[&amp;#34;कमिट B&amp;#34;]
B --&amp;gt; C[&amp;#34;कमिट C&amp;#34;]
C --&amp;gt; D[&amp;#34;कमिट D&amp;#34;]
BranchMain[&amp;#34;ब्रांच: main&amp;#34;] --&amp;gt; D
HEAD[&amp;#34;HEAD&amp;#34;] --&amp;gt; B
style HEAD fill:#f9f,stroke:#333,stroke-width:4px
&lt;/pre>
&lt;p>इस स्थिति में कमिट्स जोड़ने के बाद भी, कोई भी ब्रांच उस नए कमिट को ट्रैक नहीं करेगी। जिस क्षण आप किसी अन्य ब्रांच पर स्विच करते हैं, नया कमिट खो जाएगा।&lt;/p>
&lt;h3 id="समधन-इस-एक-नई-बरच-क-रप-म-सहज">समाधान: इसे एक नई ब्रांच के रूप में सहेजें
&lt;/h3>&lt;p>आप जहां हैं वहां एक नई ब्रांच बनाकर इसे हल किया जा सकता है।&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># वर्तमान HEAD की स्थिति पर एक नई ब्रांच बनाएँ और उस पर स्विच करें&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ git checkout -b feature/recovered-work
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;hr>
&lt;h2 id="8-कस-सटड-5-मरज-और-रबस-म-कनफलकट-क-समधन">8. केस स्टडी 5: मर्ज और रिबेस में कन्फ्लिक्ट का समाधान
&lt;/h2>&lt;p>&lt;strong>【स्थिति】&lt;/strong>
जब मैंने &lt;code>git merge&lt;/code> या &lt;code>git rebase&lt;/code> चलाया, तो &lt;code>CONFLICT (content)&lt;/code> प्रदर्शित हुआ, और प्रक्रिया बाधित हो गई।&lt;/p>
&lt;h3 id="मरज-merge-और-रबस-rebase-क-बच-अतर">मर्ज (Merge) और रिबेस (Rebase) के बीच अंतर
&lt;/h3>&lt;ol>
&lt;li>&lt;strong>Merge (मर्ज)&lt;/strong>
2 ब्रांचों के नवीनतम कमिट और एक सामान्य पूर्वज का उपयोग करके 3-वे मर्ज करता है, और एक मर्ज कमिट बनाता है।&lt;/li>
&lt;li>&lt;strong>Rebase (रिबेस)&lt;/strong>
वर्तमान ब्रांच के कमिट्स को अस्थायी रूप से सेव करता है, और उन्हें लक्ष्य (target) के शीर्ष पर फिर से लागू करता है। इतिहास एक सीधी रेखा बन जाता है।&lt;/li>
&lt;/ol>
&lt;pre class="mermaid">
gitGraph
commit id: &amp;#34;M1&amp;#34;
commit id: &amp;#34;M2&amp;#34;
branch feature
checkout feature
commit id: &amp;#34;F1&amp;#34;
commit id: &amp;#34;F2&amp;#34;
checkout main
commit id: &amp;#34;M3&amp;#34;
merge feature
&lt;/pre>
&lt;h3 id="कनफलकट-क-समधन-कस-कर">कन्फ्लिक्ट का समाधान कैसे करें
&lt;/h3>&lt;p>जिन फ़ाइलों में कन्फ्लिक्ट है उनमें निम्नलिखित मार्कर डाले गए हैं:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="o">&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&lt;/span> &lt;span class="nx">HEAD&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kr">const&lt;/span> &lt;span class="nx">apiUrl&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;https://api.production.example.com&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">=======&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kr">const&lt;/span> &lt;span class="nx">apiUrl&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;https://api.staging.example.com&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span> &lt;span class="nx">feature&lt;/span>&lt;span class="o">/&lt;/span>&lt;span class="k">new&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="nx">api&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>समाधान की प्रक्रिया अत्यंत सरल है।&lt;/p>
&lt;ol>
&lt;li>&lt;strong>मार्कर्स को हटाएँ और सही कोड में ठीक करें।&lt;/strong>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="kr">const&lt;/span> &lt;span class="nx">apiUrl&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">process&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">env&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">NODE_ENV&lt;/span> &lt;span class="o">===&lt;/span> &lt;span class="s1">&amp;#39;production&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">?&lt;/span> &lt;span class="s2">&amp;#34;https://api.production.example.com&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;https://api.staging.example.com&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;/li>
&lt;li>&lt;strong>हल की गई फ़ाइल को स्टेजिंग में जोड़ें।&lt;/strong>
&lt;code>git add&lt;/code> की भूमिका &amp;ldquo;Git को यह बताना है कि कन्फ्लिक्ट हल हो गया है।&amp;rdquo;
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">$ git add index.js
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;/li>
&lt;li>&lt;strong>प्रक्रिया को पूरा करें।&lt;/strong>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># मर्ज के मामले में&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ git commit -m &lt;span class="s2">&amp;#34;Resolve merge conflict in index.js&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># रिबेस के मामले में&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ git rebase --continue
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;/li>
&lt;/ol>
&lt;p>यदि आप घबराते हैं, तो आप हमेशा &lt;code>$ git merge --abort&lt;/code> या &lt;code>$ git rebase --abort&lt;/code> के साथ निरस्त (abort) कर सकते हैं।&lt;/p>
&lt;hr>
&lt;h2 id="9-कस-सटड-6-कमट-इतहस-बहत-गद-ह-git-rebase--i">9. केस स्टडी 6: कमिट इतिहास बहुत गंदा है! &lt;code>git rebase -i&lt;/code>
&lt;/h2>&lt;p>&lt;strong>【स्थिति】&lt;/strong>
कई छोटे कमिट्स हैं जैसे &amp;ldquo;टाइपो ठीक किया&amp;rdquo;, &amp;ldquo;फिर से ठीक किया&amp;rdquo;, &amp;ldquo;टेस्ट जोड़ा&amp;rdquo;, आदि। यदि मैं इसे इसी तरह &lt;code>main&lt;/code> में मर्ज करता हूं, तो इतिहास गंदा हो जाएगा।&lt;/p>
&lt;h3 id="समधन-इटरएकटव-रबस">समाधान: इंटरएक्टिव रिबेस
&lt;/h3>&lt;p>&lt;code>git rebase -i&lt;/code> (interactive) का उपयोग करके, आप पिछले कमिट्स के क्रम को पुनर्व्यवस्थित कर सकते हैं, कई कमिट्स को एक (squash) में जोड़ सकते हैं, या कमिट संदेशों को संशोधित कर सकते हैं।&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># पिछले 3 कमिट्स को व्यवस्थित करें&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ git rebase -i HEAD~3
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>संपादक (editor) खुल जाएगा और निम्न प्रदर्शित करेगा:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl">pick 1a2b3c4 टाइपो ठीक किया
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">pick 2b3c4d5 फिर से ठीक किया
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">pick 3c4d5e6 टेस्ट जोड़ा
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>इसे इस प्रकार फिर से लिखें:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl">pick 1a2b3c4 फीचर X लागू किया
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">squash 2b3c4d5 फिर से ठीक किया
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">squash 3c4d5e6 टेस्ट जोड़ा
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>जब आप इसे सहेजते हैं और बंद करते हैं, तो ये 3 कमिट खूबसूरती से एक में मिल जाएंगे।&lt;/p>
&lt;hr>
&lt;h2 id="10-कस-सटड-7-मझ-नह-पत-क-बग-कब-पश-कय-गय-थ-git-bisect">10. केस स्टडी 7: मुझे नहीं पता कि बग कब पेश किया गया था! &lt;code>git bisect&lt;/code>
&lt;/h2>&lt;p>&lt;strong>【स्थिति】&lt;/strong>
वर्तमान &lt;code>main&lt;/code> ब्रांच में एक बग है, लेकिन 1 महीने पहले रिलीज के समय यह सामान्य था। मैं यह पता लगाना चाहता हूं कि किस कमिट ने बग पेश किया, लेकिन 100 से अधिक कमिट हैं और इसे मैन्युअल रूप से करना असंभव है!&lt;/p>
&lt;h3 id="समधन-बइनर-सरच-क-सथ-बग-क-पहचन-करन">समाधान: बाइनरी सर्च के साथ बग की पहचान करना
&lt;/h3>&lt;p>Git में एक अंतर्निहित उपकरण है जो गणितीय बाइनरी सर्च (Binary Search) के माध्यम से उस कमिट को ढूंढता है जिसने बग पेश किया था। चूँकि जटिलता $\mathcal{O}(\log N)$ है, भले ही 1000 कमिट हों, इसे लगभग 10 परीक्षणों में पहचाना जा सकता है।&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># खोज शुरू करें&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ git bisect start
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># वर्तमान कमिट में एक बग है (bad)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ git bisect bad
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 1 महीने पहले (उदाहरण के लिए हैश a1b2c3d है) सामान्य था (good)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ git bisect good a1b2c3d
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Git स्वचालित रूप से मध्यवर्ती कमिट्स की जांच करेगा, इसलिए परीक्षण चलाएँ&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># यदि परीक्षण सफल होता है:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ git bisect good
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># यदि परीक्षण विफल रहता है:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ git bisect bad
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>बस इसे दोहराने से, Git आपको सटीक रूप से बता देगा कि &amp;ldquo;यह कमिट पहला Bad कमिट है।&amp;rdquo; पूरा होने पर, मूल स्थिति में वापस आने के लिए &lt;code>$ git bisect reset&lt;/code> का उपयोग करें।&lt;/p>
&lt;hr>
&lt;h2 id="11-अतम-सरकष-जल-git-reflog">11. अंतिम सुरक्षा जाल: &lt;code>git reflog&lt;/code>
&lt;/h2>&lt;p>Git में हर &amp;ldquo;गलती&amp;rdquo; के लिए अंतिम गुप्त तकनीक &lt;code>git reflog&lt;/code> है। Git कुछ समय के लिए सभी स्थानीय संचालन इतिहास (HEAD गति इतिहास) रिकॉर्ड करता है। भले ही आप किसी ब्रांच को हटा दें या गलत तरीके से रीसेट कर दें, आप &lt;code>git reflog&lt;/code> के साथ पिछले हैश को ढूंढ सकते हैं, और केवल &lt;code>git reset --hard&lt;/code> का उपयोग करके उसे पुनर्प्राप्त कर सकते हैं।&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">$ git reflog
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">9f8a7b6 &lt;span class="o">(&lt;/span>HEAD -&amp;gt; main&lt;span class="o">)&lt;/span> HEAD@&lt;span class="o">{&lt;/span>0&lt;span class="o">}&lt;/span>: commit: Add new feature
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">1a2b3c4 HEAD@&lt;span class="o">{&lt;/span>1&lt;span class="o">}&lt;/span>: reset: moving to HEAD~1
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="12-नषकरष">12. निष्कर्ष
&lt;/h2>&lt;p>हमने Git शुरुआती लोगों द्वारा की जाने वाली आम गलतियों, उनके पीछे Git के तंत्र और समाधानों को बहुत विस्तार से समझाया है। गलत ब्रांच में कमिट करना, पुश किए गए कमिट को रद्द करना, Stash का उपयोग करना, Detached HEAD से वापस आना, और कन्फ्लिक्ट्स को हल करना। इन सभी में, यह कल्पना करना महत्वपूर्ण है कि &amp;ldquo;पर्दे के पीछे Git किन ऑब्जेक्ट्स और पॉइंटर्स में हेरफेर कर रहा है।&amp;rdquo;&lt;/p>
&lt;p>सख्त Diff एल्गोरिदम जो गणितीय सूत्रों में व्यक्त किया जा सकता है, फ़ाइलों के बीच अंतर की गणना करता है, और क्रिप्टोग्राफ़िक हैश फ़ंक्शन इतिहास की अखंडता (integrity) सुनिश्चित करते हैं। यदि आप इस सुंदर डिज़ाइन दर्शन को समझते हैं, तो आप महसूस करेंगे कि Git कभी भी &amp;ldquo;अज्ञात ब्लैक बॉक्स&amp;rdquo; नहीं है, बल्कि आपके सोर्स कोड की सुरक्षा करने वाली सबसे मजबूत ढाल है।&lt;/p>
&lt;p>अगली बार जब आप सोचें &amp;ldquo;मैंने गलती कर दी!&amp;rdquo;, तो टर्मिनल को जल्दी में बंद न करें, एक गहरी सांस लें और &lt;code>git status&lt;/code> टाइप करें। Git निश्चित रूप से आपको पुनर्प्राप्ति (recovery) के लिए संकेत देगा।&lt;/p></description></item></channel></rss>