"गिट रीसेट" और "गिट चेकआउट" में क्या अंतर है?


440

मैं हमेशा के बारे में सोचा गया है git resetऔर git checkoutइस अर्थ में कि दोनों में एक विशिष्ट प्रतिबद्ध करने के लिए परियोजना को वापस लाने में, एक ही रूप में। हालांकि, मुझे लगता है कि वे बिल्कुल वैसा नहीं हो सकते, जैसा कि बेमानी होगा। दोनों के बीच वास्तविक अंतर क्या है? मैं थोड़ा भ्रमित हूँ, क्योंकि svn को केवल svn coकमिट करना है।

जोड़ा

वॉन और चार्ल्स ने बीच git resetऔर git checkoutवास्तव में अच्छी तरह से अंतर समझाया । मेरी वर्तमान समझ यह है कि git resetसभी परिवर्तनों को एक विशिष्ट प्रतिबद्धता पर वापस लौटा दिया जाता है, जबकि git checkoutएक शाखा के लिए अधिक या कम तैयारी की जाती है। मुझे इस समझ में आने में निम्नलिखित दो चित्र काफी उपयोगी लगे:

http://a.imageshack.us/img651/1559/86421927.png http://a.imageshack.us/img801/1986/resetr.png

जोड़ा गया 3

से http://think-like-a-git.net/sections/rebase-from-the-ground-up/using-git-cherry-pick-to-simulate-git-rebase.html , चेकआउट और रीसेट कर सकते हैं अनुकरण रिबेस।

यहां छवि विवरण दर्ज करें

git checkout bar 
git reset --hard newbar 
git branch -d newbar 

यहां छवि विवरण दर्ज करें



पुन: "क्या यह गलत है या अति सरलीकृत है?" हां, वह पहला आरेख चेकआउट और रीसेट के बीच अंतर के बारे में भ्रामक है। (यह -- filesवेरिएंट के संबंध में ठीक हो सकता है ; मुझे यकीन नहीं है।) यह आरेख बनाता है यह मुख्य अंतर की तरह दिखता है कि क्या वे सूचकांक या डब्ल्यूडी को प्रभावित करते हैं। उससे संबंधित मेरा उत्तर देखें। दूसरा और तीसरा आरेख वास्तविक अंतर को देखने के लिए बहुत सहायक हैं। 4 वें और 5 वें आरेख यह जांचने के लिए उपयोगी हैं कि क्या आप समझते हैं कि ये कमांड क्या करते हैं, लेकिन वास्तव में आपको वहां पहुंचने में मदद नहीं करेंगे।
लार्स डे

मुझे सबसे सहायक सारांश देने के लिए "Git Tools Reset Demystified" का अनुभाग "इसे देखें" मिला ।
योशिय्याह योडर

1
prosseek: यदि आप @LarsH से सहमत हैं कि पहला आरेख भ्रामक है, तो क्या आप इसे हटा सकते हैं, कृपया?
जोशिया योदर

कृपया ध्यान दें कि चेकआउट और रीसेट केवल रिबास के दूसरे भाग का अनुकरण करते हैं, और think-like-a-git.netडेटा के नुकसान को रोकने के लिए अतिरिक्त चरण (लिंक किए गए लेख में प्रदान किए गए ) की आवश्यकता होती है।
काउलिनेटर

जवाबों:


198
  • git resetविशेष रूप से सूचकांक को अद्यतन करने के बारे में है , हेड को आगे बढ़ाता है।
  • git checkoutकाम कर रहे पेड़ (सूचकांक या निर्दिष्ट पेड़ के लिए) को अपडेट करने के बारे में है । यह केवल हेड को अपडेट करेगा यदि आप एक शाखा की जांच करते हैं (यदि नहीं, तो आप एक अलग हेड के साथ समाप्त होते हैं )।
    (वास्तव में, Git 2.23 Q3 2019 के साथ, यह git restoreजरूरी नहीं होगा git checkout)

तुलना करके, चूंकि svn का कोई सूचकांक नहीं है, केवल एक काम करने वाला पेड़ है, svn checkoutएक अलग निर्देशिका पर दिए गए संशोधन की नकल करेगा।
इसके लिए समतुल्य बराबर git checkoutहोगा:

  • svn update (यदि आप एक ही शाखा में हैं, तो एक ही SVN URL का अर्थ है)
  • svn switch (यदि आप एक ही शाखा उदाहरण के लिए चेकआउट करते हैं, लेकिन दूसरे SVN रेपो URL से)

सभी उन तीन कार्य पेड़ संशोधनों ( svn checkout, update, switch) Git में केवल एक ही आदेश है: git checkout
लेकिन चूँकि git में भी रेपो और वर्किंग ट्री के बीच इंडेक्स की धारणा है (जो "स्टेजिंग एरिया" है), आपके पास भी है git reset


थिअटी ने टिप्पणियों में " रीसेट डिमिस्टीफाइड " लेख का उल्लेख किया है

उदाहरण के लिए, यदि हमारी दो शाखाएँ हैं, ' master' और ' develop' अलग-अलग कमानों की ओर इशारा करते हैं, और हम वर्तमान में ' develop' पर हैं (इसलिए HEAD इसे इंगित करता है) और हम चलाते हैं git reset master, ' develop' अब वह उसी प्रतिबद्धता की ओर संकेत करेगा '' master' कर देता है।

दूसरी ओर, अगर हम इसके बजाय भागते हैं git checkout master, तो ' develop' नहीं चलेगा, HEADखुद जाएगा। HEADअब ' master' को इंगित करेगा ।

इसलिए, दोनों मामलों में हम HEADकमिट करने के लिए आगे बढ़ रहे हैं A, लेकिन हम ऐसा कैसे करते हैं यह बहुत अलग है। resetशाखा के HEADबिंदुओं की ओर बढ़ेगा , चेकआउट HEADदूसरी शाखा की ओर इशारा करता है।

http://git-scm.com/images/reset/reset-checkout.png

उन बिंदुओं पर, हालांकि:

टिप्पणी में लार्स कहते हैं :

इस उत्तर का पहला पैराग्राफ, हालांकि, भ्रामक है: " git checkout... HEAD को केवल तभी अपडेट करेगा जब आप एक शाखा की जांच करते हैं (यदि नहीं, तो आप एक अलग हेड के साथ समाप्त होते हैं)"।
सच नहीं है: git checkoutHEAD को अपडेट करेगा भले ही आप एक कमिट की जांच करें जो एक शाखा नहीं है (और हां, आप एक अलग हेड के साथ समाप्त होते हैं, लेकिन यह अभी भी अपडेट हो गया है)।

git checkout a839e8f updates HEAD to point to commit a839e8f.

डी नोवो कॉन्सर्ट इन कमेंट्स :

@ लार्स सही है।
दूसरी बुलेट में इस बारे में गलत धारणा है कि HEAD क्या है, HEAD को तभी अपडेट करेगा जब आप ब्रांच चेकआउट करेंगे।
आप जहां भी हों, हेड एक छाया की तरह जाता है।
कुछ गैर-शाखा रेफरी (उदाहरण के लिए, एक टैग), या सीधे एक कमिट की जाँच करना, HEAD को स्थानांतरित करेगा। अलग किए गए सिर का मतलब यह नहीं है कि आप हेड से अलग हो गए हैं, इसका मतलब है कि हेड को एक शाखा रेफ से अलग किया गया है, जिसे आप उदाहरण के लिए देख सकते हैं git log --pretty=format:"%d" -1

  • संलग्न प्रमुख राज्यों के साथ शुरू होगा (HEAD ->,
  • अलग हो जाएगा फिर भी दिखाएगा (HEAD, लेकिन एक शाखा रेफरी के लिए एक तीर नहीं होगा।

7
मैं कहूंगा कि git resetशाखा "लेबल" को संशोधित करने और वैकल्पिक रूप से एक प्रभाव के रूप में सूचकांक या कार्यशील पेड़ को अद्यतन करने के बारे में है। git checkoutकाम कर रहे पेड़ को अद्यतन करने और वर्तमान में "चयनित" शाखा ( HEAD) को बदलने के बारे में है ।
मिकको रेंटालिनेन

2
@ मायको रेंटालैनेन नोप। git resetके बारे में 100% है HEAD। यह एक अलग HEAD मोड ( stackoverflow.com/a/3965714/6309 ) में भी काम करता है , जिसका अर्थ है कि जहाँ कोई शाखा नहीं है !)। git चेकआउट एक अलग HEAD मोड में भी काम करता है, या एक SHA1 को एक अलग HEAD मोड में चेकआउट करने के लिए इस्तेमाल किया जा सकता है: फिर से उस मामले में कोई शाखा शामिल नहीं है।
वॉनसी

3
खोज इंजन द्वारा यहां भेजे गए सभी खोए हुए आत्माओं के लिए आगे पढ़ने, मुझे लगता है कि यह इसके लायक है: git-scm.com/blog/2011/07/11/reset.html
Thinkeye

2
@Thinkeye अच्छा संदर्भ। अधिक दृश्यता के उत्तर में मैंने एक प्रासंगिक अर्क के साथ इसे शामिल किया है।
VonC

2
रीसेट डेमिस्टिफ़ाइड से स्पष्टीकरण उत्कृष्ट है। इस उत्तर का पहला पैराग्राफ, हालांकि, भ्रामक है: "git checkout ... HEAD को केवल तभी अपडेट करेगा जब आप एक ब्रांच चेकआउट करेंगे (यदि नहीं, तो आप अलग किए गए HEAD के साथ समाप्त होते हैं)"। सच नहीं है ... git चेकआउट HEAD को अपडेट करेगा भले ही आप एक ऐसा चेकआउट करें जो एक शाखा नहीं है (और हाँ, आप एक अलग हेड के साथ समाप्त होते हैं, लेकिन यह अभी भी अपडेट हो गया है)। शायद मैं गलत समझ रहा हूं कि "अपडेट" से आपका क्या मतलब है? git checkout a839e8fHEAD को इंगित करने के लिए अद्यतन करता है a839e8f
लार्स

67

अपने सरलतम रूप में, resetकार्यशील पेड़ को छूने के बिना सूचकांक को रीसेट करता है, जबकि काम के पेड़ को सूचकांक को छूने के बिना checkoutबदलता है।

मिलान करने के लिए अनुक्रमणिका रीसेट करता है HEAD, काम कर रहे पेड़ को अकेला छोड़ दिया गया है:

git reset

वैचारिक रूप से, यह कार्यशील पेड़ में सूचकांक की जाँच करता है। वास्तव में ऐसा करने के लिए आपको -fकिसी भी स्थानीय परिवर्तन को अधिलेखित करने के लिए इसे मजबूर करने के लिए उपयोग करना होगा । यह सुनिश्चित करने के लिए एक सुरक्षा सुविधा है कि "कोई तर्क नहीं" फ़ॉर्म विनाशकारी नहीं है:

git checkout

एक बार जब आप पैरामीटर जोड़ना शुरू करते हैं तो यह सच है कि कुछ ओवरलैप है।

checkoutआमतौर पर एक शाखा, टैग या प्रतिबद्ध के साथ प्रयोग किया जाता है। इस स्थिति में यह रीसेट हो जाएगा HEADऔर इंडेक्स दिए गए कमिट के साथ-साथ इंडेक्स के चेकआउट को कार्यशील ट्री में प्रदर्शन करेगा।

इसके अलावा, अगर आप की आपूर्ति --hardकरने के लिए resetआप पूछ सकते हैं resetकाम कर पेड़ अधिलेखित करने के साथ-साथ सूचकांक को रीसेट।

यदि आपके पास करंट है तो एक ब्रांच चेक आउट करें resetऔर checkoutजब आप वैकल्पिक ब्रांच या कमिटमेंट सप्लाई करते हैं तो बीच में एक महत्वपूर्ण अंतर होता है । resetचयनित शाखा को इंगित करने के लिए वर्तमान शाखा को बदल देगा, जबकि checkoutवर्तमान शाखा को अकेला छोड़ देगा, लेकिन आपूर्ति की गई शाखा की जांच करेगा या इसके बजाय प्रतिबद्ध होगा।

अन्य प्रकार के resetऔर commitपथों की आपूर्ति करना शामिल है।

यदि आप पथों की आपूर्ति करते हैं तो आप आपूर्ति resetनहीं कर सकते हैं --hardऔर resetकेवल आपूर्ति किए गए पथों के अनुक्रमणिका संस्करण को आपूर्ति किए गए कमिट में संस्करण में बदल देंगे (या HEADयदि आप कोई वचन निर्दिष्ट नहीं करते हैं)।

यदि आप रास्तों की आपूर्ति करते हैं checkout, जैसे कि resetयह आपूर्ति किए गए प्रतिबद्ध (या HEAD) से मेल खाने के लिए आपूर्ति किए गए रास्तों के सूचकांक संस्करण को अपडेट करेगा , लेकिन यह हमेशा कार्यशील पेड़ में आपूर्ति किए गए पथों के सूचकांक संस्करण की जांच करेगा।


2
यह कहना असत्य है कि "चेकआउट" सूचकांक को नहीं बदलता है: इसे तब बदलता है जब एक शाखा से दूसरी में जाते थे।
विकी १००

उनके सरलतम रूप में, रीसेट कार्यशील पेड़ को छूने के बिना सूचकांक को रीसेट करता है, जबकि चेकआउट सूचकांक को छूने के बिना काम करने वाले पेड़ को बदलता है। : कितना भ्रामक है: |
आदित्य गुप्ता

41

परिवर्तन को वापस करते समय एक साधारण उपयोग मामला:
1. यदि आप संशोधित फ़ाइल के मंचन को पूर्ववत करना चाहते हैं, तो रीसेट का उपयोग करें।
2. चेकआउट का उपयोग करें यदि आप अस्थिर फाइल / एस में परिवर्तन को छोड़ना चाहते हैं।


1
एकदम सही जवाब। धन्यवाद।
user358591

11

संक्षेप में मुख्य अंतर यह है कि reset वर्तमान शाखा संदर्भ कोcheckout स्थानांतरित करता है , जबकि यह (हेड नहीं चलता है)।

जैसा कि प्रो Git किताब में बताया गया है कि रीसेट डिमिस्टिफाई ,

पहली बात resetयह है कि HEAD किस ओर इशारा करता है । यह स्वयं हेड को बदलने के समान नहीं है (जो ऐसा checkoutकरता है); reset उस शाखा को स्थानांतरित करता है जिसे HEAD इंगित कर रहा है। इसका मतलब है कि यदि हेड को masterशाखा में सेट किया गया है (यानी आप वर्तमान में masterशाखा पर हैं), तो रनिंग पॉइंट से git reset 9e5e6a4शुरू होगा । [महत्व दिया]master9e5e6a4

एक बहुत ही उपयोगी पाठ और एक ही लेख से आरेख के लिए VonC का उत्तर भी देखें , जिसे मैं यहां नकल नहीं करूंगा।

बेशक क्या प्रभाव के बारे में बहुत अधिक जानकारी के देखते हैं checkoutऔर resetसूचकांक और काम कर पेड़ पर हो सकता है, क्या मापदंडों उपयोग किया जाता है पर निर्भर करता है। दोनों आज्ञाओं के बीच बहुत सारी समानताएं और अंतर हो सकते हैं। लेकिन जैसा कि मैंने इसे देखा है, सबसे महत्वपूर्ण अंतर यह है कि क्या वे वर्तमान शाखा के सिरे को हिलाते हैं।


2
मेरे पुराने उत्तर के अलावा, अच्छी प्रतिक्रिया। +1
वॉन

2

दो कमांड (रीसेट और चेकआउट) पूरी तरह से अलग हैं।

checkout X नहीं है reset --hard X

यदि X एक शाखा का नाम है, checkout Xतो वर्तमान शाखा को बदल reset --hard Xदेगा जबकि ऐसा नहीं करेगा।


2
लेकिन अगर X एक फ़ाइल या फ़ोल्डर है, तो वे समान हैं।
टेड बीघम

1

संक्षिप्त ज्ञान:

git reset HEAD           :             index = HEAD
git checkout             : file_tree = index
git reset --hard HEAD    : file_tree = index = HEAD
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.