Git में फ़ाइल को अनस्टेज करने के दो तरीके क्यों हैं?


1166

कभी-कभी git rm --cachedगिट एक फाइल को अनस्टेज करने का सुझाव देता है, कभी-कभी git reset HEAD file। मुझे कब उपयोग करना चाहिए?

संपादित करें:

D:\code\gt2>git init
Initialized empty Git repository in D:/code/gt2/.git/
D:\code\gt2>touch a

D:\code\gt2>git status
# On branch master
#
# Initial commit
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       a
nothing added to commit but untracked files present (use "git add" to track)

D:\code\gt2>git add a

D:\code\gt2>git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#       new file:   a
#
D:\code\gt2>git commit -m a
[master (root-commit) c271e05] a
 0 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 a

D:\code\gt2>touch b

D:\code\gt2>git status
# On branch master
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       b
nothing added to commit but untracked files present (use "git add" to track)

D:\code\gt2>git add b

D:\code\gt2>git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       new file:   b
#

20
क्यों? मैं कहूंगा कि क्योंकि git का कमांडलाइन इंटरफ़ेस व्यवस्थित रूप से विकसित हुआ है और चीजों को सुसंगत बनाने के लिए कभी भी बड़े पुनर्गठन के अधीन नहीं रहा है। (यदि आप असहमत हैं, टिप्पणी कैसे git rmदोनों कर सकते हैं चरण एक विलोपन और भी unstage एक अतिरिक्त )
रोमन Starkov

3
@romkyns: मैं मानता हूं कि Git के इंटरफ़ेस में कई विषमताएँ हैं क्योंकि यह व्यवस्थित रूप से विकसित हुआ है, लेकिन एक निष्कासन निश्चित रूप से एक जोड़ का उलटा कार्य है, इसलिए इसे rmपूर्ववत करना तर्कसंगत नहीं है add? आपको क्या लगता है कि आपको कैसा rmव्यवहार करना चाहिए?
ज़ाज

6
अपने प्रश्न का केवल वास्तविक जवाब है कि सही होने के बाद एक है git initकोई HEADको पुनर्स्थापित करने के लिए।
माइल्स राउत

इसके लिए सर्वश्रेष्ठ डॉक्स: help.github.com/articles/changing-a-remote-s-url
ScottyBlades

4
@Zaz, मैं अपनी राय दूंगा। rmएक यूनिक्स संदर्भ में विलोपन का मतलब है। यह सूचकांक में जोड़ने के विपरीत नहीं है। स्टेजिंग-स्टेट को बदलने के लिए फ़ंक्शन को हटाने के लिए फ़ंक्शन को कार्यों के साथ अतिभारित नहीं किया जाना चाहिए। यदि कार्यान्वयन विवरण हैं जो संयोजन करने के लिए सुविधाजनक बनाते हैं, तो यह आसानी से गिट में अमूर्तता की एक विचारशील परत की कमी को इंगित करता है, जो प्रयोज्य को स्पष्ट करेगा।
जोशुआ गोल्डबर्ग

जवाबों:


1891

git rm --cached <filePath> एक फ़ाइल को अनस्टेज नहीं करता है , यह वास्तव में रेपो से फ़ाइल (एस) को हटाने को चरणबद्ध करता है (यह मानते हुए कि यह पहले से ही प्रतिबद्ध था) लेकिन फ़ाइल को आपके काम करने वाले पेड़ में छोड़ देता है (आपको एक अनट्रैक फ़ाइल के साथ छोड़कर)।

git reset -- <filePath>दी गई फ़ाइल के लिए किसी भी चरणबद्ध परिवर्तन को रोक देगा ।

उस ने कहा, यदि आप git rm --cachedएक नई फ़ाइल पर उपयोग किया जाता है, जिसका मंचन किया जाता है, तो यह मूल रूप से ऐसा लगेगा जैसे आपने इसे पहले ही अप्रतिबंधित कर दिया था क्योंकि यह पहले कभी प्रतिबद्ध नहीं था।

2.24 के अपडेट के लिए
इस नए संस्करण में git के git restore --stagedबजाय आप का उपयोग कर सकते हैं git reset। देखें गिट डॉक्स


70
मैं कहूंगा कि git rm --cachedफ़ाइल को unstages करें लेकिन इसे कार्यशील निर्देशिका से नहीं हटाएं।
पियरे डे LESPINAY

4
जोड़ के लिए मंचित फ़ाइल को हटाने के लिए ताकि उसका मंचन नहीं किया जा सके, निश्चित रूप से "इसके लिए मंचित फ़ाइल को अस्थिर करना" कहा जा सकता है, है ना? अंतिम परिणाम एक मंचन विलोपन नहीं है , यह सुनिश्चित करने के लिए है, इसलिए मुझे लगता है कि गलतफहमी पूरी तरह से समझ में आती है।
रोमन स्टार्कोव

4
इसलिए आम तौर पर, किसी को git rm --cached <filePath>रेपो से कुछ फ़ाइल (रों) को हटाने के लिए उपयोग करना होगा, यह महसूस करने के बाद कि उसे रेपो में कभी नहीं होना चाहिए: इसलिए सबसे अधिक संभावना है कि यह कमांड चला रहा हो और फिर संबंधित फाइलों को इसमें जोड़ रहा हो gitignore। क्या मैं सही हूँ?
एड्रियन बन

13
सवाल और जवाब दोनों पर कई वोटों के साथ, मैं कहूंगा कि जाहिर तौर पर हम एक unstageकमांड रखना चाहते हैं git
milosmns

4
"git स्टेटस" अब सलाह देता है: "git Restore --staged <file> ..." का उपयोग करने के लिए unstage
yucer

334

git rm --cachedइंडेक्स से फाइल हटाने के लिए प्रयोग किया जाता है। उस स्थिति में जहां फ़ाइल पहले से ही रेपो में है, git rm --cachedफ़ाइल को इंडेक्स से हटा देगा, इसे वर्किंग डायरेक्टरी में छोड़ देगा और एक कमिट अब इसे रेपो से भी हटा देगा। असल में, कमिट के बाद, आपने फाइल को अनवील कर दिया और एक स्थानीय कॉपी रख ली।

git reset HEAD file(जो डिफ़ॉल्ट रूप से --mixedध्वज का उपयोग कर रहा है ) उस मामले में अलग है जहां फ़ाइल पहले से ही रेपो में है, यह रेपो (HEAD) से फ़ाइल के इंडेक्स संस्करण को प्रतिस्थापित करता है, प्रभावी रूप से इसमें संशोधन को अस्थिर करता है।

बिना फाइल के मामले में, यह पूरी फाइल को अनस्टेज करने जा रहा है क्योंकि फाइल HEAD में नहीं थी। इस पहलू में git reset HEAD fileऔर git rm --cachedसमान हैं, लेकिन वे समान नहीं हैं (जैसा कि रेपो में पहले से मौजूद फाइलों के मामले में बताया गया है)

के सवाल के लिए Why are there 2 ways to unstage a file in git?- वास्तव में कुछ भी करने के लिए केवल एक ही रास्ता नहीं है। कि यह की सुंदरता है :)


7
दोनों स्वीकृत उत्तर और यह एक महान हैं, और समझाते हैं कि आप एक बनाम दूसरे का उपयोग क्यों करेंगे। लेकिन वे सीधे तौर पर इस सवाल का जवाब नहीं देते कि दो अलग-अलग तरीकों का सुझाव क्यों दिया जाता है। ओपी के उदाहरण में पहले मामले में, एक गिट इनिट किया गया है। उस स्थिति में, git "git rm --cached" का सुझाव देता है क्योंकि उस बिंदु पर रिपॉजिटरी में कोई कमिट नहीं हैं और इसलिए HEAD मान्य नहीं है। "जीआईटी रीसेट हेड - एक" उत्पादन: "घातक: एक वैध रेफरी के रूप में 'हेड' को हल करने में विफल।"
sootsnoot

5
'गिट चेकआउट' के साथ, क्या आप फ़ाइल में किए गए सभी परिवर्तनों को नहीं खोएंगे? यह एक फ़ाइल को अस्थिर करने के समान नहीं है, जब तक कि मुझे गलतफहमी न हो।
जॉन डेगन

there is never really only one way to do anything in git. that is the beauty of it- ओह क्यों ? यह हमेशा महान होता है, जब केवल एक ही स्पष्ट तरीका होता है। यह हमारे दिमाग में बहुत समय और याददाश्त को बचाता है))
Oto Shavadze

128

एकदम आसानी से:

  • git rm --cached <file> फ़ाइल को पूरी तरह से ट्रैक करना बंद कर देता है (इसे फ़ाइल सिस्टम में छोड़कर, सादे के विपरीत git rm)
  • git reset HEAD <file> अंतिम प्रतिबद्ध के बाद से फ़ाइल में किए गए किसी भी संशोधन को रोकता है (लेकिन फाइल सिस्टम में उन्हें वापस नहीं करता है, इसके विपरीत कमांड नाम ** क्या सुझाव दे सकता है)। फ़ाइल संशोधन नियंत्रण में है।

यदि फ़ाइल पहले नियंत्रण में नहीं थी (यानी आप एक ऐसी फ़ाइल खोल रहे हैं, जिसे आपने git addपहली बार एड किया था ), तो दोनों कमांड का एक ही प्रभाव होता है, इसलिए इनका प्रकट होना "कुछ करने के दो तरीके" "।

* अपने उत्तर में कैविएट @DrewT उल्लेख को ध्यान में रखें, git rm --cachedएक फाइल के बारे में जो पहले रिपॉजिटरी के लिए प्रतिबद्ध थी । इस प्रश्न के संदर्भ में, अभी-अभी जोड़ी गई फ़ाइल और अभी तक प्रतिबद्ध नहीं है, इस बारे में चिंता करने की कोई बात नहीं है।

** मैं अपने नाम के कारण गिट रीसेट कमांड का उपयोग करने के लिए एक शर्मनाक लंबे समय से डर गया था - और आज भी मैं अक्सर यह सुनिश्चित करने के लिए वाक्यविन्यास देखता हूं कि मैं पेंच नहीं करता हूं। ( अपडेट : मैंने अंततः एक tldr पेज के उपयोगgit reset को संक्षेप में प्रस्तुत करने के लिए समय लिया , इसलिए अब मेरे पास एक बेहतर मानसिक मॉडल है कि यह कैसे काम करता है, और जब मैं कुछ विवरण भूल जाता हूं तो एक त्वरित संदर्भ।)


यह हैgit rm <file> --cached
neonmate

8
मुझे नहीं लगता कि इस उत्तर के लिए 4 अगस्त 2015 का सम्पादन एक समग्र सुधार था। यह तकनीकी शुद्धता तय कर सकता है (मुझे लगता है कि इसका मूल्यांकन करने के लिए योग्य नहीं लगता है), लेकिन मुझे डर है कि यह उत्तर की टोन को बहुत कम सुलभ बना देगा, जैसे भाषा को शुरू करने से "वर्तमान में अनट्रैक की गई फ़ाइल को ट्रैक करना शुरू करना अपरिहार्य हो जाता है। ", और" इंडेक्स "और" हेड "जैसे शब्दजाल का उपयोग करके, ठीक उसी तरह का सामान जो शुरुआती लोगों को डराता है। यदि कोई कर सकता है, तो कृपया अधिक नवागंतुक-अनुकूल भाषा को पुनर्स्थापित करने के लिए संपादित करें।
अगस्त्य

5
@Waldyrious से सहमत हैं। मूल उत्तर सीधे तौर पर git पाठ्यपुस्तक से बाहर नहीं हो सकता था, लेकिन इसने पर्याप्त तकनीकी स्तर पर इस सवाल का जवाब दिया। तकनीकी विवरण को टिप्पणियों में स्पष्ट किया जाना चाहिए था, न कि एक संपादित के रूप में जो मूल इरादे को अस्पष्ट करता था।
साइमन रॉब

मैंने संपादन को वापस कर दिया है। मेरा मानना ​​है कि समुदाय (पिछली टिप्पणियों में और उन पर वोटों) द्वारा पर्याप्त सत्यापन किया गया है कि संपादित उत्तर की स्पष्टता के लिए हानिकारक था।
वाल्ड्रियस जूल

नोट @ ड्र्यूट ने चेतावनी दी है कि यदि उपयोग rm --cachedऔर धक्का दिया जाता है, तो उसी शाखा को खींचने वाले किसी व्यक्ति के पास वास्तव में काम करने वाले पेड़ से फाइल (फाइल) होगी।
टॉम हेल 12

53

यह धागा थोड़ा पुराना है, लेकिन मैं अभी भी थोड़ा प्रदर्शन जोड़ना चाहता हूं क्योंकि यह अभी भी एक सहज समस्या नहीं है:

me$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   new file:   to-be-added
#   modified:   to-be-modified
#   deleted:    to-be-removed
#

me$ git reset -q HEAD to-be-added

    # ok

me$ git reset -q HEAD to-be-modified

    # ok

me$ git reset -q HEAD to-be-removed

    # ok

# or alternatively:

me$ git reset -q HEAD to-be-added to-be-removed to-be-modified

    # ok

me$ git status
# On branch master
# Changes not staged for commit:
#   (use "git add/rm <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   to-be-modified
#   deleted:    to-be-removed
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#   to-be-added
no changes added to commit (use "git add" and/or "git commit -a")

git reset HEAD(बिना -q) संशोधित फ़ाइल के बारे में एक चेतावनी देता है और इसका निकास कोड 1 है जिसे स्क्रिप्ट में त्रुटि माना जाएगा।

संपादित करें: git checkout HEAD to-be-modified to-be-removedयह भी अस्थिरता के लिए काम करता है, लेकिन कार्यक्षेत्र से परिवर्तन को पूरी तरह से हटा देता है

2.23.0 अपडेट अपडेट करें: समय-समय पर, कमांड बदलते रहते हैं। अब, git statusकहते हैं:

  (use "git restore --staged <file>..." to unstage)

... जो तीनों प्रकार के परिवर्तन के लिए काम करता है


धन्यवाद, पहले दो उत्तरों (पूरी तरह से शब्दावली पर मेरी अज्ञानता) से पूरी तरह से स्पष्ट नहीं था कि जीआईटी रीसेट ने स्थानीय रूप से फ़ाइल में संशोधनों को छोड़ दिया (जैसा कि चेक चेक के विपरीत होगा जो उन्हें वापस कर देगा)।
सूपडॉग

आपको संस्करण के बारे में भीख मांगने की चेतावनी देनी चाहिए, क्योंकि पुराने संस्करण ने नए संस्करणों में फ़ाइलों को हटा दिया है
लुइस मौरिसियो ने

@LuisMauricio कौन सी कमांड फाइलों को डिलीट करती है?
डैनियल एल्डर

36

यदि आपने गलती से उन फ़ाइलों का मंचन किया है, जिन्हें आप करना नहीं चाहते हैं, और निश्चित रहें कि आप परिवर्तन रखना चाहते हैं, तो आप भी उपयोग कर सकते हैं:

git stash
git stash pop

यह HEAD के लिए एक रीसेट करता है और आपके परिवर्तनों को फिर से लागू करता है, जिससे आप प्रतिबद्ध फ़ाइलों को पुन: चरणबद्ध कर सकते हैं। यदि आप पुल अनुरोधों ( git stash ; git checkout -b <feature> ; git stash pop) के लिए एक सुविधा शाखा बनाना भूल गए हैं तो यह भी सहायक है ।


3
यह "जीआईटी आरएम" टाइप करने की तुलना में एक साफ समाधान है और बहुत कम चिंताजनक है
सबमेज

1
git stashअन्य संबंधित लाभ हैं, क्योंकि यह भविष्य में उपलब्ध होने वाले रिफ्लग में प्रविष्टियां बनाता है। जब संदेह हो, तो आगे बढ़ें और एक करें git stash(उदाहरण के लिए git stash save -u "WIP notes to self"('-u' किसी भी नई / अनटैक की गई फ़ाइलों को स्टैश कमिट में शामिल करें) ... फिर git reflog show stashस्टैश कमिट्स की सूची और उनके शेक की सूची देखने का प्रयास करें। मैं एक शेल की सिफारिश करता हूं। उर्फ की तरहalias grs="git reflog show stash"
cweekly

15

इन 2 आदेशों में कई सूक्ष्म अंतर हैं यदि प्रश्न में फाइल पहले से ही रेपो में है और संस्करण नियंत्रण (पहले से प्रतिबद्ध आदि) में है:

  • git reset HEAD <file> मौजूदा कमेट में फाइल को अनस्टेज करता है।
  • git rm --cached <file>भविष्य के कमिट के लिए भी फाइल को अस्थिर करेगा। इसके साथ फिर से जुड़ जाने पर यह अस्थिर नहीं होता है git add <file>

और एक और महत्वपूर्ण अंतर है:

  • चलाने के बाद git rm --cached <file>और दूरदराज के लिए अपने शाखा धक्का, रिमोट से अपनी शाखा खींच किसी फ़ाइल मिल जाएगा वास्तव में उनके फ़ोल्डर से हटा दिया, अपने स्थानीय कामकाज में सिर्फ ट्रैक न किए गए (यानी शारीरिक रूप से फ़ोल्डर से नहीं हटाया) हो जाता है फ़ाइल सेट भले ही।

यह अंतिम अंतर उन परियोजनाओं के लिए महत्वपूर्ण है जिनमें एक कॉन्फ़िगर फ़ाइल शामिल होती है जहां टीम के प्रत्येक डेवलपर का एक अलग कॉन्फ़िगरेशन होता है (यानी अलग-अलग बेस यूआरएल, आईपी या पोर्ट सेटिंग) इसलिए यदि आप git rm --cached <file>किसी को भी उपयोग कर रहे हैं जो आपकी शाखा को खींचता है तो उसे मैन्युअल रूप से फिर से करना होगा- कॉन्फ़िगरेशन बनाएं, या आप उन्हें अपना भेज सकते हैं और वे इसे फिर से अपनी आईपी सेटिंग्स (आदि) में संपादित कर सकते हैं, क्योंकि डिलीट केवल उन लोगों को प्रभावित करता है जो आपकी शाखा को रिमोट से खींच रहे हैं।


10

आइए आपको stageपूरी निर्देशिका git add <folder>बताते हैं, लेकिन आप एक फ़ाइल को चरणबद्ध सूची (यानी वह सूची जो उत्पन्न करते समय चलती है git status) से बाहर करना चाहते हैं और बाहर रखी गई फ़ाइल के भीतर संशोधनों को रखें (आप कुछ काम कर रहे थे और यह प्रतिबद्ध होने के लिए तैयार नहीं है, लेकिन आप अपना काम नहीं खोना चाहते ...)। आप बस उपयोग कर सकते हैं:

git reset <file>

जब आप चलते हैं git status, तो आप देखेंगे कि आप जो भी फाइल (फाइलें) resetहैं unstagedऔर बाकी फाइलें आप addedअभी भी stagedसूची में हैं।


10

1।

D:\code\gt2>git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#       new file:   a

("git rm --cached ..." का उपयोग करें)

  • गिट पॉइंटर्स की एक प्रणाली है

  • आपके पास अपना पॉइंटर बदलने के लिए अभी तक कोई कमिटमेंट नहीं है

  • बदलावों को देखने के लिए आपके द्वारा बताई गई फ़ाइलों को हटाने के लिए 'बाल्टी से बाहर की ओर इशारा की गई फ़ाइलों को निकालने ' का एकमात्र तरीका है

2।

D:\code\gt2>git commit -m a
[master (root-commit) c271e05] a
0 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 a

git कमिट -मा

  • आपने कमिट किया, ' बचाया '

3।

D:\code\gt2>git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       new file:   b
#

("रीसेट रीसेट HEAD ..." को अनस्टेज करने के लिए उपयोग करें)

  • आपने इस समय अपने कोड में एक कमिट किया
  • अब आप अपने पॉइंटर को अपने कमिट में रीसेट कर सकते हैं ' बैक टू बैक लास्ट सेव '

1
यह वास्तव में एकमात्र उत्तर है जो ठीक से प्रश्न का उत्तर देता है, आईएमओ। यह वास्तव में इस सवाल का जवाब देता है, जो 'git rm --cached' और 'git reset HEAD' में क्या अंतर नहीं है, लेकिन 'git असंगत रूप से दोनों विकल्प क्यों देता है?', इसका उत्तर यह है कि रीसेट करने के लिए कोई HEAD नहीं है? जब आप git initपहली बार
माइल्स राउत

5

मुझे आश्चर्य है कि किसी ने गिट रिफ्लग का उल्लेख किया ( http://git-scm.com/docs/git-reflog ))

# git reflog
<find the place before your staged anything>
# git reset HEAD@{1}

रिफ्लॉग एक गिट इतिहास है जो न केवल रेपो में परिवर्तन को ट्रैक करता है, बल्कि उपयोगकर्ता कार्यों (जैसे, अलग-अलग शाखा को चेकआउट, आदि) को भी ट्रैक करता है और उन कार्यों को पूर्ववत करने की अनुमति देता है। इसलिए फ़ाइल को अनस्टैज करने के बजाय जो गलती से मंचन किया गया था, जहाँ आप उस बिंदु पर वापस आ सकते हैं जहाँ आपने फ़ाइलों को स्टेज नहीं किया था।

इस के समान है git reset HEAD <file> लेकिन कुछ मामलों में अधिक दानेदार हो सकता है।

क्षमा करें - वास्तव में आपके प्रश्न का उत्तर नहीं दे रहा है, लेकिन अभी तक फ़ाइलों को अस्थिर करने के लिए एक और तरीका है जो मैं अक्सर उपयोग करता हूं (मैं एक रयान स्टीवर्ट द्वारा जवाब बहुत पसंद करता हूं और बहुत अच्छा लगता है;);) मुझे आशा है कि यह मदद करता है।


5

महज प्रयोग करें:

git reset HEAD <filename>

यह फ़ाइल को अस्थिर करता है और आपके द्वारा किए गए परिवर्तनों को रखता है, इसलिए आप बदले में, यदि आप चाहते हैं तो शाखाएं बदल सकते हैं और git addउन फ़ाइलों को इसके बजाय किसी अन्य शाखा में भेज सकते हैं । सभी परिवर्तन रखे गए हैं।


3

यह मुझे प्रतीत होता है कि git rm --cached <file>फ़ाइल को उस निर्देशिका से हटाए बिना सूचकांक से हटा देता है जहां एक सादा git rm <file>दोनों करता है, जैसे कि ओएस rm <file>अपने संस्करण को हटाने के बिना फ़ाइल को निर्देशिका से हटा देगा।


1

2.23 और उसके बाद के संस्करण के लिए,

इन सुझावों के बजाय, आप फ़ाइल (ओं) के git restore --staged <file>क्रम में उपयोग कर सकते हैं unstage


यह दोनों विकल्पों के साथ काम करता है --stageऔर साथ ही --staged
d131310
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.