{
  "title": "संस्करण नियंत्रण (Git)",
  "excerpt": "संस्करण नियंत्रण का _सही तरीके से_ उपयोग कैसे करें, और इसका लाभ उठाकर खुद को आपदा से बचाएं, दूसरों के साथ सहयोग करें, और समस्याग्रस्त परिवर्तनों को जल्दी से खोजें और अलग करें। अब और `rm -rf; git clone` नहीं। अब और merge conflicts नहीं (खैर, कम से कम उनमें से कम)। अब और commented-out code के बड़े ब्लॉक नहीं। अब और इस बारे में चिंता नहीं कि आपके कोड को क्या तोड़ा यह कैसे खोजें। अब और \"ओह नहीं, क्या हमने काम करने वाले कोड को डिलीट कर दिया?!\" नहीं।",
  "content_html": "<p>संस्करण नियंत्रण प्रणालियाँ (VCSs) ऐसे उपकरण हैं जिनका उपयोग source code (या फ़ाइलों और फ़ोल्डरों के अन्य संग्रहों) में परिवर्तनों को ट्रैक करने के लिए किया जाता है। जैसा कि नाम से पता चलता है, ये उपकरण परिवर्तनों का इतिहास बनाए रखने में मदद करते हैं; इसके अलावा, वे सहयोग को सुविधाजनक बनाते हैं। VCSs एक फ़ोल्डर और उसकी सामग्री में परिवर्तनों को snapshots की एक श्रृंखला में ट्रैक करते हैं, जहाँ प्रत्येक snapshot एक top-level directory के भीतर फ़ाइलों/फ़ोल्डरों की संपूर्ण स्थिति को समाहित करता है। VCSs metadata भी बनाए रखते हैं जैसे कि प्रत्येक snapshot किसने बनाया, प्रत्येक snapshot से जुड़े संदेश, और इसी तरह।</p>\n\n<p>संस्करण नियंत्रण उपयोगी क्यों है? यहां तक कि जब आप अकेले काम कर रहे हों, तो यह आपको किसी प्रोजेक्ट के पुराने snapshots को देखने, कुछ परिवर्तन क्यों किए गए इसका लॉग रखने, विकास की समानांतर शाखाओं पर काम करने, और बहुत कुछ करने की अनुमति दे सकता है। दूसरों के साथ काम करते समय, यह देखने के लिए कि अन्य लोगों ने क्या बदला है, साथ ही समवर्ती विकास में संघर्षों को हल करने के लिए यह एक अमूल्य उपकरण है।</p>\n\n<p>आधुनिक VCSs आपको आसानी से (और अक्सर स्वचालित रूप से) इस तरह के सवालों के जवाब देने देते हैं:</p>\n\n<ul>\n<li>इस module को किसने लिखा?</li>\n<li>इस विशेष फ़ाइल की इस विशेष पंक्ति को कब संपादित किया गया था? किसके द्वारा? इसे क्यों संपादित किया गया था?</li>\n<li>पिछले 1000 revisions में, कोई विशेष unit test कब/क्यों काम करना बंद कर दिया?</li>\n</ul>\n\n<p>जबकि अन्य VCSs मौजूद हैं, <strong>Git</strong> संस्करण नियंत्रण के लिए वास्तविक मानक है। यह <a href=\"https://xkcd.com/1597/\">XKCD comic</a> Git की प्रतिष्ठा को दर्शाता है:</p>\n\n<p><img src=\"https://imgs.xkcd.com/comics/git.png\" alt=\"xkcd 1597\" /></p>\n\n<p>क्योंकि Git का interface एक leaky abstraction है, Git को top-down सीखना (इसके interface / command-line interface से शुरू करना) बहुत भ्रम पैदा कर सकता है। मुट्ठी भर commands को याद करना और उन्हें जादुई मंत्रों के रूप में सोचना संभव है, और जब भी कुछ गलत हो जाए तो ऊपर दिए गए comic में दिए गए दृष्टिकोण का पालन करना संभव है।</p>\n\n<p>जबकि Git का interface कुरूप है, इसका अंतर्निहित डिज़ाइन और विचार सुंदर हैं। जबकि एक कुरूप interface को <em>याद</em> करना पड़ता है, एक सुंदर डिज़ाइन को <em>समझा</em> जा सकता है। इस कारण से, हम Git की bottom-up व्याख्या देते हैं, इसके data model से शुरू करते हुए और बाद में command-line interface को कवर करते हैं। एक बार data model समझ में आ जाने के बाद, commands को बेहतर ढंग से समझा जा सकता है कि वे अंतर्निहित data model को कैसे manipulate करते हैं।</p>\n\n<h1>Git का data model</h1>\n\n<p>संस्करण नियंत्रण के लिए आप कई ad-hoc दृष्टिकोण अपना सकते हैं। Git के पास एक सुविचारित model है जो संस्करण नियंत्रण की सभी अच्छी सुविधाओं को सक्षम बनाता है, जैसे इतिहास बनाए रखना, branches का समर्थन करना, और सहयोग को सक्षम करना।</p>\n\n<h2>Snapshots</h2>\n\n<p>Git किसी top-level directory के भीतर फ़ाइलों और फ़ोल्डरों के संग्रह के इतिहास को snapshots की एक श्रृंखला के रूप में model करता है। Git की शब्दावली में, एक फ़ाइल को \"blob\" कहा जाता है, और यह सिर्फ bytes का एक समूह है। एक directory को \"tree\" कहा जाता है, और यह नामों को blobs या trees से map करता है (इसलिए directories में अन्य directories हो सकती हैं)। एक snapshot वह top-level tree है जिसे ट्रैक किया जा रहा है। उदाहरण के लिए, हमारे पास निम्नानुसार एक tree हो सकता है:</p>\n\n<pre><code>&lt;root&gt; (tree)\n|\n+- foo (tree)\n|  |\n|  + bar.txt (blob, contents = \"hello world\")\n|\n+- baz.txt (blob, contents = \"git is wonderful\")\n</code></pre>\n\n<p>Top-level tree में दो तत्व होते हैं, एक tree \"foo\" (जिसमें स्वयं एक तत्व होता है, एक blob \"bar.txt\"), और एक blob \"baz.txt\"।</p>\n\n<h2>इतिहास को model करना: snapshots को संबंधित करना</h2>\n\n<p>एक संस्करण नियंत्रण प्रणाली को snapshots को कैसे संबंधित करना चाहिए? एक सरल model एक रैखिक इतिहास होगा। एक इतिहास समय-क्रम में snapshots की एक सूची होगी। कई कारणों से, Git इस तरह के सरल model का उपयोग नहीं करता है।</p>\n\n<p>Git में, एक इतिहास snapshots का एक directed acyclic graph (DAG) है। यह एक फैंसी गणित शब्द की तरह लग सकता है, लेकिन डरें नहीं। इसका मतलब यह है कि Git में प्रत्येक snapshot \"parents\" के एक सेट को संदर्भित करता है, वे snapshots जो इससे पहले थे। यह एक single parent के बजाय parents का एक सेट है (जैसा कि एक रैखिक इतिहास में होगा) क्योंकि एक snapshot कई parents से उतर सकता है, उदाहरण के लिए, विकास की दो समानांतर शाखाओं को संयोजित (merging) करने के कारण।</p>\n\n<p>Git इन snapshots को \"commit\" कहता है। एक commit history को visualize करना कुछ इस तरह दिख सकता है:</p>\n\n<pre><code>o &lt;-- o &lt;-- o &lt;-- o\n            ^\n             \\\n              --- o &lt;-- o\n</code></pre>\n\n<p>ऊपर दिए गए ASCII art में, <code>o</code>s व्यक्तिगत commits (snapshots) से मेल खाते हैं। तीर प्रत्येक commit के parent की ओर इशारा करते हैं (यह एक \"comes before\" संबंध है, \"comes after\" नहीं)। तीसरे commit के बाद, इतिहास दो अलग-अलग branches में विभाजित हो जाता है। यह उदाहरण के लिए, दो अलग-अलग features के समानांतर, एक दूसरे से स्वतंत्र रूप से विकसित होने से मेल खा सकता है। भविष्य में, इन branches को merge किया जा सकता है ताकि एक नया snapshot बनाया जा सके जो दोनों features को शामिल करता है, एक नया इतिहास बनाता है जो इस तरह दिखता है, नए बनाए गए merge commit को bold में दिखाया गया है:</p>\n\n<pre class=\"highlight\">\n<code>\no &lt;-- o &lt;-- o &lt;-- o &lt;---- <strong>o</strong>\n            ^            /\n             \\          v\n              --- o &lt;-- o\n</code>\n</pre>\n\n<p>Git में commits immutable हैं। इसका मतलब यह नहीं है कि गलतियों को ठीक नहीं किया जा सकता है; यह सिर्फ इतना है कि commit history में \"edits\" वास्तव में पूरी तरह से नए commits बना रहे हैं, और references (नीचे देखें) को नए वाले की ओर इशारा करने के लिए अपडेट किया जाता है।</p>\n\n<h2>Data model, pseudocode के रूप में</h2>\n\n<p>Git के data model को pseudocode में लिखा देखना instructive हो सकता है:</p>\n\n<pre><code>// एक फ़ाइल bytes का एक समूह है\ntype blob = array&lt;byte&gt;\n\n// एक directory में नामित फ़ाइलें और directories होती हैं\ntype tree = map&lt;string, tree | blob&gt;\n\n// एक commit में parents, metadata, और top-level tree होता है\ntype commit = struct {\n    parents: array&lt;commit&gt;\n    author: string\n    message: string\n    snapshot: tree\n}\n</code></pre>\n\n<p>यह इतिहास का एक स्वच्छ, सरल model है।</p>\n\n<h2>Objects और content-addressing</h2>\n\n<p>एक \"object\" एक blob, tree, या commit है:</p>\n\n<pre><code>type object = blob | tree | commit\n</code></pre>\n\n<p>Git data store में, सभी objects उनके <a href=\"https://en.wikipedia.org/wiki/SHA-1\">SHA-1 hash</a> द्वारा content-addressed हैं।</p>\n\n<pre><code>objects = map&lt;string, object&gt;\n\ndef store(object):\n    id = sha1(object)\n    objects[id] = object\n\ndef load(id):\n    return objects[id]\n</code></pre>\n\n<p>Blobs, trees, और commits इस तरह से एकीकृत हैं: वे सभी objects हैं। जब वे अन्य objects को संदर्भित करते हैं, तो वे वास्तव में उन्हें अपने on-disk representation में <em>contain</em> नहीं करते हैं, बल्कि उनके hash द्वारा उनका reference रखते हैं।</p>\n\n<p>उदाहरण के लिए, उदाहरण directory structure के लिए tree <a href=\"#snapshots\">ऊपर</a> (<code>git cat-file -p 698281bc680d1995c5f4caaf3359721a5a58d48d</code> का उपयोग करके visualized), इस तरह दिखता है:</p>\n\n<pre><code>100644 blob 4448adbf7ecd394f42ae135bbeed9676e894af85    baz.txt\n040000 tree c68d233a33c5c06e0340e4c224f0afca87c8ce87    foo\n</code></pre>\n\n<p>Tree स्वयं अपनी सामग्री के लिए pointers रखता है, <code>baz.txt</code> (एक blob) और <code>foo</code> (एक tree)। यदि हम <code>git cat-file -p 4448adbf7ecd394f42ae135bbeed9676e894af85</code> के साथ baz.txt से संबंधित hash द्वारा addressed सामग्री को देखते हैं, तो हमें निम्नलिखित मिलता है:</p>\n\n<pre><code>git is wonderful\n</code></pre>\n\n<h2>References</h2>\n\n<p>अब, सभी snapshots को उनके SHA-1 hashes द्वारा पहचाना जा सकता है। यह असुविधाजनक है, क्योंकि मनुष्य 40 hexadecimal characters की strings को याद रखने में अच्छे नहीं हैं।</p>\n\n<p>इस समस्या का Git का समाधान SHA-1 hashes के लिए human-readable नाम हैं, जिन्हें \"references\" कहा जाता है। References commits के pointers हैं। Objects के विपरीत, जो immutable हैं, references mutable हैं (एक नए commit की ओर इशारा करने के लिए अपडेट किए जा सकते हैं)। उदाहरण के लिए, <code>master</code> reference आमतौर पर विकास की मुख्य शाखा में नवीनतम commit की ओर इशारा करता है।</p>\n\n<pre><code>references = map&lt;string, string&gt;\n\ndef update_reference(name, id):\n    references[name] = id\n\ndef read_reference(name):\n    return references[name]\n\ndef load_reference(name_or_id):\n    if name_or_id in references:\n        return load(references[name_or_id])\n    else:\n        return load(name_or_id)\n</code></pre>\n\n<p>इसके साथ, Git इतिहास में किसी विशेष snapshot को संदर्भित करने के लिए \"master\" जैसे human-readable नामों का उपयोग कर सकता है, एक लंबी hexadecimal string के बजाय।</p>\n\n<p>एक विवरण यह है कि हम अक्सर इतिहास में \"हम वर्तमान में कहाँ हैं\" की एक धारणा चाहते हैं, ताकि जब हम एक नया snapshot लें, तो हम जानते हैं कि यह किसके सापेक्ष है (हम commit के <code>parents</code> field को कैसे सेट करते हैं)। Git में, वह \"हम वर्तमान में कहाँ हैं\" एक विशेष reference है जिसे \"HEAD\" कहा जाता है।</p>\n\n<h2>Repositories</h2>\n\n<p>अंत में, हम परिभाषित कर सकते हैं कि (मोटे तौर पर) एक Git <em>repository</em> क्या है: यह data <code>objects</code> और <code>references</code> है।</p>\n\n<p>Disk पर, सभी Git stores objects और references हैं: Git के data model में बस इतना ही है। सभी <code>git</code> commands objects को जोड़कर और references को जोड़कर/अपडेट करके commit DAG के कुछ manipulation से map होते हैं।</p>\n\n<p>जब भी आप किसी command में टाइप कर रहे हों, तो सोचें कि command अंतर्निहित graph data structure में क्या manipulation कर रहा है। इसके विपरीत, यदि आप commit DAG में किसी विशेष प्रकार का परिवर्तन करने की कोशिश कर रहे हैं, जैसे \"uncommitted changes को discard करें और 'master' ref को commit <code>5d83f9e</code> की ओर point करें\", तो शायद इसे करने के लिए एक command है (जैसे इस मामले में, <code>git checkout master; git reset --hard 5d83f9e</code>)।</p>\n\n<h1>Staging area</h1>\n\n<p>यह एक और अवधारणा है जो data model के लिए orthogonal है, लेकिन यह commits बनाने के लिए interface का एक हिस्सा है।</p>\n\n<p>एक तरीका जिससे आप ऊपर वर्णित snapshotting को implement करने की कल्पना कर सकते हैं, वह है एक \"create snapshot\" command होना जो working directory की <em>वर्तमान स्थिति</em> के आधार पर एक नया snapshot बनाता है। कुछ संस्करण नियंत्रण उपकरण इस तरह काम करते हैं, लेकिन Git नहीं। हम स्वच्छ snapshots चाहते हैं, और वर्तमान स्थिति से एक snapshot बनाना हमेशा आदर्श नहीं हो सकता है। उदाहरण के लिए, एक परिदृश्य की कल्पना करें जहाँ आपने दो अलग-अलग features को implement किया है, और आप दो अलग-अलग commits बनाना चाहते हैं, जहाँ पहला पहले feature को पेश करता है, और अगला दूसरे feature को पेश करता है। या एक परिदृश्य की कल्पना करें जहाँ आपके पास अपने पूरे code में debugging print statements जोड़े गए हैं, एक bugfix के साथ; आप सभी print statements को discard करते हुए bugfix को commit करना चाहते हैं।</p>\n\n<p>Git ऐसे परिदृश्यों को \"staging area\" नामक एक तंत्र के माध्यम से अगले snapshot में कौन से modifications शामिल किए जाने चाहिए यह निर्दिष्ट करने की अनुमति देकर समायोजित करता है।</p>\n\n<h1>Git command-line interface</h1>\n\n<p>जानकारी को दोहराने से बचने के लिए, हम नीचे दिए गए commands को विस्तार से समझाने नहीं जा रहे हैं। अधिक जानकारी के लिए अत्यधिक अनुशंसित <a href=\"https://git-scm.com/book/en/v2\">Pro Git</a> देखें।</p>\n\n<h2>Basics</h2>\n\n<p><code>git init</code> command एक नया Git repository initialize करता है, repository metadata <code>.git</code> directory में संग्रहीत किया जाता है:</p>\n\n<pre><code class=\"language-console\">$ mkdir myproject\n$ cd myproject\n$ git init\nInitialized empty Git repository in .git\n$ git status\nOn branch master\nNo commits yet\nnothing to commit (create/copy files and use \"git add\" to track)\n</code></pre>\n\n<p>हम इस output की व्याख्या कैसे करें? \"No commits yet\" मूल रूप से इसका मतलब है कि हमारा संस्करण इतिहास खाली है। चलिए इसे ठीक करते हैं।</p>\n\n<pre><code class=\"language-console\">$ echo \"hello, git\" &gt; hello.txt\n$ git add hello.txt\n$ git status\nOn branch master\nNo commits yet\nChanges to be committed:\n  (use \"git rm --cached &lt;file&gt;...\" to unstage)\n        new file:   hello.txt\n$ git commit -m 'Initial commit'\n[master (root-commit) 4515d17] Initial commit\n 1 file changed, 1 insertion(+)\n create mode 100644 hello.txt\n</code></pre>\n\n<p>इसके साथ, हमने staging area में एक फ़ाइल को <code>git add</code> किया है, और फिर उस परिवर्तन को <code>git commit</code> किया है, एक सरल commit message \"Initial commit\" जोड़ते हुए। यदि हमने <code>-m</code> option निर्दिष्ट नहीं किया होता, तो Git हमें एक commit message टाइप करने की अनुमति देने के लिए हमारे text editor को खोलता।</p>\n\n<p>अब जब हमारे पास एक non-empty संस्करण इतिहास है, तो हम इतिहास को visualize कर सकते हैं। इतिहास को एक DAG के रूप में visualize करना repo की वर्तमान स्थिति को समझने और इसे Git data model की आपकी समझ से जोड़ने में विशेष रूप से सहायक हो सकता है।</p>\n\n<p><code>git log</code> command इतिहास को visualize करता है। डिफ़ॉल्ट रूप से, यह एक flattened संस्करण दिखाता है, जो graph structure को छुपाता है। यदि आप <code>git log --all --graph --decorate</code> जैसे command का उपयोग करते हैं, तो यह आपको repository का पूर्ण संस्करण इतिहास दिखाएगा, graph form में visualized।</p>\n\n<pre><code class=\"language-console\">$ git log --all --graph --decorate\n* commit 4515d17a167bdef0a91ee7d50d75b12c9c2652aa (HEAD -&gt; master)\n  Author: Subramanya N &lt;subramanyanagabhushan@gmail.com&gt;\n  Date: Tue Dec 21 22:18:36 2020 -0500\n      Initial commit\n</code></pre>\n\n<p>यह इतना graph-like नहीं दिखता है, क्योंकि इसमें केवल एक single node है। चलिए कुछ और परिवर्तन करते हैं, एक नया commit author करते हैं, और इतिहास को एक बार फिर visualize करते हैं।</p>\n\n<pre><code class=\"language-console\">$ echo \"another line\" &gt;&gt; hello.txt\n$ git status\nOn branch master\nChanges not staged for commit:\n  (use \"git add &lt;file&gt;...\" to update what will be committed)\n  (use \"git checkout -- &lt;file&gt;...\" to discard changes in working directory)\n        modified:   hello.txt\nno changes added to commit (use \"git add\" and/or \"git commit -a\")\n$ git add hello.txt\n$ git status\nOn branch master\nChanges to be committed:\n  (use \"git reset HEAD &lt;file&gt;...\" to unstage)\n        modified:   hello.txt\n$ git commit -m 'Add a line'\n[master 35f60a8] Add a line\n 1 file changed, 1 insertion(+)\n</code></pre>\n\n<p>अब, यदि हम इतिहास को फिर से visualize करते हैं, तो हम graph structure का कुछ हिस्सा देखेंगे:</p>\n\n<pre><code>* commit 35f60a825be0106036dd2fbc7657598eb7b04c67 (HEAD -&gt; master)\n| Author: Subramanya N &lt;subramanyanagabhushan@gmail.com&gt;\n| Date:   Tue Dec 21 22:26:20 2020 -0500\n|     Add a line\n* commit 4515d17a167bdef0a91ee7d50d75b12c9c2652aa\n  Author: Subramanya N &lt;subramanyanagabhushan@gmail.com&gt;\n  Date: Tue Dec 21 22:18:36 2020 -0500\n      Initial commit\n</code></pre>\n\n<p>साथ ही, ध्यान दें कि यह वर्तमान HEAD को दिखाता है, वर्तमान branch (master) के साथ।</p>\n\n<p>हम <code>git checkout</code> command का उपयोग करके पुराने संस्करणों को देख सकते हैं।</p>\n\n<pre><code class=\"language-console\">$ git checkout 4515d17  # previous commit hash; आपका अलग होगा\nNote: checking out '4515d17'.\nYou are in 'detached HEAD' state. You can look around, make experimental\nchanges and commit them, and you can discard any commits you make in this\nstate without impacting any branches by performing another checkout.\nIf you want to create a new branch to retain commits you create, you may\ndo so (now or later) by using -b with the checkout command again. Example:\n  git checkout -b &lt;new-branch-name&gt;\nHEAD is now at 4515d17 Initial commit\n$ cat hello.txt\nhello, git\n$ git checkout master\nPrevious HEAD position was 4515d17 Initial commit\nSwitched to branch 'master'\n$ cat hello.txt\nhello, git\nanother line\n</code></pre>\n\n<p>Git आपको दिखा सकता है कि फ़ाइलें कैसे विकसित हुई हैं (differences, या diffs) <code>git diff</code> command का उपयोग करके:</p>\n\n<pre><code class=\"language-console\">$ git diff 4515d17 hello.txt\ndiff --git c/hello.txt w/hello.txt\nindex 94bab17..f0013b2 100644\n--- c/hello.txt\n+++ w/hello.txt\n@@ -1 +1,2 @@\n hello, git\n +another line\n</code></pre>\n\n<ul>\n<li><code>git help &lt;command&gt;</code>: एक git command के लिए help प्राप्त करें</li>\n<li><code>git init</code>: एक नया git repo बनाता है, data <code>.git</code> directory में संग्रहीत होता है</li>\n<li><code>git status</code>: आपको बताता है कि क्या हो रहा है</li>\n<li><code>git add &lt;filename&gt;</code>: staging area में फ़ाइलें जोड़ता है</li>\n<li><code>git commit</code>: एक नया commit बनाता है\n<ul>\n<li><a href=\"https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html\">अच्छे commit messages</a> लिखें!</li>\n<li><a href=\"https://chris.beams.io/posts/git-commit/\">अच्छे commit messages</a> लिखने के और भी कारण!</li>\n</ul></li>\n<li><code>git log</code>: इतिहास का एक flattened log दिखाता है</li>\n<li><code>git log --all --graph --decorate</code>: इतिहास को एक DAG के रूप में visualize करता है</li>\n<li><code>git diff &lt;filename&gt;</code>: staging area के सापेक्ष आपके द्वारा किए गए परिवर्तनों को दिखाता है</li>\n<li><code>git diff &lt;revision&gt; &lt;filename&gt;</code>: snapshots के बीच एक फ़ाइल में अंतर दिखाता है</li>\n<li><code>git checkout &lt;revision&gt;</code>: HEAD और current branch को अपडेट करता है</li>\n</ul>\n\n<h2>Branching और merging</h2>\n\n<p>Branching आपको संस्करण इतिहास को \"fork\" करने की अनुमति देता है। यह स्वतंत्र features या bug fixes पर समानांतर में काम करने के लिए सहायक हो सकता है। <code>git branch</code> command का उपयोग नई branches बनाने के लिए किया जा सकता है; <code>git checkout -b &lt;branch name&gt;</code> एक branch बनाता है और उसे check out करता है।</p>\n\n<p>Merging branching के विपरीत है: यह आपको forked संस्करण इतिहासों को संयोजित करने की अनुमति देता है, जैसे एक feature branch को master में वापस merge करना। <code>git merge</code> command का उपयोग merging के लिए किया जाता है।</p>\n\n<ul>\n<li><code>git branch</code>: branches दिखाता है</li>\n<li><code>git branch &lt;name&gt;</code>: एक branch बनाता है</li>\n<li><code>git checkout -b &lt;name&gt;</code>: एक branch बनाता है और उस पर switch करता है\n<ul>\n<li><code>git branch &lt;name&gt;; git checkout &lt;name&gt;</code> के समान</li>\n</ul></li>\n<li><code>git merge &lt;revision&gt;</code>: current branch में merge करता है</li>\n<li><code>git mergetool</code>: merge conflicts को हल करने में मदद करने के लिए एक fancy tool का उपयोग करें</li>\n<li><code>git rebase</code>: patches के सेट को एक नए base पर rebase करें</li>\n</ul>\n\n<h2>Remotes</h2>\n\n<ul>\n<li><code>git remote</code>: remotes की सूची बनाएं</li>\n<li><code>git remote add &lt;name&gt; &lt;url&gt;</code>: एक remote जोड़ें</li>\n<li><code>git push &lt;remote&gt; &lt;local branch&gt;:&lt;remote branch&gt;</code>: remote को objects भेजें, और remote reference को अपडेट करें</li>\n<li><code>git branch --set-upstream-to=&lt;remote&gt;/&lt;remote branch&gt;</code>: local और remote branch के बीच correspondence सेट करें</li>\n<li><code>git fetch</code>: एक remote से objects/references प्राप्त करें</li>\n<li><code>git pull</code>: <code>git fetch; git merge</code> के समान</li>\n<li><code>git clone</code>: remote से repository डाउनलोड करें</li>\n</ul>\n\n<h2>Undo</h2>\n\n<ul>\n<li><code>git commit --amend</code>: एक commit की सामग्री/संदेश को संपादित करें</li>\n<li><code>git reset HEAD &lt;file&gt;</code>: एक फ़ाइल को unstage करें</li>\n<li><code>git checkout -- &lt;file&gt;</code>: परिवर्तनों को discard करें</li>\n</ul>\n\n<h1>Advanced Git</h1>\n\n<ul>\n<li><code>git config</code>: Git <a href=\"https://git-scm.com/docs/git-config\">अत्यधिक customizable</a> है</li>\n<li><code>git clone --depth=1</code>: shallow clone, संपूर्ण संस्करण इतिहास के बिना</li>\n<li><code>git add -p</code>: interactive staging</li>\n<li><code>git rebase -i</code>: interactive rebasing</li>\n<li><code>git blame</code>: दिखाएं कि किस पंक्ति को अंतिम बार किसने संपादित किया</li>\n<li><code>git stash</code>: working directory में modifications को अस्थायी रूप से हटाएं</li>\n<li><code>git bisect</code>: इतिहास की binary search (जैसे regressions के लिए)</li>\n<li><code>.gitignore</code>: जानबूझकर untracked फ़ाइलों को ignore करने के लिए <a href=\"https://git-scm.com/docs/gitignore\">निर्दिष्ट</a> करें</li>\n</ul>\n\n<h1>Miscellaneous</h1>\n\n<ul>\n<li><strong>GUIs</strong>: Git के लिए कई <a href=\"https://git-scm.com/downloads/guis\">GUI clients</a> हैं। हम व्यक्तिगत रूप से उनका उपयोग नहीं करते हैं और इसके बजाय command-line interface का उपयोग करते हैं।</li>\n<li><strong>Shell integration</strong>: आपके shell prompt के हिस्से के रूप में Git status होना बहुत आसान है (<a href=\"https://github.com/olivierverdier/zsh-git-prompt\">zsh</a>, <a href=\"https://github.com/magicmonty/bash-git-prompt\">bash</a>)। अक्सर <a href=\"https://github.com/ohmyzsh/ohmyzsh\">Oh My Zsh</a> जैसे frameworks में शामिल होता है।</li>\n<li><strong>Editor integration</strong>: ऊपर के समान, कई features के साथ आसान integrations। <a href=\"https://github.com/tpope/vim-fugitive\">fugitive.vim</a> Vim के लिए मानक है।</li>\n<li><strong>Workflows</strong>: हमने आपको data model सिखाया, साथ ही कुछ बुनियादी commands; हमने आपको यह नहीं बताया कि बड़े projects पर काम करते समय किन practices का पालन करना चाहिए (और <a href=\"https://nvie.com/posts/a-successful-git-branching-model/\">कई</a> <a href=\"https://www.endoflineblog.com/gitflow-considered-harmful\">अलग-अलग</a> <a href=\"https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow\">दृष्टिकोण</a> हैं)।</li>\n<li><strong>GitHub</strong>: Git GitHub नहीं है। GitHub के पास अन्य projects में code योगदान करने का एक विशिष्ट तरीका है, जिसे <a href=\"https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests\">pull requests</a> कहा जाता है।</li>\n<li><strong>अन्य Git providers</strong>: GitHub विशेष नहीं है: कई Git repository hosts हैं, जैसे <a href=\"https://about.gitlab.com/\">GitLab</a> और <a href=\"https://bitbucket.org/\">BitBucket</a>।</li>\n</ul>\n\n<h1>Resources</h1>\n\n<ul>\n<li><a href=\"https://git-scm.com/book/en/v2\">Pro Git</a> <strong>अत्यधिक अनुशंसित पठन</strong> है। Chapters 1--5 से गुजरना आपको सिखाना चाहिए कि Git का कुशलतापूर्वक उपयोग करने के लिए आपको क्या चाहिए, अब जब आप data model को समझते हैं। बाद के chapters में कुछ दिलचस्प, advanced सामग्री है।</li>\n<li><a href=\"https://ohshitgit.com/\">Oh Shit, Git!?!</a> कुछ सामान्य Git गलतियों से recover करने के बारे में एक संक्षिप्त मार्गदर्शिका है।</li>\n<li><a href=\"https://eagain.net/articles/git-for-computer-scientists/\">Git for Computer Scientists</a> Git के data model की एक संक्षिप्त व्याख्या है, इन lecture notes की तुलना में कम pseudocode और अधिक fancy diagrams के साथ।</li>\n<li><a href=\"https://jwiegley.github.io/git-from-the-bottom-up/\">Git from the Bottom Up</a> सिर्फ data model से परे Git के implementation details की एक विस्तृत व्याख्या है, जिज्ञासुओं के लिए।</li>\n<li><a href=\"https://smusamashah.github.io/blog/2017/10/14/explain-git-in-simple-words\">How to explain git in simple words</a></li>\n<li><a href=\"https://learngitbranching.js.org/\">Learn Git Branching</a> एक browser-based game है जो आपको Git सिखाता है।</li>\n</ul>",
  "source_hash": "sha256:1882fed561269610d4ac35bc5a461efe73f8481070dd58a45db04a8899598a98",
  "model": "claude-sonnet-4-5-20250929",
  "generated_at": "2026-01-02T04:10:08.664246+00:00"
}