Git: कैसे 2 फ़ाइलों को वापस बदलने के लिए जो हठपूर्वक "बदली गई लेकिन प्रतिबद्ध नहीं" पर अटक गई हैं?


84

मेरे पास एक रेपो है जिसमें दो फाइलें हैं जिन्हें माना जाता है कि मैंने स्थानीय रूप से बदल दिया है।

तो मैं इस के साथ फंस गया हूँ:

$ git status
# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   dir1/foo.aspx
#       modified:   dir2/foo.aspx
#
no changes added to commit (use "git add" and/or "git commit -a")

डूइंग का git diffकहना है कि पूरी फ़ाइल सामग्री बदल गई है, भले ही इसे नेत्रहीन से लगता है कि असत्य लगता है (सामान्य पंक्ति की सीमाएं प्रतीत होती हैं जो देखने में विफल होती हैं)।

दिलचस्प है कि मुझे इन फाइलों को स्थानीय स्तर पर बदलना याद नहीं है। इस रेपो का उपयोग एक रिमोट रेपो (प्राइवेट, GitHub.com, FWIW) के साथ किया जाता है।

कोई फर्क नहीं पड़ता कि मैंने क्या कोशिश की है, मैं इन स्थानीय परिवर्तनों को नहीं छोड़ सकता। मैंने सभी की कोशिश की है:

$ git checkout -- .
$ git checkout -f
$ git checkout -- dir1/checkout_receipt.aspx
$ git reset --hard HEAD
$ git stash save --keep-index && git stash drop
$ git checkout-index -a -f

दूसरे शब्दों में, मैंने हर चीज की कोशिश की है कि मैं गिट में अस्थिर परिवर्तनों को कैसे छोड़ दूं? प्लस अधिक। लेकिन 2 फाइलें "परिवर्तित लेकिन प्रतिबद्ध नहीं" के रूप में अटकी हुई हैं।

क्या बिल्ली इस तरह दो फ़ाइलों को अटकाने का कारण बनेगी और प्रतीत होता है कि "अन-रिवर्ट-टेबल" ??

PS ऊपर दी गई सूची में, जो मैंने पहले से ही आजमाया हुआ था, मैंने गलती से लिखा था git revertजब मेरा मतलब था git checkout। मुझे खेद है और आप में से उन लोगों को धन्यवाद जिन्होंने उत्तर दिया कि मुझे कोशिश करनी चाहिए checkout। मैंने इसे ठीक करने के लिए प्रश्न संपादित किया। मैंने निश्चित रूप से पहले से ही कोशिश की थी checkout


के आउटपुट में फर्क पड़ता है git diff --ignore-space-changeया नहीं ? git diff --ignore-all-spacegit diff
JDD

@ जरमहद हां! या तो ध्वज के साथ, git diffफ़ाइलें समान हैं।
ग्रेग हेंडरशॉट

2
के संभावित डुप्लिकेट stackoverflow.com/questions/2016404/... । मुझे वैसे भी बेहतर तरीके से स्वीकार किए गए उत्तर पसंद हैं, जो git config --global core.autocrlf false'सही' के बजाय सेट करना है।
जोहान

2
उत्तर [यहां] [1] मेरे और कई अन्य लोगों के लिए काम किया। [१]: stackoverflow.com/questions/2016404/…
माइक के

2
ऐसा तब भी होता है जब एक ही निर्देशिका में 2 या अधिक फ़ाइलों वाले रिपॉजिटरी को केस-असंवेदनशील फाइल सिस्टम में चेक किया जाता है। समस्या को हल करने के लिए फ़ाइल में से किसी एक को निकालें या नाम बदलें।
465544

जवाबों:


33

फ़ाइलों में लाइन अंत क्या हैं? मैं शर्त लगा रहा हूँ कि वे CRLF हैं। यदि वे हैं, तो इस गाइड को देखें: http://help.github.com/line-endings/

संक्षेप में, आपको यह सुनिश्चित करने की ज़रूरत है कि लाइन एंडिंग को LF की ओर से कन्वर्ट करने के लिए सेट किया गया है, और फिर उन फ़ाइलों को कमिट करें। रेपो में फाइलें हमेशा एलएफ होनी चाहिए, जांच की गई फाइलें ओएस की मूल होनी चाहिए, यह मानते हुए कि आपने सही तरीके से सेट किया है।


1
धन्यवाद। मेरे पास पहले से ही है git config --global core.autocrlf trueऔर इसलिए अन्य पार्टी GitHub पर रेपो को आगे बढ़ाती है।
ग्रेग हेंडरशॉट

1
तब आपको <pre>रेपो में फ़ाइलों को ठीक करने के लिए उस गाइड के अंतिम ब्लॉक में बिट्स करने की आवश्यकता होगी ।
टेककुब

5
मैं इस बात से असहमत हूं कि रेपो में लाइन एंडिंग हमेशा LF होनी चाहिए (खासकर अगर किसी और ने CRLF को कमिट किया हो) और यह भी कि OS हमेशा देशी होना चाहिए। मेरा विंडोज एडिटर और वातावरण (मुख्य रूप से PHP, HTML, CSS आदि के लिए) LF लाइन एंडिंग के साथ पूरी तरह से मेल खाता है।
साइमन ईस्ट

एक प्रतिभाशाली जवाब, मैं भूल गया था कि मैं हाल ही में gitattributes का उपयोग रेपो फ़ाइलों में LF को बाध्य करने के लिए कर रहा था और यह उम्मीद नहीं कर रहा था कि ऑटो फ़ाइल को बदल देगा। हमारे पास विंडोज़ और लिनक्स डेवलपर्स का एक मिश्रण है और यह हमें पागल बना रहा था क्योंकि विभिन्न प्लेटफार्मों पर संपादक लाइन टर्मिनेटरों को स्विच आउट करते रहे, एक बार जब यह सब बदल गया, तो इसे हटा देना चाहिए।
ओलिवर डेंगी

120

मैंने एक समान मुद्दे को हल करने की कोशिश में घंटों बिताए - एक दूरस्थ शाखा जिसे मैंने चेक किया था, जिसने हठपूर्वक चार फ़ाइलों को 'चेंजेड लेकिन अपडेट नहीं' के रूप में दिखाया था, यहां तक ​​कि सभी फाइलों को हटाने और git checkout -fफिर से चलने पर (या इस पोस्ट से अन्य विविधताएं)!

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

git ls-files -m | xargs -i git update-index --assume-unchanged "{}"

हालाँकि, मैक OSX पर xargs थोड़ा अलग है (टिप्पणी के लिए thx डैनियल):

git ls-files -m | xargs -I {} git update-index --assume-unchanged {}

मैंने इसे अगली बार अपने लिए एक प्लेसहोल्डर के रूप में जोड़ा है, लेकिन मुझे उम्मीद है कि यह किसी और को भी मदद करता है।

-al


9
मेरे पास कुछ ज़िद्दी फाइलें थीं और इस कमांड को चलाया, git स्टेटस में अब कोई बदलाव नहीं हुआ है, लेकिन जब मैं ब्रांच git को बदलने की कोशिश करता हूं तब भी मुझे बताता है कि मैं ब्रांच नहीं बदल सकता क्योंकि उन दोनों फाइलों में लोकल बदलाव हैं। मुझे यकीन नहीं है कि मैंने क्या गलत किया है, लेकिन ऐसा लगता है कि इसे ठीक करने के बजाय समस्या को कवर किया गया है? मैं भी उस कमांड को चलाने के बाद फाइलों को कमिट नहीं कर सका। मेरे लिए समाधान उन्हें हटाना, प्रतिबद्ध करना और शाखाओं को स्वैप करना था।
रोडएच 257

5
धन्यवाद! मैंने कोशिश की कि मेरे द्वारा खोजे गए हर दूसरे उत्तर में वर्णित सभी ट्रिक्स - कोई भी काम न करें। एक मैक पर लाइन का उपयोग नहीं कर सकता है, बस प्रत्येक फ़ाइल पर git अद्यतन-अनुक्रमणिका-अपरिवर्तित <फ़ाइल नाम> भागा और इससे समस्या दूर हो गई।
योनातन करणी

2
जब आप इस फ़ाइल पर स्थानीय संशोधन चाहते हैं, तो "--assume-अपरिवर्तित" विकल्प का उपयोग नहीं किया जाना चाहिए? जैसे जब आप एक टेम्पलेट वेबसाइट कॉन्फिग फाइल को चेकआउट करते हैं और इसे संवेदनशील इन्फोस के साथ अपडेट करते हैं जिसे रिपॉजिटरी में संग्रहीत नहीं किया जाना चाहिए?
मैक्सिम रॉसिनी

6
यह वही है जो मुझे चाहिए था, हालांकि मैक पर xargs थोड़ा अलग तरीके से काम कर रहा है (मैं 10.10 योसेमाइट चला रहा हूं)। यह अंत में मेरे लिए काम किया:git ls-files -m | xargs -I {} git update-index --assume-unchanged {}
डैनियल

3
कमांड के प्रभाव को वापस git ls-files -v|grep '^h' | cut -c3- | xargs -i git update-index --no-assume-unchanged "{}"
लाने के लिए

20

यह है कि मैंने अपने मामले में एक ही समस्या को कैसे तय किया: खुला ।सुविधाएँ बदलें:

* text=auto

सेवा:

#* text=auto

सहेजें और बंद करें, फिर वापस लाएं या रीसेट करें, संकेत के लिए @Simon पूर्व के लिए धन्यवाद


1
निकाला जा रहा है text=auto.gitattributes में सेटिंग मेरे लिए काम किया है, और फिर बाद मैं git reset --hard, तो वह सेटिंग वापस डाल, अब पता चला है फ़ाइलों के रूप में संशोधित!
EricE

1
इस text=autoसेटिंग में स्पष्ट रूप से कुछ गड़बड़ है । मैं कई ओएस से आने वाले रिपोज के साथ काम कर रहा हूं और मुझे अभी भी यह पता नहीं चला है कि मुझे और क्या परेशानी होती है: इसे रखना या इसे छोड़ देना।
मैरिनो एक

1
@MarinosAn हाँ, विशेष रूप से, git आपको मौजूदा पाठ फ़ाइलों को गलत लाइन एंडिंग के साथ छोड़ने की अनुमति देता है जब आप पहली बार इस सेटिंग को जोड़ते हैं। यह सिर्फ गलत है और जब तक आप खुद को ऐसा करने के लिए याद नहीं करते, आप अंततः इन अन-रीवर्टेबल परिवर्तनों में से एक में भाग लेंगे।
रोमन स्टार्कोव

12

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

git diff dir1 / foo.aspx

और यह आपको फ़ाइल मोड परिवर्तन दिखाएगा। यह अभी भी आपको उन्हें वापस नहीं आने देगा, हालाँकि। उस उपयोग के लिए या तो

git config core.filemode false

या जोड़कर अपने पाठ संपादक में अपना git .config बदलें

[कोर]

filemode = false

ऐसा करने के बाद, आप उपयोग कर सकते हैं

git रीसेट HEAD dir1 / foo.aspx

और फ़ाइल गायब हो जानी चाहिए।

(मुझे यह सब इस जवाब से मिला कि मैं git को मोड परिवर्तन (chmod) कैसे अनदेखा करूं? )


1
यदि आप विंडोज पर हैं, तो ईयाल का निदान / समाधान आपका पहला अनुमान होना चाहिए
AlcubierreDrive

Cmd.exe से cygwin git का उपयोग न करने के लिए विशेष रूप से सावधान रहें। यदि आप cmd.exe में git चाहते हैं, तो msysgit इंस्टॉल करें।
अलक्यूबिएरेड्राइव

बस यह पुष्टि करने के लिए कि यह वास्तव में विंडोज पर मुद्दा था।
देजन मार्जनोविच

विंडोज पर मेरे लिए, यह मुद्दा नहीं core.filemodeथा ( पहले से ही गलत था)। मेरे मामले में, फिक्स / वर्कअराउंड एलन फोर्सिथ के जवाब में एक था ।
वेनरिक्स

3

स्थानीय परिवर्तनों को वापस लाने का प्रयास करें :

git checkout -- dir1/foo.aspx
git checkout -- dir2/foo.aspx

मेरे पास मस्तिष्क पर "उल्टा" था और मेरा मतलब लिखना था checkout। मैंने पहले से ही कोशिश की थी checkout। आपके उत्तर के लिए वैसे भी धन्यवाद। यह मेरे मूल प्रश्न का एक अच्छा उत्तर था इसलिए मैं इसे बढ़ाऊंगा।
ग्रेग Hendershott

3

मेरे पास कुछ प्रेत परिवर्तित फाइलें थीं जो संशोधित के रूप में दिखाई दे रही थीं, लेकिन वास्तव में समान थीं।

यह कमांड चलाना कभी-कभी काम करता है:
(गिट्स के "स्मार्ट" लेकिन अक्सर अनचाही लाइन-एंड रूपांतरणों को बंद कर देता है)

git config --local core.autocrlf false

लेकिन एक अन्य मामले में मैंने पाया कि यह .gitattributesरूट में एक फ़ाइल के कारण था जिसमें कुछ लाइन-एंडिंग सेटिंग्स मौजूद थीं, जो autocrlfबंद होने पर भी कुछ फ़ाइलों के लिए आवेदन करने की कोशिश कर रही थी। यह वास्तव में उपयोगी नहीं था, इसलिए मैंने हटा दिया .gitattributes, प्रतिबद्ध किया, और फ़ाइल अब संशोधित नहीं दिखाई गई।


निकाला जा रहा है text=auto.gitattributes में सेटिंग मेरे लिए काम किया है, और फिर बाद मैं git reset --hard, तो वह सेटिंग वापस डाल, अब पता चला है फ़ाइलों के रूप में संशोधित!
EricE

2
git checkout dir1/foo.aspx
git checkout dir2/foo.aspx

मेरे पास मस्तिष्क पर "उल्टा" था और मेरा मतलब लिखना था checkout। मैंने पहले से ही कोशिश की थी checkout। आपके उत्तर के लिए वैसे भी धन्यवाद। यह मेरे मूल प्रश्न का एक अच्छा उत्तर था इसलिए मैं इसे बढ़ाऊंगा।
ग्रेग Hendershott

2

आपको निर्देशिकाओं के नामकरण से संबंधित समस्या भी हो सकती है। आपके कुछ सहकर्मी निर्देशिका का नाम बदल सकते हैं जैसे उदाहरण myHandler से MyHandler । यदि आपने बाद में मूल निर्देशिका की कुछ फ़ाइलों को धकेल दिया और खींच लिया तो आपके पास दूरस्थ रिपॉजिटरी पर 2 अलग-अलग निर्देशिकाएँ होंगी और केवल आपके स्थानीय मशीन पर विंडोज पर केवल एक ही हो सकता है। और तुम मुश्किल में हो।

यह जाँचने के लिए कि क्या ऐसा है, बस यह देखें कि दूरस्थ रिपॉजिटरी में दोहरी संरचना है या नहीं।

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


2

मुझे लगता है कि समस्या को बेहतर ढंग से समझने के लिए, इस मुद्दे को कैसे पुन: पेश करना है , इस पर एक संकेत प्रदान करना उपयोगी होगा :

$ git init
$ echo "*.txt -text" > .gitattributes
$ echo -e "hello\r\nworld" > 1.txt
$ git add 1.txt 
$ git commit -m "committed as binary"
$ echo "*.txt text" > .gitattributes
$ echo "change.." >> 1.txt

# Ok let's revert now

$ git checkout -- 1.txt
$ git status
 modified:   1.txt

# Oooops, it didn't revert!!


# hm let's diff:

$ git diff
 warning: CRLF will be replaced by LF in 1.txt.
 The file will have its original line endings in your working 
 directory.
 diff --git a/1.txt b/1.txt
 index c78c505..94954ab 100644
 --- a/1.txt
 +++ b/1.txt
 @@ -1,2 +1,2 @@
 -hello
 +hello
  world

# No actual changes. Ahh, let's change the line endings...

$ file 1.txt 
 1.txt: ASCII text, with CRLF line terminators
$ dos2unix 1.txt
 dos2unix: converting file 1.txt to Unix format ...
$ git diff
 git diff 1.txt
 diff --git a/1.txt b/1.txt
 index c78c505..94954ab 100644
 --- a/1.txt
 +++ b/1.txt
 @@ -1,2 +1,2 @@
 -hello
 +hello
  world

# No, it didn't work, file is still considered modified.

# Let's try to revert for once more:
$ git checkout -- 1.txt
$ git status
 modified:   1.txt

# Nothing. Let's use a magic command that prints wrongly committed files.

$ git grep -I --files-with-matches --perl-regexp '\r' HEAD

HEAD:1.txt

पुन: पेश करने 2nd रास्ता: ऊपर स्क्रिप्ट में इस लाइन को बदल दें:
echo "*.txt -text" > .gitattributes
के साथ
git config core.autocrlf=false
और लाइनों के बाकी रखने के रूप में


उपरोक्त सभी क्या कहते हैं? एक पाठ फ़ाइल कर सकते हैं (कुछ परिस्थितियों में), CRLF के साथ प्रतिबद्ध होना (जैसे -textमें .gitattributes/ या core.autocrlf=false)।

जब हम बाद में उसी फाइल को टेक्स्ट ( -text-> text) के रूप में मानना ​​चाहते हैं, तो उसे फिर से प्रतिबद्ध होना होगा।
बेशक आप अस्थायी रूप से इसे वापस कर सकते हैं (जैसा कि अबू असर द्वारा सही उत्तर दिया गया है )। हमारे मामले में:

echo "*.txt -text" > .gitattributes
git checkout -- 1.txt
echo "*.txt text" > .gitattributes

जवाब है : क्या आप वास्तव में ऐसा करना चाहते हैं, क्योंकि यह वही समस्या पैदा करने वाला है जिससे आप फ़ाइल बदलते हैं।


रिकार्ड के लिए:

यह जाँचने के लिए कि आपके रेपो में कौन सी फाइलें इस समस्या का कारण बन सकती हैं, निम्नलिखित कमांड को निष्पादित करें (git --with-libpc के साथ संकलित किया जाना चाहिए):

git grep -I --files-with-matches --perl-regexp '\r' HEAD

फ़ाइल (ओं) को प्रतिबद्ध करके (यह मानते हुए कि आप उन्हें पाठ के रूप में मानना ​​चाहते हैं), यह वही है जो इस लिंक में प्रस्तावित है http://help.github.com/line-endings/ ऐसी समस्याओं को ठीक करने के लिए । लेकिन, आपको हटाने .git/indexऔर प्रदर्शन करने के बजाय reset, आप बस फ़ाइल बदल सकते हैं, फिर प्रदर्शन कर सकते हैं git checkout -- xyz zyfऔर फिर प्रतिबद्ध कर सकते हैं।


2

मेरे पास एक ही मुद्दा था, दिलचस्प जोड़ के साथ कि फाइलें विंडोज़ पर बदल दी गईं, लेकिन डब्ल्यूएसएल से उन्हें देखते समय नहीं। रेखा के अंत, रीसेट आदि के साथ खिलवाड़ की कोई राशि इसे बदलने में सक्षम नहीं थी।

आखिरकार, मुझे इस जवाब में एक समाधान मिला । निम्नलिखित संयोजक के लिए पाठ है:


मैंने निम्नलिखित चरणों का उपयोग करके इस समस्या को हल किया है

1) हर फाइल को Git के इंडेक्स से निकालें।

git rm --cached -r .

2) सभी नई लाइन अंत को लेने के लिए Git इंडेक्स को फिर से लिखें।

git reset --hard

समाधान साइट पर वर्णित चरणों का हिस्सा था https://help.github.com/articles/deal-with-line-end//


1

मेरे लिए मुद्दा लाइन एंडिंग का नहीं था। यह फ़ोल्डर नाम में केस बदलने के बारे में था (Reset_password -> Reset_Password)। इस समाधान ने मेरी मदद की: https://stackoverflow.com/a/34919019/1328513


1

यह समस्या इसलिए भी हो सकती है क्योंकि गिट कैपिटलाइज़ेशन के अंतर को विभिन्न फ़ाइलों के रूप में मानते हैं लेकिन विंडोज़ उन्हें एक ही फ़ाइल के रूप में मानते हैं। यदि किसी फ़ाइल का नाम केवल इसका कैपिटलाइज़ेशन बदल गया है, तो उस रेपो का प्रत्येक विंडोज़ उपयोगकर्ता इस स्थिति में समाप्त हो जाएगा।

समाधान की पुष्टि करने के लिए है कि फ़ाइलें सामग्री सही हैं और फिर इसे पुनः प्राप्त करें। चूंकि अलग थे, इसलिए हमें दो फ़ाइलों की सामग्री को एक साथ मिलाना पड़ा। फिर खींचो और एक मर्ज संघर्ष होगा जिसे आप डुप्लिकेट फ़ाइल को हटाकर हल कर सकते हैं। मर्ज रिज़ॉल्यूशन की अनुशंसा करें और आप एक स्थिर स्थिति में वापस आ गए हैं।

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