गिट फ़िल्टर-शाखा के साथ लाइन-एंडिंग को ठीक करने की कोशिश की जा रही है, लेकिन कोई भी भाग्य नहीं है


270

मुझे विंडोज / लिनक्स लाइन-एंडिंग मुद्दे के साथ काट दिया गया है। ऐसा लगता है, GitHub, MSysGit, और अन्य स्रोतों के माध्यम से, सबसे अच्छा समाधान यह है कि आपके स्थानीय रिपोज़ को linux-style line endings का उपयोग करने के लिए सेट किया जाए, लेकिन इसे सेट core.autocrlfकरें true। दुर्भाग्य से, मैंने इसे जल्दी शुरू नहीं किया, इसलिए अब हर बार जब मैं बदलाव करता हूं तो लाइन एंडिंग बोर हो जाते हैं।

मुझे लगा कि मुझे यहाँ एक उत्तर मिल गया है लेकिन मैं इसे मेरे लिए काम नहीं कर सकता। मेरी लिनक्स कमांड लाइन का ज्ञान सबसे अच्छा है, इसलिए मुझे यह भी पता नहीं है कि "xargs fromdos" लाइन उनकी स्क्रिप्ट में क्या करती है। मुझे ऐसी किसी फ़ाइल या निर्देशिका के बारे में संदेश मिलते रहते हैं, और जब मैं इसे किसी मौजूदा निर्देशिका को इंगित करने का प्रबंधन करता हूं, तो यह बताती है कि मेरे पास अनुमति नहीं है।

मैंने इसे MSysGit के साथ Windows और Mac OS X टर्मिनल के माध्यम से आज़माया है।


मैं इस धागे को लगभग पर्याप्त तक नहीं बढ़ा सकता। +1 ++ इसके लिए मामले पर सबसे अच्छा जवाब देने के लिए।
जज

चार्ल्स से सहमत। हालाँकि, मेरे मामले में (Mac OS X 10.8 का उपयोग करके)> git config core.autocrlf false काम किया, नहीं> git config core.autocrlf input
user1045085

जवाबों:


187

Gitattributes के लिए git प्रलेखन अब "फिक्सिंग" या आपके प्रोजेक्ट में सभी लाइन एंडिंग को सामान्य करने के लिए एक और दृष्टिकोण का दस्तावेज करता है। यहाँ इसका सार है:

$ echo "* text=auto" >.gitattributes
$ git add --renormalize .
$ git status        # Show files that will be normalized
$ git commit -m "Introduce end-of-line normalization"

यदि कोई भी फाइल जिसे सामान्यीकृत नहीं किया जाना चाहिए वह git स्टेटस में दिखाई देती है, तो git ऐड -u चलाने से पहले उनकी टेक्स्ट विशेषता को परेशान करें।

manual.pdf -text

इसके विपरीत, जिन पाठ फ़ाइलों का पता नहीं चलता है, वे सामान्य रूप से मैन्युअल रूप से सक्षम हो सकते हैं।

weirdchars.txt text

यह --renormalizeजनवरी 2018 को git v2.16.0 में जारी किए गए एक नए ध्वज का लाभ उठाता है । git के पुराने संस्करणों के लिए, कुछ और चरण हैं:

$ echo "* text=auto" >>.gitattributes
$ rm .git/index     # Remove the index to force git to
$ git reset         # re-scan the working directory
$ git status        # Show files that will be normalized
$ git add -u
$ git add .gitattributes
$ git commit -m "Introduce end-of-line normalization"

1
क्या आप मुझे बता सकते हैं कि इसका उद्देश्य क्या है git reset?
crdx

1
अनुक्रमणिका के पुनर्निर्माण के लिए बाध्य करता है, जिसके दौरान यह प्रत्येक फ़ाइल को स्कैन करता है कि क्या इसके बारे में अनुमान लगाने के लिए। आरएम पुराने सूचकांक को हटा देता है, रीसेट नए सूचकांक का निर्माण करता है।
रस ईगन

16
धन्यवाद, यह मेरे लिए काम किया। दौड़ने के बाद एक उपयोगी कमांड केवल यह सुनिश्चित करने के git statusलिए चलना है git diff --ignore-space-at-eolकि केवल वही परिवर्तन जो आप कर रहे हैं वह लाइन एंडिंग हैं।
zelanix

1
नोट: इस और "पुराने" समाधान के बीच एकमात्र "वास्तविक" अंतर .ITattributes (उपयुक्त सामग्री के साथ) की उपस्थिति में है। इसके बिना, git resetकोई संशोधन का पता नहीं लगाएगा, और इस तरह बेकार है।
रोब

3
Gitattributes पेज पर दिए गए निर्देशों को --renormalizegit v2.16.0 में जोड़े गए झंडे का लाभ उठाने के लिए अद्यतन किया गया है, जो जनवरी 2018 में जारी किया गया था। यह --renormalizeध्वज प्रत्येक ट्रैक की गई फ़ाइल के लिए री-प्रोसेसिंग लाइन एंडिंग की प्रक्रिया को एकल कमांड में समेकित करता है git add --renormalize .:।
माइक हिल

389

इसे ठीक करने का सबसे आसान तरीका है कि एक ऐसा कमिटमेंट किया जाए जो सभी लाइन एंडिंग को ठीक करे। यह मानते हुए कि आपके पास कोई संशोधित फाइल नहीं है, तो आप इस प्रकार कर सकते हैं।

# From the root of your repository remove everything from the index
git rm --cached -r .

# Change the autocrlf setting of the repository (you may want 
#  to use true on windows):
git config core.autocrlf input

# Re-add all the deleted files to the index
# (You should get lots of messages like:
#   warning: CRLF will be replaced by LF in <file>.)
git diff --cached --name-only -z | xargs -0 git add

# Commit
git commit -m "Fixed crlf issue"

# If you're doing this on a Unix/Mac OSX clone then optionally remove
# the working tree and re-check everything out with the correct line endings.
git ls-files -z | xargs -0 rm
git checkout .

7
पुनश्च मैंने github.com पर लोगों को आपके फिक्स की सिफारिश की है और उन्होंने आपके समाधान का उपयोग करने के लिए अपने हेल्प गाइड को अपडेट किया है (पहले यह सिर्फ एक ताजा क्लोन और एक हार्ड रीसेट की सिफारिश की थी, जो सभी फ़ाइलों को प्राप्त करने में नहीं लगता था।) help.github। com / डीलिंग-साथ-लाइनिंग
ब्रायन डोनह्यू

31
धन्यवाद ... यह एक महान तय है। यह GitHub पर मिला।
17

4
आप यह सुनिश्चित करने के लिए config.safecrlf की भी जाँच कर सकते हैं कि आप गैर-पाठ फ़ाइलों (जैसे कि बाइनरी) में क्रॉलर को नहीं बदल रहे हैं। इसे डॉक्स कर्नेल . org/pub/software/scm/git/ docs/ git-config.html पर देखें
वृष v

4
@ vrish88: यदि आप इस स्थिति में हैं, हालांकि, आप मिश्रित लाइनिंग एंडिंग्स से पीड़ित होने की संभावना रखते हैं और core.safecrlf वास्तव में आपको वह करने से रोक सकता है जो आपको करने की आवश्यकता है। शायद सेफसेल्फ का उपयोग नहीं करना आसान है। git को अक्सर बाइनरी फ़ाइल का पता लगाना गलत नहीं होता है और अगर ऐसा होता है, तो आप इसे मैन्युअल रूप से .itattribute के साथ बाइनरी के रूप में चिह्नित कर सकते हैं और पिछले संस्करण से सही संस्करण को पुनर्प्राप्त कर सकते हैं।
CB बेली

26
नीचे राग एगन के जवाब में अनुशंसित नया समाधान सरल है और इसमें आपके सभी स्रोत कोड को हटाने जैसी डरावनी चीजें शामिल नहीं हैं , इसलिए मैं वास्तव में लोगों को इसका उपयोग करने की सलाह दूंगा , हालांकि इस पुराने समाधान में 10 गुना अधिक वोट हैं!
पोरकुलस

11

लाइन एंडिंग से निपटने के लिए मेरी प्रक्रिया निम्नानुसार है (कई रिपोज पर परीक्षण की गई लड़ाई):

एक नया रेपो बनाते समय:

  • के .gitattributesरूप में के रूप में अन्य विशिष्ट फ़ाइलों के साथ बहुत पहले प्रतिबद्ध में डाल दिया .gitignoreऔरREADME.md

मौजूदा रेपो से निपटने के दौरान:

  • .gitattributesतदनुसार बनाएँ / संशोधित करें
  • git commit -a -m "Modified gitattributes"
  • git rm --cached -r . && git reset --hard && git commit -a -m 'Normalize CRLF' -n"
    • -n( --no-verifyपूर्व प्रतिबद्ध हुक को छोड़ना है)
    • मुझे अक्सर ऐसा करना पड़ता है कि मैंने इसे एक उपनाम के रूप में परिभाषित किया है alias fixCRLF="..."
  • पिछली कमांड को दोहराएं
    • हाँ, यह वूडू है, लेकिन आम तौर पर मुझे कमांड को दो बार चलाना पड़ता है, पहली बार यह कुछ फाइलों को सामान्य करता है, दूसरी बार और भी फाइलें। आम तौर पर जब तक कोई नई प्रतिबद्धता नहीं बनती तब तक इसे दोहराना सबसे अच्छा होगा :)
  • पुराने और सामान्यीकरण से ठीक पहले (नई शाखा) के बीच कुछ समय पीछे-पीछे जाएं। ब्रांच को स्विच करने के बाद, कभी-कभी git को और भी अधिक फाइल्स मिलेंगी जिन्हें रिन्युअल करने की आवश्यकता है!

में .gitattributesमैं सभी पाठ फ़ाइलों को स्पष्ट रूप से घोषित वामो EOL होने के रूप में आम तौर पर विंडोज टूलींग के बाद से, जबकि गैर- Windows टूलींग CRLF साथ संगत नहीं है वामो के साथ संगत है (यहां तक कि कई NodeJS कमान वामो लाइन उपकरण मान और इसलिए आपकी फ़ाइलों में EOL बदल सकते हैं)।

की सामग्री .gitattributes

.gitattributesआमतौर पर मेरी तरह दिखता है:

*.html eol=lf
*.js   eol=lf
*.json eol=lf
*.less eol=lf
*.md   eol=lf
*.svg  eol=lf
*.xml  eol=lf

यह पता लगाने के लिए कि वर्तमान रेपो में गिट द्वारा किस विशिष्ट एक्सटेंशन को ट्रैक किया जाता है, यहां देखें

सामान्यीकरण के बाद के मुद्दे

एक बार जब यह किया जाता है, तो एक और सामान्य चेतावनी है।

कहते हैं कि आपका masterपहले से ही अद्यतित और सामान्यीकृत है, और फिर आप चेकआउट करते हैं outdated-branch। अक्सर उस शाखा की जाँच के बाद ही सही, कई फाइलें संशोधित के रूप में चिह्नित करती हैं।

समाधान एक नकली प्रतिबद्ध ( git add -A . && git commit -m 'fake commit') और फिर करना है git rebase master। रिबास के बाद, नकली प्रतिबद्ध दूर जाना चाहिए।


1
मुझे लगा कि मैं पागल हो रहा हूं, जब तक कि मैं आपकी पोस्ट नहीं पढ़ता, क्योंकि मुझे कई बार आदेशों के निर्दिष्ट अनुक्रम को भी चलाना पड़ा। वूडू! ;)
शॉन फ़ॉसेट

जीआईटी संस्करण के साथ 2.7.0.windows.1, मैंने निम्नलिखित का उपयोग किया: git rm --cached -r . && git reset --hard && git add . && git commit -m "Normalize EOL" -n
सीन फ़ॉस्सेट

4
git status --short|grep "^ *M"|awk '{print $2}'|xargs fromdos

स्पष्टीकरण:

  • git status --short

    यह प्रत्येक पंक्ति को दिखाता है कि git है और इसके बारे में पता नहीं है। ऐसी फाइलें जो git नियंत्रण में नहीं हैं, उन्हें लाइन की शुरुआत में '?' से चिह्नित किया जाता है। संशोधित की गई फ़ाइलें एक एम के साथ चिह्नित हैं।

  • grep "^ *M"

    यह केवल उन फ़ाइलों को फ़िल्टर करता है जिन्हें संशोधित किया गया है।

  • awk '{print $2}'

    यह बिना किसी मार्कर के केवल नाम दिखाता है।

  • xargs fromdos

    यह पिछले कमांड से फ़ाइल नाम लेता है और लाइन-एंडिंग्स को परिवर्तित करने के लिए उपयोगिता से 'डिडोस' के माध्यम से चलाता है।


यह कमाल का है। धन्यवाद। के dos2unixबजाय समाधान की तलाश में किसी के लिए Homebrew उपयोग की बजाय fromdos
अलमीर सरज़िक़ोव

4

यहां बताया गया है कि मैंने पूरे इतिहास में सभी लाइन एंडिंग का उपयोग करके कैसे तय किया git filter-branch^Mचरित्र का उपयोग कर दर्ज करना आवश्यक है CTRL-V+ CTRL-M। मैं dos2unixफ़ाइलों को कनवर्ट करता था क्योंकि यह स्वचालित रूप से बाइनरी फ़ाइलों को छोड़ देता है।

$ git filter-branch --tree-filter 'grep -IUrl "^M" | xargs -I {} dos2unix "{}"'


3

"। Xargs fromdos" मानक इनपुट (फ़ाइलें findपाता है) से पढ़ता है और इसे कमांड के तर्क के रूप में उपयोग करता है fromdos, जो लाइन एंडिंग को रूपांतरित करता है। (उन एनवायरमेंट्स में डिडोस मानक है? मुझे dos2unix का उपयोग किया जाता है)। ध्यान दें कि आप xargs के उपयोग से बच सकते हैं (विशेष रूप से उपयोगी यदि आपके पास पर्याप्त फ़ाइलें हैं जो तर्क सूची xargs के लिए बहुत लंबी है):

find <path, tests...> -exec fromdos '{}' \;

या

find <path, tests...> | while read file; do fromdos $file; done

मैं आपकी त्रुटि संदेशों के बारे में पूरी तरह सुनिश्चित नहीं हूं। मैंने इस पद्धति का सफलतापूर्वक परीक्षण किया। प्रत्येक किस कार्यक्रम का निर्माण कर रहा है? आपके पास कौन सी फाइलें / निर्देशिकाएं अनुमतियाँ नहीं हैं? हालाँकि, यह अनुमान लगाने में एक छुरा है कि आपका क्या हो सकता है:

स्क्रिप्ट के लिए 'फ़ाइल नहीं मिली' त्रुटि प्राप्त करने का एक आसान तरीका एक रिश्तेदार पथ का उपयोग करके है - एक पूर्ण का उपयोग करें। यदि आपने अपनी स्क्रिप्ट को निष्पादन योग्य (chmod + x) नहीं बनाया है, तो इसी तरह आपको एक अनुमति त्रुटि मिल सकती है।

टिप्पणी जोड़ें और मैं कोशिश करूँगा और आपको इसे पूरा करने में मदद करूँगा!


मुझे dos2unix के साथ एक और उदाहरण दिखाई दिया और मुझे लगा कि यह किसी तरह फ़ाइलों को उस नाम के फ़ोल्डर में कॉपी कर रहा है, लेकिन अब मुझे यह मिल गया है। वाह, अब स्पष्ट लगता है। आपकी सहायताके लिए धन्यवाद!
ब्रायन डोनह्यू

1

ठीक है ... साइबरविन के तहत हमारे पास डिडोस आसानी से उपलब्ध नहीं है, और यह अजूबी सबब आपके चेहरे पर उड़ जाता है यदि आपके पास संशोधित फ़ाइलों (जो हमारे पास) के लिए रास्तों में कोई स्थान है, तो मुझे ऐसा कुछ अलग तरीके से करना था:

git status --short | grep "^ *M" | sed 's/^ *M//' | xargs -n 1 dos2unix

इस समाधान के थोक के लिए @lloyd को यश


-2

यदि आपके लिए कोई अन्य उत्तर काम नहीं करता है, तो इन चरणों का पालन करें:

  1. यदि आप विंडोज पर हैं, तो करें git config --global core.autocrlf true ; यदि आप यूनिक्स पर हैं, तो करेंgit config core.autocrlf input
  2. Daud git rm --cached -r .
  3. फ़ाइल हटाएँ .gitattributes
  4. Daud git add -A
  5. Daud git reset --hard

तब आपका स्थानीय अब साफ होना चाहिए।


4
वास्तव में? .gitattributesफ़ाइल को डिलीट करना एंडिंग समस्या का समाधान है?
अलेक्सांद्र एम

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