क्या मैं एक UTF-16 फ़ाइल को टेक्स्ट के रूप में पहचान सकता हूँ?


140

मैं एक वर्चुअल पीसी वर्चुअल मशीन फ़ाइल (* .vmc) को git में ट्रैक कर रहा हूं, और एक बदलाव के बाद फ़ाइल को बाइनरी के रूप में पहचाना और मेरे लिए इसे अलग नहीं करेगा। मुझे पता चला कि फ़ाइल UTF-16 में एन्कोड की गई थी।

क्या यह सिखाया जा सकता है कि यह फ़ाइल पाठ है और इसे उचित तरीके से संभालना है?

मैं Cygwin के तहत git का उपयोग कर रहा हूं, जिसके साथ core.autocrlf झूठा सेट है। यदि आवश्यक हो तो मैं UNS के तहत mSysGit या git का उपयोग कर सकता हूं।

जवाबों:


83

मैं थोड़ी देर के लिए इस समस्या से जूझ रहा था, और बस (मेरे लिए) एक सही समाधान खोजा:

$ git config --global diff.tool vimdiff      # or merge.tool to get merging too!
$ git difftool commit1 commit2

git difftoolके रूप में एक ही तर्क लेता है git diff, लेकिन निर्मित GNU के बजाय अपनी पसंद का एक अलग कार्यक्रम चलाता है diff। इसलिए एक मल्टीबाइट-अवेयर फ़र्क (मेरे मामले में, vimफ़्री मोड में) चुनें और git difftoolइसके बजाय केवल उपयोग करें git diff

टाइप करने के लिए "difftool" बहुत लंबा है? कोई दिक्कत नहीं है:

$ git config --global alias.dt difftool
$ git dt commit1 commit2

गिट्टियां मारना।


1
एक सही समाधान नहीं है (बल्कि एक स्क्रॉल एकीकृत रूप होगा), लेकिन, यह कम बुराई है जो विकल्पों और मेरी अनिच्छा को देखते हुए स्थापित करने के लिए कुछ नया खोजने के लिए है। "vimdiff", यह है! (yea, vim ... और git)
Roboprog

1
क्या यह UTF16 फ़ाइलों के केवल चांस को स्टेज और कमिट करने के लिए भी काम करता है?
ऑर्टविन गेंट्ज़

मैं एक अलग और मर्ज टूल के रूप में बियॉन्ड तुलना का उपयोग करता हूं । .Itconfig <pre> <code> से 3 / bcomp.exe से परे </ code> </ pre>
टॉम विल्सन

@Tom विल्सन 4 रिक्त स्थान इंडेंट करके कोड ब्लॉक को प्रारूपित करने में असमर्थ है !?
टॉम विल्सन

मुझे गिट के लिए बुनियादी ज्ञान है और यह सुनिश्चित नहीं है कि यह फ़ाइल परिवर्तनों को कैसे संभालता है। क्या यह हमेशा बाइनरी फाइलों के रूप में है या पाठ (एएससीआईआई) के लिए विशेष प्रसंस्करण / परिवर्तनों का पता लगाना है?
--६

63

एक बहुत ही सरल उपाय है जो यूनिटीज़ पर बॉक्स से बाहर काम करता है।

उदाहरण के लिए, Apple की .stringsफ़ाइलों के साथ :

  1. .gitattributesअपनी रिपॉजिटरी के मूल में एक फ़ाइल बनाएँ :

    *.strings diff=localizablestrings
    
  2. अपनी ~/.gitconfigफ़ाइल में निम्न जोड़ें :

    [diff "localizablestrings"]
    textconv = "iconv -f utf-16 -t utf-8"
    

स्रोत: डिफिट .strings फ़ाइलें गिट में (और 2010 से पुरानी पोस्ट )।


मैंने ऐसा किया था, लेकिन इसके बाद चलाने के लिए मना कर दिया। मुझे जो त्रुटि मिली है, वह है "खराब कॉन्फिग फाइल लाइन 4 इन / यूजर्स/myusername/.gitconfig"। मैंने अपनी gitconfig फ़ाइल को खोलने के लिए "git config --global --edit" का उपयोग किया। दिलचस्प बात यह है कि अगर मैं जोड़ा लाइनों को हटा दें तो सभी ठीक काम करता है। कोई सुराग?
shshnk

यदि आप कॉपी / पेस्ट करते हैं तो मैं स्मार्ट उद्धरणों का अनुमान लगाने जा रहा हूं। मैंने उसे ठीक करने के लिए उत्तर संपादित किया।
लू फ्रेंको

यह एक आकर्षण की तरह काम करता है, यह सादगी के लिए और बेहतर एकीकरण के लिए स्वीकृत उत्तर होना चाहिए। मैं यह नहीं देखता कि "किसी अन्य टूल का उपयोग कैसे करें" इसका उत्तर "क्या मैं टेक्स्ट के रूप में UTF-16 फ़ाइल को पहचान सकता हूं?"
itMaxence

@itMaxence स्ट्रिक्टली, iconvवीम या बियॉन्ड तुलना की तरह ही "एक और टूल" है (गिट सूट का हिस्सा नहीं)।
एजी हैमर्थीफ़

@ एगी हम्मेन्थिफ़ यकीन है कि फिर से पढ़ने के बाद मैं सहमत हूँ, पता नहीं मैं क्या सोच रहा था। FWIW vimdiffऔर iconvदोनों पहले से ही macOS पर मौजूद हैं, इसलिए आपको यह सोचकर परेशान होने की जरूरत नहीं है कि उन्हें कहां मिलेगा, और वे काम करते हैं
itaxaxence

39

क्या आपने .gitattributesइसे एक पाठ फ़ाइल के रूप में मानने की कोशिश की है ?

उदाहरण के लिए:

*.vmc diff

Http://www.git-scm.com/docs/gitattributes.html पर अधिक जानकारी ।


2
यह काम करता है, लेकिन शुद्धता के लिए कृपया ध्यान रखें कि यह दो विशेषताएँ निर्धारित करता है: setऔर diff...
ठीक है।

2
यह समाधान मेरे लिए एकमात्र स्वीकार्य है। @OK टिप्पणी के अनुसार, "सेट" यहां अप्रासंगिक है, बस *.vmc diff, *.sql diffआदि .. निर्दिष्ट पथ के लिए 'अंतर' विशेषता सेट करने के लिए आवश्यक है। (मैं उत्तर को संपादित नहीं कर सकता)। हालाँकि, 2 कैविएट: प्रत्येक चरित्र के बीच एक स्थान के साथ अंतर दिखाए जाते हैं, और उन समस्याग्रस्त फ़ाइलों के लिए "स्टेज हंक" या "हंक को त्यागना" संभव नहीं है।
Pac0

30

डिफ़ॉल्ट रूप से, ऐसा लगता है कि gitUTF-16 के साथ अच्छा काम नहीं करेगा; ऐसी फ़ाइल के लिए आपको यह सुनिश्चित करना होगा कि उस पर कोई CRLFप्रसंस्करण नहीं किया गया है, लेकिन आप चाहते हैं diffऔर mergeएक सामान्य पाठ फ़ाइल के रूप में काम करना है (यह अनदेखा कर रहा है कि आपका टर्मिनल / संपादक UTF-16 को संभाल सकता है या नहीं)।

लेकिन .gitattributesमैनपेज को देखते हुए , यहाँ कस्टम विशेषता है binary:

[attr]binary -diff -crlf

तो मुझे लगता है कि आप अपने शीर्ष स्तर में कस्टम विशेषता निर्धारित कर सकते हैं .gitattributesके लिए utf16(ध्यान दें कि मैं यहाँ मर्ज जोड़ने यकीन है कि यह पाठ के रूप में व्यवहार किया जाता है होना करने के लिए):

[attr]utf16 diff merge -crlf

वहां से आप किसी भी .gitattributesफ़ाइल में कुछ निर्दिष्ट कर सकेंगे :

*.vmc utf16

यह भी ध्यान दें कि आपको अभी भी diffएक फाइल करने में सक्षम होना चाहिए , भले ही आपको gitलगता है कि यह द्विआधारी है:

git diff --text

संपादित करें

यह उत्तर मूल रूप से कहता है कि GNU में wth UTF-16 या UTF-8 बहुत अच्छी तरह से काम नहीं करता है। यदि आप gitमतभेदों को देखने के लिए एक अलग उपकरण का उपयोग करना चाहते हैं (के माध्यम से --ext-diff), तो वह जवाब गुइफी का सुझाव देता है ।

लेकिन जिस चीज की आपको जरूरत है वह सिर्फ diffUTF-16 फाइल में है जिसमें केवल ASCII अक्षर हैं। एक तरीका है कि काम करने के लिए उपयोग करने के लिए --ext-diffऔर निम्नलिखित खोल स्क्रिप्ट है:

#!/bin/bash
diff <(iconv -f utf-16 -t utf-8 "$1") <(iconv -f utf-16 -t utf-8 "$2")

ध्यान दें कि UTF-8 में रूपांतरित करने का काम हो सकता है, साथ ही आपको यह सुनिश्चित करना होगा कि यह दोनों दिशाओं में हो।

UTF-16 फ़ाइल का एक अलग रूप देखने पर टर्मिनल के आउटपुट के लिए:

स्क्रीन पर उगल दिए गए द्विआधारी कचरे के परिणाम के समान होने की कोशिश करना। अगर git GNU डिफरेंशियल का उपयोग कर रहा है, तो ऐसा लगेगा कि GNU डिस्कोड यूनिकोड-अवेयर नहीं है।

GNU diff वास्तव में यूनिकोड के बारे में परवाह नहीं करता है, इसलिए जब आप diff का उपयोग करते हैं - तो यह सिर्फ भिन्न होता है और पाठ को आउटपुट करता है। समस्या यह है कि आप जिस टर्मिनल का उपयोग कर रहे हैं वह UTF-16 को उत्सर्जित नहीं कर सकता है (ASCII वर्णों के साथ भिन्न चिह्नों के साथ संयुक्त)।


स्क्रीन पर उगल दिए गए द्विआधारी कचरे के परिणाम के समान होने की कोशिश करना। अगर git GNU डिफरेंशियल का उपयोग कर रहा है, तो ऐसा लगेगा कि GNU डिफरेंशियल यूनिकोड-अवेयर नहीं है।
स्किप्पॉपी

1
GNU diff वास्तव में यूनिकोड के बारे में परवाह नहीं करता है, इसलिए जब आप diff का उपयोग करते हैं - तो यह सिर्फ भिन्न होता है और पाठ को आउटपुट करता है। समस्या यह है कि आप जिस टर्मिनल का उपयोग कर रहे हैं वह UTF-16 को उत्सर्जित नहीं कर सकता है (ASCII वर्णों के साथ भिन्न चिह्नों के साथ संयुक्त)।
जेरेड ओबरहॉस

@ jared-oberhaus - क्या इस स्क्रिप्ट को केवल कुछ प्रकार की फ़ाइलों के लिए ट्रिगर करने का एक तरीका है (यानी कुछ एक्सटेंशन दिया गया है)?
टेरी

8

समाधान के माध्यम से फ़िल्टर करना है cmd.exe /c "type %1"। cmd की typeबिल्डिन रूपांतरण करेगी, और इसलिए आप इसका उपयोग कर सकते हैं कि पाठ की क्षमता के साथ-साथ UTF-16 फ़ाइलों के पाठ को अलग करने में सक्षम होना चाहिए (UTF-8 के साथ काम करना चाहिए, हालांकि अप्रयुक्त)।

Gitattributes मैन पेज से उद्धरण:


पाठ प्रदर्शन बाइनरी फ़ाइलों के भिन्न होते हैं

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

Textconv config विकल्प इस तरह के रूपांतरण के लिए एक कार्यक्रम को परिभाषित करने के लिए प्रयोग किया जाता है। कार्यक्रम को एक तर्क, रूपांतरण के लिए एक फ़ाइल का नाम और स्टडआउट पर परिणामी पाठ का उत्पादन करना चाहिए।

उदाहरण के लिए, बाइनरी जानकारी के बजाय किसी फ़ाइल की exif जानकारी के अंतर को दिखाने के लिए (मान लें कि आपके पास exif टूल स्थापित है), निम्न अनुभाग को अपनी $GIT_DIR/configफ़ाइल (या $HOME/.gitconfigफ़ाइल) में जोड़ें:

[diff "jpg"]
        textconv = exif

Mingw32 , cygwin प्रशंसकों के लिए एक समाधान के लिए दृष्टिकोण को बदलना पड़ सकता है। समस्या cmd.exe में कनवर्ट करने के लिए फ़ाइल नाम को पारित करने के साथ है - यह आगे के स्लैश का उपयोग करेगा, और cmd बैकस्लैश निर्देशिका विभाजकों को मानता है।

चरण 1:

एकल तर्क स्क्रिप्ट बनाएँ जो stdout में रूपांतरण करेगा। c: \ पथ \ to \ कुछ \ script.sh:

#!/bin/bash
SED='s/\//\\\\\\\\/g'
FILE=\`echo $1 | sed -e "$SED"\`
cmd.exe /c "type $FILE"

चरण 2:

स्क्रिप्ट फ़ाइल का उपयोग करने में सक्षम होने के लिए सेट अप करें। अपना Git config (अंदर ~/.gitconfigया .git/configया देखने man git-config), इस डाल:

[diff "cmdtype"]
textconv = c:/path/to/some/script.sh

चरण 3:

इस वर्कआॅर्ड को लागू करने के लिए फ़ाइलों को इंगित करें। .itattributes फ़ाइलों का उपयोग करके (देखें मानव गिटिटेज (5) देखें):

*vmc diff=cmdtype

फिर git diffअपनी फ़ाइलों पर उपयोग करें।


लगभग टोनी कुनेक के बिना लेकिन "c: /path/to/some/script.sh" entropy.ch/blog/Developer/2010/04/15/…
एलेक्सी शुम्किन

मैं के रूप में विंडोज के लिए Git के साथ ऊपर दिखाए गए लेकिन मैंने पाया निम्नलिखित रास्ते में रिक्त स्थान के साथ सौदा कर सकते हैं ठीक है और यह भी स्क्रिप्ट के साथ कुछ समस्या है: cmd //c type "${1//\//\\}"
patthoyts

यह एक स्क्रिप्ट फ़ाइल बनाने की आवश्यकता के बिना काम करेगा:textconv = powershell -NoProfile -Command \"& {Get-Content \\$args[0]}\"
जकुब बेरेज़ांस्की

5

git ने हाल ही में utf16 जैसे एनकोडिंग्स को समझना शुरू किया है। Gitattributes डॉक्स देखें , खोजेंworking-tree-encoding

[सुनिश्चित करें कि आपका आदमी पृष्ठ मेल खाता है क्योंकि यह काफी नया है!]

अगर (कहते हैं) फ़ाइल बिना किसी मशीन के यूटीएफ -16 विंडोज मशीन पर है तो अपनी .gitattributesफाइल में जोड़ें

*.vmc text working-tree-encoding=UTF-16LE eol=CRLF

यदि यूटीएफ -16 (बम के साथ) पर * निक्स बनाते हैं:

*.vmc text working-tree-encoding=UTF-16-BOM eol=LF

(बदलें *.vmcसाथ *.whateverके लिए whateverप्रकार फ़ाइलों को आप संभाल करने की जरूरत है)

देखें: वर्किंग-ट्री-एन्कोडिंग "UTF-16LE-BOM" का समर्थन करें


बाद में जोड़ा गया

@Hackslash के बाद, कोई पा सकता है कि यह अपर्याप्त है

 *.vmc text working-tree... 

अच्छा टेक्स्ट-डिफरेंस पाने के लिए आपको जरूरत है

 *.vmc diff working-tree...

दोनों को मिलाकर काम करना

 *.vmc text diff working-tree... 

लेकिन यकीनन है

  • निरर्थक - eol=...तात्पर्य हैtext
  • Verbose - एक बड़ी परियोजना में आसानी से दर्जनों विभिन्न पाठ फ़ाइल प्रकार हो सकते हैं

समस्या

Git में एक मैक्रो-विशेषता है binary जिसका अर्थ है -text -diff। विपरीत +text +diffउपलब्ध नहीं है, लेकिन गिट इसे संश्लेषित करने के लिए उपकरण (मुझे लगता है!) देता है

समाधान

Git नई मैक्रो विशेषताओं को परिभाषित करने की अनुमति देता है।

मुझे लगता है कि .gitattributesआपके पास उस फ़ाइल का शीर्ष प्रस्ताव होगा

 [attr]textfile text diff

फिर उन सभी रास्तों के लिए जिन्हें पाठ और अलग करना आवश्यक है

 path textfile working-tree-encoding= eol=...

ध्यान दें कि ज्यादातर मामलों में हम डिफ़ॉल्ट एन्कोडिंग (utf-8) और डिफ़ॉल्ट eol (देशी) चाहते हैं और इसलिए इसे गिराया जा सकता है।

ज्यादातर लाइनों की तरह दिखना चाहिए

textfile *.c
textfile *.py
Etc

सिर्फ अंतर का उपयोग क्यों नहीं?

व्यावहारिक: ज्यादातर मामलों में हम देशी ईओएल चाहते हैं। जिसका अर्थ है नहीं eol=...। तो textनिहित नहीं होगा और स्पष्ट रूप से रखा जाना चाहिए।

वैचारिक: पाठ बनाम द्विआधारी मौलिक भेद है। eol, एन्कोडिंग, फ़र्क आदि इसके कुछ पहलू हैं।

अस्वीकरण

विचित्र समय के कारण हम जिस जीवन में रह रहे हैं, उसमें वर्तमान कार्य के साथ मशीन नहीं है। इसलिए मैं नवीनतम जोड़ की जांच करने में फिलहाल असमर्थ हूं। अगर किसी को कुछ गलत लगता है, तो मैं उसे हटा / हटा दूँगा।


काम करने के लिए मेरी UTF-16LE-BOM फ़ाइल प्राप्त करने के लिए मुझे उपयोग करना पड़ा*.vmc diff working-tree-encoding=UTF-16LE-BOM eol=CRLF
HackSlash

@HackSlash: हेड-अप के लिए धन्यवाद। मुझे लगता है कि आप textअकेले कह रहे हैं कि आपको अच्छा टेक्स्ट डिफरेंस नहीं मिला है? क्या आप कृपया जाँच सकते हैं कि दोनों text और diffसब कुछ ठीक है? किस मामले में मैं एक अलग सिफारिश करूंगा
रुसी

सही, textबाइनरी में अकेले परिणाम की तुलना। मैं कर सकता हूँ diffया text diffयह काम करता है। मुझे -BOMबस इसलिए जोड़ना पड़ा क्योंकि मेरी फ़ाइल में BOM, YMMV था।
हैकलैश

@HackSlash मैंने आपकी खोज को शामिल कर लिया है। यह बहुत अच्छा होगा यदि आप इसे देख सकते हैं!
रुसी

धन्यवाद @ रूसी, मुझे समझ में आता है।
HackSlash

4

मैंने एक छोटा गिट-डिफ-ड्राइवर लिखा है to-utf8, जो कि किसी भी गैर-एएससीआईआई / यूटीएफ -8 एन्कोडिंग फ़ाइलों को अलग करना आसान बना सकता है। आप इसे यहां दिए गए निर्देशों का उपयोग करके स्थापित कर सकते हैं: https://github.com/chaitanyagupta/gitutils#to-utf8 ( to-utf8स्क्रिप्ट एक ही रेपो में उपलब्ध है)।

ध्यान दें कि इस स्क्रिप्ट को सिस्टम पर उपलब्ध होने के लिए दोनों fileऔर iconvकमांड की आवश्यकता होती है।


2

हाल ही में Windows पर इस समस्या थी, और dos2unixऔर unix2dosडिब्बे कि विंडोज़ के लिए Git के साथ जहाज चाल किया था। डिफ़ॉल्ट रूप से वे अंदर स्थित हैं C:\Program Files\Git\usr\bin\इसका निरीक्षण केवल तभी करें जब आपकी फ़ाइल को UTF-16 की आवश्यकता हो। उदाहरण के लिए, किसी ने अचानक एक python फ़ाइल को UTF-16 के रूप में एन्कोड कर दिया जब उसे (मेरे मामले में) होने की आवश्यकता नहीं थी।

PS C:\Users\xxx> dos2unix my_file.py
dos2unix: converting UTF-16LE file my_file.py to ANSI_X3.4-1968 Unix format...

तथा

PS C:\Users\xxx> unix2dos my_file.py
unix2dos: converting UTF-16LE file my_file.py to ANSI_X3.4-1968 DOS format...
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.