2010-03-29 11 views
41

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

शायद एक या कोई भी --hard विकल्प को मूल checkout करने के विकल्प को जोड़ने में परेशान होगा।

शायद इतिहास में आप किस तरह से अंतर देखेंगे?

+1

मैं अपने पिछले प्रश्नों में से एक करने के लिए अपने जवाब के लिए एक अद्यतन में इस कवर - विशेष रूप से जहां शीर्ष के निकट ascii कला को देखो, यह कहता है "Digression: ..." (जितना मैं इसे फिर से जवाब देने के लिए और अधिक प्रतिनिधि प्यार करता हूँ) – Cascabel

+0

मुझे लगता है कि आप यहां अपना उत्तर पोस्ट कर सकते हैं और इससे प्रतिनिधि प्राप्त कर सकते हैं। अगर कोई इस विशेष ज्ञान की खोज करता है, तो उसे दूसरी पोस्ट नहीं मिलेगी। यह एक बहुत ही विशिष्ट विषय का लक्ष्य रखता है, और यह इसके अलग पृष्ठ के लायक है। बीटीडब्ल्यू, ऐसा लगता है कि आप मेरे गिट सलाहकार हैं :-) हरिगाटो, सेंन्सी! –

+1

लेकिन क्या मुझे यह मिल रहा है, अंतर यह है कि रीसेट शाखा को स्थानांतरित करता है और चेकआउट नहीं करता है। –

उत्तर

52

यह उत्तर ज्यादातर मेरे पिछले प्रश्न के उत्तर से उद्धृत किया गया है: git reset in plain english

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

मान लीजिए आपका इतिहास, इस तरह दिखता है अभी चेक आउट मास्टर शाखा के साथ:

- A - B - C (HEAD, master) 

और आप git reset --hard B चलाते हैं। आप इस मिल जाएगा:

- A - B (HEAD, master)  # - C is still here, but there's no 
          # branch pointing to it anymore 

आप वास्तव में है कि प्रभाव प्राप्त होता है, तो आप --mixed या --soft भी उपयोग - फर्क सिर्फ इतना है कि क्या अपने काम के पेड़ और सूचकांक करने के लिए होता है। --hard मामले में, कार्य पेड़ और अनुक्रमणिका मिलान B

अब, मान लीजिए कि आप इसके बजाय git checkout B चलाएंगे। आपको यह मिल जाएगा:

- A - B (HEAD) - C (master) 

आप एक अलग सिर स्थिति में समाप्त हो गए हैं। HEAD, कार्य पेड़, सूचकांक सभी मैच B, हार्ड रीसेट के साथ ही, लेकिन मास्टर शाखा C पर पीछे छोड़ दी गई थी। आप एक नया इस बिंदु पर D प्रतिबद्ध बनाने, तो आप इस मिल जाएगा, जो शायद नहीं है कि आप क्या चाहते:

- A - B - C (master) 
     \ 
     D (HEAD) 

तो, आप चेकआउट उपयोग करने के लिए, ठीक है, कि प्रतिबद्ध की जाँच करें। आप इसके साथ परेशान हो सकते हैं, जो भी आपको पसंद है, लेकिन आपने अपनी शाखा को पीछे छोड़ दिया है। यदि आप चाहते हैं कि शाखा भी चली गई हो, तो आप रीसेट का उपयोग करें।

+5

+1 भी देखें। यह धागा (http://marc.info/?l=git&m=120955970704567&w=2) ने एक साइड-इफेक्ट भी जोड़ा: यदि आप विलय के बीच में हैं (उदाहरण के लिए जब मर्ज विवाद होते हैं, या 'गिट विलय के बाद - -नो-प्रतिबद्ध'), 'गिट रीसेट - हार्ड' विलय भूल जाता है, लेकिन 'गिट चेकआउट -एफ' नहीं करता है; इसलिए, उत्तरार्द्ध के बाद एक 'गिट प्रतिबद्ध' एक विलय प्रतिबद्धता उत्पन्न करेगा, जो आम तौर पर आप जो चाहते हैं वह नहीं है। – VonC

+0

@ वॉनसी: और सामान्य रूप से आपके द्वारा एक उत्कृष्ट अतिरिक्त बिंदु! – Cascabel

14

यदि गिट के साथ प्रदान किया गया दस्तावेज आपकी मदद नहीं करता है, तो मार्क लोडाटो द्वारा A Visual Git Reference पर एक नज़र डालें।

विशेष रूप से यदि आप git reset --hard <non-branch> साथ git checkout <non-branch> तुलना कर रहे हैं (hotlinked):

git checkout master~3 http://marklodato.github.com/visual-git-guide/checkout-detached.svg.png

git reset --hard master~3 http://marklodato.github.com/visual-git-guide/reset-commit.svg.png

ध्यान दें कि git reset --hard master~3 के मामले आप संशोधन की DAG का एक हिस्सा पीछे छोड़ में - में से कुछ किसी भी शाखा द्वारा संदर्भित नहीं किया जाता है। वे द्वारा 30 दिनों के लिए (डिफ़ॉल्ट रूप से) सुरक्षित हैं; वे अंततः छीन लिया जाएगा (हटाया गया)।

6

git-reset hash दिए गए हैश के लिए शाखा संदर्भ सेट करता है, और वैकल्पिक रूप से इसेके साथ चेक आउट करता है।

git-checkout hash दिए गए हैश में काम करने वाले पेड़ को सेट करता है; और जब तक हैश शाखा का नाम नहीं है, तो आप एक अलग सिर के साथ समाप्त हो जाएंगे।

अंततः, 3 चीजों के साथ Git सौदों:

    working tree (your code) 
------------------------------------------------------------------------- 
        index/staging-area 
------------------------------------------------------------------------- 
     repository (bunch of commits, trees, branch names, etc) 

git-checkout डिफ़ॉल्ट रूप से केवल सूचकांक और काम कर पेड़ अद्यतन करता है, और वैकल्पिक रूप भंडार में कुछ (-b विकल्प के साथ) को अपडेट कर सकते

git-reset डिफ़ॉल्ट रूप से केवल भंडार और सूचकांक अद्यतन करता है, और वैकल्पिक रूप से कार्यरत पेड़ (--hard विकल्प के साथ)

आप भंडार के बारे में सोच सकते हैं इस तरह:

HEAD -> master 

refs: 
    master -> sha_of_commit_X 
    dev -> sha_of_commit_Y 

objects: (addressed by sha1) 

    sha_of_commit_X, sha_of_commit_Y, sha_of_commit_Z, sha_of_commit_A .... 

git-reset क्या शाखा संदर्भ को इंगित manipulates।

अपने इतिहास इस तरह दिखता है मान लीजिए:

  T--S--R--Q [master][dev] 
     /
    A--B--C--D--E--F--G [topic1] 
        \ 
        Z--Y--X--W [topic2][topic3] 

ध्यान रखें कि शाखाओं बस ऐसे नाम हैं जो अग्रिम स्वचालित रूप से आप जब प्रतिबद्ध हैं।

तो आप निम्नलिखित शाखाएं हैं:

master -> Q 
dev -> Q 
topic1 -> G 
topic2 -> W 
topic3 -> W 

और अपने वर्तमान शाखा topic2 सिर अंक topic2 है, कि है,।

HEAD -> topic2 

फिर, git reset X एक्स को इंगित करने के नाम topic2 रीसेट कर देगा; यदि आप एक शाखा topic2 पर पी प्रतिबद्ध बनाने के लिए, चीजों को इस तरह दिखेगा, जिसका अर्थ है:

  T--S--R--Q [master][dev] 
     /
    A--B--C--D--E--F--G [topic1] 
        \ 
        Z--Y--X--W [topic3] 
          \ 
          P [topic2] 
संबंधित मुद्दे