我可以让git将UTF-16文件识别为文本吗?

我可以让git将UTF-16文件识别为文本吗?,git,unicode,character-encoding,diff,utf-16,Git,Unicode,Character Encoding,Diff,Utf 16,我正在跟踪git中的一个虚拟PC虚拟机文件(*.vmc),在进行更改后,git将该文件标识为二进制文件,不会为我区分。我发现这个文件是用UTF-16编码的 git可以被教导识别这个文件是文本并适当地处理它吗 我在Cygwin下使用git,core.autocrlf设置为false。如果有必要,我可以在UNIX下使用mSysGit或git。默认情况下,git似乎无法与UTF-16配合使用;对于这样的文件,您必须确保不对其进行CRLF处理,但您希望diff和merge作为普通文本文件工作(这将忽略您

我正在跟踪git中的一个虚拟PC虚拟机文件(*.vmc),在进行更改后,git将该文件标识为二进制文件,不会为我区分。我发现这个文件是用UTF-16编码的

git可以被教导识别这个文件是文本并适当地处理它吗


我在Cygwin下使用git,core.autocrlf设置为false。如果有必要,我可以在UNIX下使用mSysGit或git。

默认情况下,
git
似乎无法与UTF-16配合使用;对于这样的文件,您必须确保不对其进行
CRLF
处理,但您希望
diff
merge
作为普通文本文件工作(这将忽略您的终端/编辑器是否可以处理UTF-16)

但是看看,这里有一个自定义属性,它是二进制的:

[attr]binary -diff -crlf
因此,在我看来,您可以在顶级
.gittattributes
中为
utf16
定义一个自定义属性(注意,我在这里添加了merge,以确保它被视为文本):

从那里,您可以在任何
.gittributes
文件中指定如下内容:

*.vmc utf16
还要注意的是,即使
git
认为它是二进制文件,您仍然应该能够使用:

git diff --text
编辑

基本上说,GNU diff与UTF-16甚至UTF-8的工作不太好。如果您想让git使用不同的工具查看差异(通过
--ext diff
),答案是这样的

但您可能需要的只是
diff
一个只包含ASCII字符的UTF-16文件。使其工作的一种方法是使用
--ext diff
和以下shell脚本:

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

diff您是否尝试将
.gittributes
设置为文本文件

e、 g:


有关详细信息,请参见。

解决方案是通过
cmd.exe/c“type%1”进行筛选。
。cmd的
类型
内置将进行转换,因此您可以使用git diff的textconv功能来启用UTF-16文件的文本差异(虽然未经测试,但也应与UTF-8一起使用)

引用gitattributes手册页:


执行二进制文件的文本差异 有时需要查看一些二进制文件的文本转换版本的差异。例如,可以将字处理器文档转换为ASCII文本表示形式,并显示文本的差异。尽管此转换会丢失一些信息,但生成的差异对于人类查看很有用(但不能直接应用)

textconv config选项用于定义用于执行此类转换的程序。程序应该使用一个参数,即要转换的文件名,并在stdout上生成结果文本

例如,要显示文件的exif信息而不是二进制信息的差异(假设已安装exif工具),请将以下部分添加到
$GIT_DIR/config
文件(或
$HOME/.gitconfig
文件)中:


对于mingw32,cygwin粉丝可能需要改变方法。问题在于传递文件名以转换为cmd.exe-它将使用正斜杠,cmd使用反斜杠目录分隔符

步骤1: 创建将转换为标准输出的单参数脚本。c:\path\to\some\script.sh:

#!/bin/bash
SED='s/\//\\\\\\\\/g'
FILE=\`echo $1 | sed -e "$SED"\`
cmd.exe /c "type $FILE"
步骤2: 将git设置为能够使用脚本文件。在git配置(
~/.gitconfig
.git/config
或参见
man git config
)中,放置以下内容:

[diff "cmdtype"]
textconv = c:/path/to/some/script.sh
步骤3: 通过使用.gittributes文件指出要应用此解决方法的文件(请参阅man gittributes(5)):


然后在您的文件上使用
git diff

我已经为这个问题挣扎了一段时间,刚刚发现(对我来说)一个完美的解决方案:

$ git config --global diff.tool vimdiff      # or merge.tool to get merging too!
$ git difftool commit1 commit2
git difftool
采用与
git diff
相同的参数,但运行您选择的diff程序,而不是内置的GNU
diff
。因此,选择一个多字节感知的diff(在我的例子中,diff模式下是
vim
),只需使用
git difftool
而不是
git diff

是否发现“difftool”太长而无法键入?没问题:

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

Git rocks。

我已经编写了一个小型Git diff驱动程序,
to-utf8
,它应该可以很容易地区分任何非ASCII/UTF-8编码的文件。您可以按照此处的说明进行安装:(同一个repo中提供了
to-utf8
脚本)


请注意,此脚本要求系统上同时提供
文件
iconv
命令。

有一个非常简单的解决方案,可以在Unices上开箱即用

例如,对于Apple的
.strings
文件,只需:

  • 使用以下内容在存储库的根目录中创建
    .gittributes
    文件:

     *.strings diff=localizablestrings
    
  • 将以下内容添加到
    ~/.gitconfig
    文件中:

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

  • 来源:(从2010年开始)。

    最近在Windows上出现了这个问题,git for Windows附带的
    dos2unix
    unix2dos
    垃圾箱解决了这个问题。默认情况下,它们位于
    C:\ProgramFiles\Git\usr\bin\
    请注意,只有当您的文件不需要UTF-16时,此选项才有效。例如,有人意外地将一个python文件编码为UTF-16,而该文件不需要UTF-16(在我的例子中)


    git最近开始理解utf16等编码。 请参阅文档,搜索
    工作树编码

    [确保您的手册页匹配,因为这是全新的!]

    如果(比如)文件是UTF-16,在Windows机器上没有BOM表,则添加到
    .gittributes
    文件中

    *.vmc text working-tree-encoding=UTF-16LE eol=CRLF
    
    如果UTF-16(带bom)开启*nix,则进行以下操作:

    *.vmc text working-tree-encoding=UTF-16-BOM eol=LF
    
    (将
    *.vmc
    替换为
    *.which
    ,用于
    任何需要处理的类型文件)

    请参阅:


    后来添加 在@Hackslash之后,你可能会发现
     [diff "localizablestrings"]
     textconv = "iconv -f utf-16 -t utf-8"
    
    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...
    
    *.vmc text working-tree-encoding=UTF-16LE eol=CRLF
    
    *.vmc text working-tree-encoding=UTF-16-BOM eol=LF
    
     *.vmc text working-tree... 
    
     *.vmc diff working-tree...
    
     *.vmc text diff working-tree... 
    
     [attr]textfile text diff
    
     path textfile working-tree-encoding= eol=...
    
    *.c textfile
    *.py textfile
    Etc
    
     *.uni diff=utf16
    
    [diff=utf16]
        textconv = "iconv -f utf-16 -t utf-8"