बेन जैक्सन के जवाब पर विस्तार करने के लिए , जो ठीक है, आइए मूल प्रश्न को करीब से देखें। ( प्रकार के प्रश्न क्यों परेशान करते हैं , इसके बारे में उनका उत्तर देखें ; यह जो चल रहा है उसके बारे में अधिक है ।)
मैं संस्करण नियंत्रण में नया हूं और मैं समझता हूं कि "कमिटिंग" जो आप काम कर रहे हैं उसके नए 'वर्तमान' संस्करण को अपडेट करते समय अनिवार्य रूप से एक बैकअप बना रहा है।
यह काफी सही नहीं है । बैकअप और संस्करण नियंत्रण निश्चित रूप से संबंधित हैं-बिल्कुल कुछ बातों पर दृढ़ता से निर्भर करता है जो कुछ हद तक राय के मामले हैं - लेकिन निश्चित रूप से कुछ अंतर हैं, यदि केवल इरादे में: बैकअप आमतौर पर आपदा वसूली के लिए डिज़ाइन किए जाते हैं (मशीन विफल हो जाती है, आग नष्ट हो जाती है सभी भंडारण मीडिया, आदि सहित पूरी इमारत)। संस्करण नियंत्रण आम तौर पर महीन-दाने वाली बातचीत के लिए डिज़ाइन किया गया है और ऐसे फीचर्स प्रदान करता है जो बैकअप नहीं करते हैं। बैकअप को आमतौर पर कुछ समय के लिए संग्रहीत किया जाता है, फिर "बहुत पुराना" के रूप में जोड़ा जाता है: एक फ्रेशर बैकअप यह सब मायने रखता है। संस्करण नियंत्रण सामान्य रूप से हर प्रतिबद्ध संस्करण को हमेशा के लिए बचाता है।
जो मुझे समझ में नहीं आता है वह व्यावहारिक दृष्टिकोण से है। क्या किसी चीज़ का मंचन केवल नाम में मौजूद है या यह एक उद्देश्य की पूर्ति करता है? जब आप प्रतिबद्ध होते हैं, तो यह सब कुछ वैसे भी करने के लिए जा रहा है, है ना?
हां और ना। यहाँ Git का डिज़ाइन कुछ अजीब है। वहाँ मौजूद संस्करण नियंत्रण प्रणाली है कि एक अलग मंचन की आवश्यकता नहीं है। उदाहरण के लिए, Mercurial, जो अन्यथा उपयोग के मामले में Git की तरह एक बहुत कुछ है, एक अलग कदम की आवश्यकता नहींhg add है, बहुत पहले वाले से परे जो एक नई फाइल पेश करता है। Mercurial के साथ, आप का उपयोग करते हैंhg कमांड का जो कुछ प्रतिबद्ध का चयन करता है, फिर आप अपना काम करते हैं, फिर आप दौड़ते हैं hg commit, और आप कर रहे हैं। गिट के साथ, आप का उपयोग करते हैं git checkout, 1 तो आप अपना काम करते हैं, फिर आप चलाते हैं git add, और फिर git commit। अतिरिक्त git addकदम क्यों ?
यहाँ राज़ है जो Git कॉल करता है, विभिन्न, सूचकांक या मंचन क्षेत्र , या कभी-कभी - शायद ही कभी इन दिनों- कैश । ये सभी एक ही चीज के नाम हैं।
संपादित करें: मुझे लगता है कि मैं शब्दावली को भ्रमित कर सकता हूं। क्या एक 'मंचित' फ़ाइल 'ट्रैक की गई' फ़ाइल के समान है?
नहीं, लेकिन ये संबंधित हैं। एक ट्रैक की गई फ़ाइल वह है जो Git के सूचकांक में मौजूद है। इंडेक्स को ठीक से समझने के लिए, कमिटिंग को समझने के साथ शुरुआत करना अच्छा है।
Git संस्करण 2.23 के बाद से, आप git switchइसके बजाय उपयोग कर सकते हैं git checkout। इस विशेष मामले के लिए, ये दोनों कमांड बिल्कुल एक ही काम करते हैं। नया आदेश मौजूद है क्योंकिgit checkout बहुत सारी चीजों के साथ अति-भरा हुआ है; वे दो अलग-अलग कमांडों में विभाजित हो गए, git switchऔर git restore, इसे आसान बनाने और Git का उपयोग करने के लिए सुरक्षित हो गए।
करता है
Git में, एक कमिट प्रत्येक का पूरा स्नैपशॉट बचाता है Git के बारे में जानने वाली फ़ाइल । (कौन सी फाइल के बारे में Git को पता है? हम अगले भाग में देखेंगे।) ये स्नैपशॉट एक विशेष, रीड-ओनली, Git-only, संपीड़ित और डी-डुप्लिकेट रूप में संग्रहीत किए जाते हैं, जो सामान्य रूप से केवल Git ही पढ़ सकते हैं । ( बस की तुलना में प्रत्येक प्रतिबद्ध में अधिक सामान है इस स्नैपशॉट की , लेकिन यह सब हम यहां कवर करेंगे।)
डी-डुप्लीकेशन अंतरिक्ष के साथ मदद करता है: हम आम तौर पर केवल कुछ फ़ाइलों को बदलते हैं, फिर एक नई प्रतिबद्धता बनाते हैं। तो सबसे एक में फ़ाइलों के लिए प्रतिबद्ध ज्यादातर पिछले में फ़ाइलों के लिए प्रतिबद्ध के रूप में ही कर रहे हैं। बस उन फ़ाइलों को सीधे उपयोग करके, Git बहुत सारी जगह बचाता है: यदि हमने केवल एक फ़ाइल को छुआ है, तो नई कमिट केवल एक नई प्रतिलिपि के लिए जगह लेती है। तब भी यह संकुचित होता है - कभी-कभी बहुत संकुचित होता है, हालांकि यह वास्तव में बाद में होता है- ताकि एक .gitनिर्देशिका वास्तव में उन फाइलों से छोटी हो सकती है, जो एक बार सामान्य रोजमर्रा की फ़ाइलों के लिए विस्तारित हो जाती हैं। डी-डुप्लीकेशन सुरक्षित है क्योंकि प्रतिबद्ध फाइलें हर समय जमी रहती हैं। कोई भी एक परिवर्तन नहीं कर सकता है, इसलिए यह सुरक्षित है कि यह एक-दूसरे की प्रतियों पर निर्भर हो।
क्योंकि संग्रहीत फ़ाइलें इस विशेष, जमे हुए-सभी-समय के लिए हैं, गिट-केवल प्रारूप, हालांकि, गिट को प्रत्येक फ़ाइल को एक साधारण रोजमर्रा की नकल में विस्तारित करना होगा । यह सामान्य प्रतिलिपि Git की प्रतिलिपि नहीं है: यह आपकी प्रतिलिपि है, जैसा कि आप करेंगे। जब आप इसे ऐसा करने के लिए कहेंगे, तो Git इन्हें लिखेगा, ताकि आपके पास काम करने के लिए आपकी प्रतियां हों। ये प्रयोग करने योग्य प्रतियां आपके काम करने वाले पेड़ या काम के पेड़ में हैं ।
इसका मतलब यह है कि जब आप कुछ विशेष प्रतिबद्ध की जांच करते हैं, तो प्रत्येक फ़ाइल की स्वचालित रूप से दो प्रतियां होती हैं :
Git के पास वर्तमान समय में जमे-के-लिए-सर्वकालिक, Git-ified प्रति है । आप इस प्रति को नहीं बदल सकते (हालाँकि आप निश्चित रूप से एक अलग प्रतिबद्ध का चयन कर सकते हैं, या एक नई प्रतिबद्धता बना सकते हैं)।
आपके पास, आपके कार्य-वृक्ष में, एक सामान्य-प्रारूप प्रति है। आप अपने कंप्यूटर पर किसी भी कमांड का उपयोग करके, इसके लिए कुछ भी कर सकते हैं।
अन्य संस्करण नियंत्रण प्रणाली (ऊपर उल्लिखित मर्कुरियल सहित) इन दो प्रतियों के साथ बंद हो जाती हैं। आप बस अपनी कार्य-वृक्ष की प्रति संशोधित करें, फिर प्रतिबद्ध करें। Git ... नहीं।
अनुक्रमणिका
इन दो प्रतियां के बीच में, Git एक संग्रहीत करता तीसरे प्रति 2 हर फ़ाइल की। यह तीसरी प्रतिलिपि जमे हुए प्रारूप में है , लेकिन प्रतिबद्ध में जमे हुए प्रतिलिपि के विपरीत, आप इसे बदल सकते हैं। इसे बदलने के लिए, आप उपयोग करते हैंgit add ।
git addआदेश साधन फ़ाइल के सूचकांक प्रतिलिपि काम पेड़ प्रति से मिलान करने के । यही है, आप Git को बता रहे हैं: जमे हुए प्रारूप, डी-डुप्लिकेटेड कॉपी को बदलें जो कि अभी सूचकांक में है, मेरी अपडेट की गई ट्री-कॉपी को डी-डुप्लिकेट करके, इसे डी-डुप्लिकेट करके, और इसे नए कमिट में फ्रीज होने के लिए तैयार कर लें। यदि आप उपयोग नहीं करते हैं git add, तो सूचकांक अभी भी वर्तमान प्रारूप से जमे हुए प्रारूप की प्रतिलिपि रखता है।
जब आप चलाने git commit, Git अप पैकेज जो कुछ भी सूचकांक में है सही और फिर नया स्नैपशॉट के रूप में उपयोग करने के लिए। चूंकि यह पहले से ही जमे हुए प्रारूप में है, और प्री-डी-डुप्लिकेट किया गया है, इसलिए गिट को बहुत अधिक अतिरिक्त काम नहीं करना पड़ता है।
यह भी बताता है कि सभी फ़ाइलों के बारे में क्या हैं। एक ट्रैक न किए गए फ़ाइल एक फ़ाइल अपने काम-वृक्ष में है, लेकिन वह यह है कि नहीं है Git के सूचकांक में अभी । इससे कोई फर्क नहीं पड़ता कि यह इस राज्य में फ़ाइल को कैसे घायल करता है। हो सकता है कि आपने इसे अपने कंप्यूटर पर किसी अन्य जगह से अपने कार्य-वृक्ष में कॉपी किया हो। हो सकता है कि आपने इसे यहां नया बनाया हो। हो सकता है कि वहाँ था Git के सूचकांक में एक प्रति है, लेकिन आप के साथ है कि प्रतिलिपि हटा दिया git rm --cached। एक तरह से या किसी अन्य, आपके कार्य-वृक्ष में यहां एक प्रति है, लेकिन गिट के सूचकांक में कोई प्रति नहीं है। यदि आप एक नई कमिट करते हैं, तो वह फाइल नए कमिट में नहीं होगी ।
ध्यान दें कि git checkoutशुरू में आपके द्वारा किए गए चेक से Git के सूचकांक में भर जाता है। इसलिए सूचकांक कमिटमेंट से मेल खाता है। Git भी इसी स्रोत से आपके कार्य-वृक्ष में भरता है। तो, शुरू में, सभी तीन मैच। जब आप अपने कार्य-वृक्ष में फ़ाइलों को बदलते हैं और git addउन्हें, ठीक है, अब सूचकांक और आपके कार्य-वृक्ष मेल खाते हैं। फिर तुम दौड़ोgit commit और Git इंडेक्स से एक नया कमिट करता है, और अब तीनों फिर से मैच करते हैं।
क्योंकि Git इंडेक्स से नए कमिट करता है, हम चीजों को इस तरह से रख सकते हैं: Git का इंडेक्स आपके पास अगली प्रतिबद्ध योजना बनाता है। यह उस विस्तारित भूमिका को अनदेखा करता है जिसे गिट के सूचकांक एक विवादित विलय के दौरान लेते हैं, लेकिन हम इसे अभी भी वैसे ही अनदेखा करना चाहेंगे। :-)
यह सब वहाँ है - लेकिन यह अभी भी बहुत जटिल है! यह विशेष रूप से मुश्किल है क्योंकि Git के सूचकांक में वास्तव में देखने का कोई आसान तरीका नहीं है। 3 लेकिन वहाँ है एक Git आदेश है कि आपको बताता है क्या एक तरह से बहुत उपयोगी है में, हो रहा है, और कहा कि आदेश है git status।
2 तकनीकी रूप से, यह वास्तव में एक प्रति नहीं है । इसके बजाय, यह Git-ified फ़ाइल, पूर्व-डी-डुप्लिकेट और सब कुछ का संदर्भ है। यहां सामान अधिक है, जैसे कि मोड, फ़ाइल का नाम, एक स्टेजिंग नंबर, और कुछ कैश डेटा जो Git को तेज बनाते हैं। लेकिन जब तक आप Git के कुछ निम्न-स्तरीय कमांडों के साथ काम नहीं कर लेते - git ls-files --stageऔर git update-indexविशेष रूप से- आप इसे कॉपी के रूप में सोच सकते हैं।
3git ls-files --stage आदेश आप नाम और Git के सूचकांक में हर फ़ाइल के मंचन की संख्या दिखाएगा, लेकिन आम तौर पर यह बहुत ही उपयोगी वैसे भी नहीं है।
git status
git statusआदेश वास्तव में दो अलग-अलग चलाकर काम करता है git diffआप के लिए आदेश (और भी इस तरह के कह रहा है जो शाखा पर आप हैं, के रूप में, कुछ अन्य उपयोगी सामान कर रही है)।
पहली git diffवर्तमान प्रतिबद्ध की तुलना करती है - जो, याद रखें, हर समय के लिए जमे हुए है - जो कुछ भी Git के सूचकांक में है। जो फाइलें समान हैं , उनके लिए Git कुछ भी नहीं कहेगा। अलग - अलग फ़ाइलों के लिए , Git आपको बताएगा कि यह फ़ाइल प्रतिबद्ध के लिए मंचित है । यह सभी नए फ़ाइलों-अगर प्रतिबद्ध नहीं है शामिल हैं sub.pyउस में है, लेकिन सूचकांक करता है sub.pyउस में, फिर इस फ़ाइल को जोड़ा गया है और किसी भी निकाली गई फ़ाइलें, कि थे (और कर रहे हैं) के लिए प्रतिबद्ध है, लेकिन में नहीं हैं सूचकांक किसी भी अधिक ( git rm, शायद)।
दूसरा git diffआपके वर्क-ट्री में Git के इंडेक्स की सभी फाइलों की फाइलों से तुलना करता है। जो फाइलें समान हैं , उनके लिए Git कुछ भी नहीं कहता है। अलग - अलग फ़ाइलों के लिए , Git आपको बताएगा कि यह फ़ाइल प्रतिबद्ध के लिए मंचित नहीं है । पहले अंतर के विपरीत, इस विशेष सूची में वे फाइलें शामिल नहीं हैं जो बिलकुल नई हैं: यदि फाइल untrackedआपके कार्य-वृक्ष में मौजूद है, लेकिन Git के सूचकांक में नहीं है, तो Git इसे केवल अनट्रैक की गई फ़ाइलों की सूची में शामिल करता है । 4
अंत में, एक सूची में इन अनटैक की गई फ़ाइलों को जमा करने से, उन फ़ाइलों के नामों की भी git statusघोषणा होगी , लेकिन एक विशेष अपवाद है: यदि किसी फ़ाइल का नाम किसी फ़ाइल में सूचीबद्ध है , जो इस अंतिम सूची को दबा देता है। ध्यान दें कि एक ट्रैक की गई फ़ाइल को सूचीबद्ध करना - जो कि Git के सूचकांक में है - का यहाँ कोई प्रभाव नहीं है : फ़ाइल सूचकांक में है, इसलिए इसकी तुलना की जाती है, और प्रतिबद्ध हो जाती है, भले ही यह सूचीबद्ध हो । अनदेखा फ़ाइल केवल "अनट्रैक फ़ाइल" शिकायतों को दबा देती है। 5.gitignore.gitignore.gitignore
4git status - लघु संस्करण का उपयोग करते समय git status -s- अनट्रैक की गई फाइलें अलग-अलग नहीं होती हैं, लेकिन सिद्धांत समान होता है। फाइलों को इस तरह git statusसंकलित करने से भी कभी-कभी निर्देशिका नाम, केवल मुद्रित करके अनटैक की गई फ़ाइलों के नामों के एक समूह को संक्षेप में प्रस्तुत करने की सुविधा मिलती है । पूरी सूची प्राप्त करने के लिए, का उपयोग करें git status -uallया git status -u।
5 एक फ़ाइल लिस्टिंग भी एन सामूहिक रूप से करता है कई फ़ाइल जोड़ने जैसे कार्य git add .या git add *ट्रैक न किए गए फ़ाइल पर छोड़ दें। यह हिस्सा थोड़ा और अधिक जटिल हो जाता है, क्योंकि आप git add --forceएक फ़ाइल को जोड़ने के लिए उपयोग कर सकते हैं जो सामान्य रूप से छोड़ दिया जाएगा। कुछ अन्य सामान्य-मामूली विशेष मामले हैं, जिनमें से सभी इसमें जोड़े जाते हैं: फ़ाइल .gitignoreको अधिक उचित .git-do-not-complain-about-these-untracked-files-and-do-not-auto-add-themरूप से कहा जा सकता है या कुछ समान रूप से अनिच्छुक हो सकता है । लेकिन यह बहुत हास्यास्पद है, इसलिए .gitignoreयह है।
git add -u, git commit -aआदि
यहाँ के बारे में जानने के लिए कई आसान शॉर्टकट हैं:
git add .वर्तमान निर्देशिका और किसी भी उप-निर्देशिका में सभी अद्यतन की गई फ़ाइलों को जोड़ देगा । यह सम्मान करता है .gitignore, इसलिए यदि वर्तमान में अनट्रैक की गई फ़ाइल के बारे में शिकायत नहीं की जाती है git status, तो यह स्वतः-जोड़ा नहीं जाएगा।
git add -uआपके कार्य-वृक्ष में कहीं भी सभी अद्यतित फ़ाइलों को स्वतः जोड़ देगा । 6 यह केवल प्रभावित करता है ट्रैक की गई फ़ाइलों को । ध्यान दें कि अगर आपने वर्क-ट्री कॉपी को हटा दिया है, तो यह इंडेक्स कॉपी को भी हटा देगा ( git addक्या यह इसके हिस्से के रूप में काम के पेड़ की चीज़ से मेल खाता है)।
git add -Agit add .आपके कार्य-वृक्ष के शीर्ष स्तर से चलने जैसा है (लेकिन फुटनोट 6 देखें)।
इनके अलावा, आप चला सकते हैं git commit -a, जो चलने और फिर लगभग 7 के बराबर है । यही है, यह आपको वही व्यवहार देता है जो मर्क्यूरियल में सुविधाजनक है।git add -ugit commit
मैं आम तौर पर के खिलाफ सलाह देता हूं git commit -a पैटर्न के हूं: मुझे लगता है कि यह git statusअक्सर उपयोग करने के लिए बेहतर है , आउटपुट पर बारीकी से देखें , और यदि स्थिति वह नहीं है जो आप की अपेक्षा करते हैं, तो समझें कि ऐसा क्यों है। का उपयोग करना git commit -a, गलती से किसी फ़ाइल को संशोधित करना और एक बदलाव करना आसान है जिसे आपने करने का इरादा नहीं किया है। लेकिन यह ज्यादातर स्वाद / राय का मामला है।
6 यदि आपका Git संस्करण Git 2.0 से पहले आता है, तो यहां सावधान रहें: git add -uकेवल वर्तमान निर्देशिका और उप-निर्देशिकाओं पर काम करता है, इसलिए आपको अपने कार्य-वृक्ष के शीर्ष स्तर पर चढ़ना होगा। git add -Aविकल्प ने वही समस्या है।
7 मैं कहता हूँ कि मोटे तौर पर समतुल्य है क्योंकि git commit -aवास्तव में एक अतिरिक्त सूचकांक बनाकर काम करता है, और प्रतिबद्ध करने के लिए उस अन्य सूचकांक का उपयोग करता है। यदि कमिट काम करता है , तो आपको करने के समान प्रभाव मिलता हैgit add -u && git commit । यदि कमिट काम नहीं करता है - यदि आप Git बनाते हैं तो कमिटमेंट को कई तरीकों से कर सकते हैं जो आप कर सकते हैं - फिर कोई भी फाइल git add-ed बाद में नहीं होती है, क्योंकि Git अस्थायी अतिरिक्त इंडेक्स को फेंक देता है और मुख्य इंडेक्स का उपयोग करने के लिए वापस चला जाता है ।
यदि आप git commit --onlyयहां उपयोग करते हैं तो अतिरिक्त जटिलताएं हैं। इस मामले में, Git एक तीसरा सूचकांक बनाता है , और चीजें बहुत मुश्किल हो जाती हैं, खासकर यदि आप पूर्व-प्रतिबद्ध हुक का उपयोग करते हैं। अलग git addसंचालन का उपयोग करने का यह एक और कारण है ।