git이 UTF-16 파일을 텍스트로 인식하도록 할 수 있습니까?


140

git에서 Virtual PC 가상 머신 파일 (* .vmc)을 추적하고 있으며 변경 git을 수행 한 후 파일을 이진 파일로 식별하여 diff하지 않습니다. 파일이 UTF-16으로 인코딩되었음을 발견했습니다.

git 에게이 파일이 텍스트임을 인식하고 적절하게 처리하도록 가르 칠 수 있습니까?

core.autocrlf가 false로 설정된 Cygwin에서 git을 사용하고 있습니다. 필요한 경우 UNIX에서 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 프로그램을 실행합니다 diff. 따라서 멀티 바이트 인식 diff (필자의 경우 vimdiff 모드)를 선택하고 git difftool대신 대신 사용하십시오 git diff.

"difftool"이 너무 길어서 입력 할 수 없습니까? 문제 없어요:

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

힘내 바위.


1
완벽한 해결책은 아니지만 (단순히 통합 된 diff를 가질 것입니다), 그러나 새로운 것을 설치할 선택과 내 의지가 주어지면 덜 악합니다. "vimdiff"입니다! (yea, vim ... and git)
Roboprog

1
UTF16 파일 덩어리 만 준비하고 커밋하는 데에도 효과가 있습니까?
Ortwin Gentz

내가 사용 너머 비교 은 diff와 병합 도구로. .gitconfig에서 <pre> <code> [difftool "bc3"] 경로 = c : / 프로그램 파일 (x86) / Beyond 비교 3 / bcomp.exe [mergetool "bc3"] 경로 = c : / 프로그램 파일 (x86) / 너머 비교 3 / bcomp.exe </ code> </ pre>
Tom Wilson

@Tom Wilson 4 개의 공백을 들여 써서 코드 블록을 포맷 할 수 없습니다!?
Tom Wilson

git에 대한 기본 지식이 있으며 파일 변경을 처리하는 방법을 모르겠습니다. 이것은 항상 이진 파일 또는 텍스트 (ASCII)로 변경 처리에 대한 특별한 처리 / 탐지가 있습니까?
i486

63

Unices에서 바로 사용할 수있는 매우 간단한 솔루션이 있습니다.

예를 들어 Apple의 .strings파일은 다음과 같습니다.

  1. 다음 .gitattributes을 사용하여 저장소 루트에 파일을 작성하십시오 .

    *.strings diff=localizablestrings
    
  2. ~/.gitconfig파일에 다음을 추가 하십시오.

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

출처 : Git (및 2010 년 이전 게시물 )의 Diff .strings 파일


나는 이것을했지만 git은 이것 이후에 달리기를 거부합니다. 내가 얻는 오류는 "/Users/myusername/.gitconfig의 잘못된 구성 파일 줄 4"입니다. "git config --global --edit"를 사용하여 gitconfig 파일을 열었습니다. 흥미롭게도 추가 된 줄을 제거하면 모두 잘 작동합니다. 단서가 있습니까?
shshnk

복사 / 붙여 넣기하면 스마트 따옴표를 추측 할 것입니다. 그 문제를 해결하기 위해 답을 편집했습니다.
Lou Franco

이것은 매력처럼 작동합니다. 단순성을 위해 그리고 더 나은 통합을 위해 허용되는 대답이어야합니다. "다른 도구 사용"이 어떻게 git이 UTF-16 파일을 텍스트로 인식하도록 할 수 있습니까?
itMaxence

@itMaxence 엄밀히 말하면, iconvVim이나 Beyond Compare와 같은 방식으로 "또 다른 툴"입니다 (git suite의 일부는 아님).
Agi Hammerthief

@AgiHammerthief 다시 읽은 후에는 내가 생각했던 것을 동의합니다. FWIW vimdiff하고 iconv어디를 얻는 방법 궁금 귀찮게 할 필요가 없습니다 모두 맥 OS에 이미 존재하는, 그들은 작업을 수행
itMaxence

39

.gitattributes텍스트 파일로 취급하도록 설정 했습니까 ?

예 :

*.vmc diff

자세한 내용은 http://www.git-scm.com/docs/gitattributes.html 에서 확인 하십시오 .


2
이것은 작동하지만 정확성을 위해 다음 두 가지 속성을 설정 합니다. setdiff...
OK.

2
이 솔루션은 나에게만 허용됩니다. @OK 코멘트 당으로, "세트"그냥 여기 무관 *.vmc diff, *.sql diff등 지정된 경로에 대한 'DIFF'속성을 설정하는 데 필요합니다. (답변을 편집 할 수 없습니다). 그러나 2 가지주의 사항 : 각 문자 사이에 공백이있는 diff가 표시되며 문제가있는 파일에 대해 "stage hunk"또는 "discard hunk"를 수행 할 수 없습니다.
Pac0

30

기본적 git으로 UTF-16에서는 잘 작동하지 않는 것 같습니다 . 이러한 파일을 사용자가 더 있는지 확인해야 CRLF처리가 그것을 수행되지 않습니다,하지만 당신이 원하는 diffmerge일반 텍스트 파일로 작업에 (이 터미널 / 편집기 UTF-16을 처리 할 수 있는지 여부를 무시).

그러나 .gitattributes맨 페이지를 보면 다음과 같은 사용자 정의 속성이 있습니다 binary.

[attr]binary -diff -crlf

당신이 당신의 톱 레벨의 사용자 지정 특성을 정의 할 수 있다는 것을 나에게 보인다 그래서 .gitattributes위해 utf16(나는 확실히 그것을 텍스트로 처리됩니다로 여기 병합을 추가하는 것이 주) :

[attr]utf16 diff merge -crlf

거기에서 .gitattributes다음과 같은 파일 을 지정할 수 있습니다 .

*.vmc utf16

또한 다음과 같이 바이너리라고 생각 diff하더라도 파일 을 계속 사용할 수 있어야합니다 git.

git diff --text

편집하다

이 답변은 기본적으로 UTF-16 또는 UTF-8의 GNU 차이점이 잘 작동하지 않는다고 말합니다. 를 git통해 다른 도구를 사용하여 차이점을보고 싶다면 Guiffy를--ext-diff 제안 합니다. 입니다.

그러나 diffASCII 문자 만 포함 된 UTF-16 파일 만 있으면됩니다. 그것을 작동시키는 방법 --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 diff를 사용하는 경우 GNU diff는 유니 코드를 인식하지 않는 것 같습니다.

GNU diff는 실제로 유니 코드를 신경 쓰지 않으므로 diff --text를 사용하면 텍스트를 diff하고 출력합니다. 문제는 사용중인 터미널이 방출 된 UTF-16 (ASCII 문자 인 diff 표시와 결합)을 처리 할 수 ​​없다는 것입니다.


이처럼 차이가 나면 이진 쓰레기가 화면에 뿌려집니다. git이 GNU diff를 사용하는 경우 GNU diff는 유니 코드를 인식하지 않는 것 같습니다.
skiphoppy 2009

1
GNU diff는 실제로 유니 코드를 신경 쓰지 않으므로 diff --text를 사용하면 텍스트를 diff하고 출력합니다. 문제는 사용중인 터미널이 방출 된 UTF-16 (ASCII 문자 인 diff 표시와 결합)을 처리 할 수 ​​없다는 것입니다.
Jared Oberhaus

@ jared-oberhaus-특정 유형의 파일 (예 : 특정 확장자)에 대해서만이 스크립트를 트리거하는 방법이 있습니까?
Terry

8

해결책은를 통해 필터링하는 것 cmd.exe /c "type %1"입니다. cmdtype 내장 기능은 변환을 수행하므로 git diff의 textconv 기능을 사용하여 UTF-16 파일의 텍스트 디핑을 활성화 할 수 있습니다 (테스트되지 않았지만 UTF-8에서도 작동해야 함).

gitattributes 매뉴얼 페이지에서 인용 :


이진 파일의 텍스트 차이 수행

때때로 일부 바이너리 파일의 텍스트 변환 버전의 차이점을 보는 것이 바람직합니다. 예를 들어, 워드 프로세서 문서는 ASCII 텍스트 표현과 텍스트의 diff로 변환 될 수 있습니다. 이 변환에서 일부 정보가 손실 되더라도 diff는 사람이 보는 데 유용하지만 직접 적용 할 수는 없습니다.

textconv 구성 옵션은 이러한 변환을 수행하기위한 프로그램을 정의하는 데 사용됩니다. 프로그램은 변환 할 파일 이름 인 단일 인수를 가져 와서 stdout에서 결과 텍스트를 생성해야합니다.

예를 들어, 2 진 정보 대신 파일의 EXIF ​​정보의 차이를 표시하려면 (exif 도구가 설치되어 있다고 가정) $GIT_DIR/config파일 (또는 $HOME/.gitconfig파일)에 다음 섹션을 추가하십시오 .

[diff "jpg"]
        textconv = exif

mingw32를위한 솔루션 , cygwin 팬을 은 접근 방식을 변경해야 할 수도 있습니다. 문제는 파일 이름을 전달하여 cmd.exe로 변환하는 것입니다. 슬래시를 사용하고 cmd는 백 슬래시 디렉토리 구분 기호를 사용합니다.

1 단계:

stdout으로 변환 할 단일 인수 스크립트를 작성하십시오. c : \ 경로 \ to \ some \ script.sh :

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

2 단계:

스크립트 파일을 사용할 수 있도록 git을 설정하십시오. 당신의 자식 설정 (내부 ~/.gitconfig또는 .git/config또는 참조 man git-config),이를 넣어 :

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

3 단계 :

.gitattributes 파일을 사용하여이 workarond를 적용 할 파일을 지정하십시오 (man gitattributes (5) 참조).

*vmc diff=cmdtype

그런 다음 git diff파일에서 사용 하십시오.


거의 토니 Kuneck의 그러나 "C : /path/to/some/script.sh"없이 entropy.ch/blog/Developer/2010/04/15/...
알렉세이 Shumkin

Windows 용 Git에서 위에 표시된대로 스크립트에 문제가 있지만 다음은 문제가없고 경로의 공백도 처리 할 수 ​​있다는 것을 알았습니다 cmd //c type "${1//\//\\}" .
patthoyts

이것은 스크립트 파일을 만들 필요없이 작동합니다 :textconv = powershell -NoProfile -Command \"& {Get-Content \\$args[0]}\"
Jakub Berezanski

5

git은 최근 utf16과 같은 인코딩을 이해하기 시작했습니다. gitattributes 참조 검색, 문서를working-tree-encoding

[이것은 매우 새롭기 때문에 맨 페이지가 일치하는지 확인하십시오!]

파일이 Windows 시스템에서 BOM이없는 UTF-16 인 경우 파일에 추가 .gitattributes하십시오

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

* nix에서 UTF-16 (bom 포함)으로 만들면 :

*.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
  • 자세한 정보 — 대형 프로젝트는 수십 가지의 다른 텍스트 파일 형식을 쉽게 가질 수 있습니다.

문제

힘내는 매크로 속성 binary 을 의미 -text -diff합니다. 반대+text +diff 는 내장되어 있지 않지만 git은 그것을 합성하기위한 도구 (생각합니다!)를 제공합니다

해결책

힘내 새 매크로 속성을 정의 할 수 있습니다.

나는 .gitattributes당신이 가진 파일의 상단을 제안합니다

 [attr]textfile text diff

그런 다음 텍스트 및 diff가되어야하는 모든 경로에 대해

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

대부분의 경우 기본 인코딩 (utf-8)과 기본 eol (기본)을 원하므로 삭제 될 수 있습니다.

대부분의 줄은

textfile *.c
textfile *.py
Etc

왜 diff를 사용하지 않습니까?

실용적 : 대부분의 경우 네이티브 eol을 원합니다. 아니야 eol=.... 따라서 text암시되지 않으며 명시 적으로 넣어야합니다.

개념 : Text Vs 바이너리는 근본적인 차이점입니다. eol, encoding, diff 등은 그중 일부입니다.

부인 성명

우리가 살고있는 기괴한 시간으로 인해 현재 작동중인 자식이있는 기계가 없습니다. 따라서 현재 최신 추가 사항을 확인할 수 없습니다. 누군가가 잘못된 것을 발견하면, 나는 제거 / 제거 할 것입니다.


UTF-16LE-BOM 파일을 작동 시키려면 사용해야했습니다*.vmc diff working-tree-encoding=UTF-16LE-BOM eol=CRLF
HackSlash

@HackSlash : 고마워요. 나는 당신이 text혼자서 좋은 텍스트 차이를 얻지 못했다고 말하는 것 같아요 ? 둘 다 확인 text하고 diff모든 것이 잘 작동하는지 확인해 주 시겠습니까? 어떤 경우에는 다른 추천을 할 것입니다
Rusi

수정, text이진 만 결과를 비교한다. 내가 할 수있는 diff또는 text diff그것을 작동합니다. -BOM파일에 BOM YMMV가 있으므로 간단히 추가 해야했습니다.
HackSlash

@HackSlash 나는 당신의 발견을 통합했습니다. 당신이 그것을 확인할 수 있다면 좋을 것입니다!
Rusi

@Rusi에게 감사합니다.
HackSlash

4

작은 git-diff 드라이버 to-utf8를 작성했습니다. 이는 ASCII가 아닌 / UTF-8 인코딩 파일을 쉽게 구분할 수있게합니다. https://github.com/chaitanyagupta/gitutils#to-utf8 의 지침을 사용하여 설치할 수 있습니다 (to-utf8 스크립트는 동일한 리포지토리에서 사용 가능).

이 스크립트를 사용하려면 시스템에서 fileiconv명령을 모두 사용할 수 있어야합니다.


2

Windows 에서이 문제가 최근에 있었고 Windows 용 git과 함께 제공 되는 dos2unixunix2dosbin이 트릭을 수행했습니다. 기본적으로는에 있습니다 C:\Program Files\Git\usr\bin\. 파일 UTF-16 일 필요 가없는 경우에만 작동합니다 . 예를 들어 누군가 실수로 파이썬 파일을 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...
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.