无法使用iconv和utf-16来玩得很好

时间:2016-06-04 16:16:56

标签: git utf-16 msysgit iconv

我试图让git将UTF-16识别为文本,以允许我本地区分和修补文本,但是我无法使textconv参数生效。< / p>

我可以手动拨打

iconv -f utf-16 -t utf-8 some-utf-16-file.rc

一切都很好。但是,如果我按如下方式配置我的.gitconfig

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

和我的.gitattributes:

# Custom for MFC
*.rc text eol=crlf diff=utf16

但是,如果我运行git diff,则会显示以下内容:

iconv: C:/Users/Mahmoud/AppData/Local/Temp/IjLBZ8_OemKey.rc:104:1: incomplete character or shift sequence

使用procmon,我可以在创建此过程时将其跟踪:

sh -c "iconv.exe -f utf-16le -t utf-8 \"$@\"" "iconv.exe -f utf-16le -t utf-8" C:/Users/Mahmoud/AppData/Local/Temp/JLOkVa_OemKey.rc

...我实际上可以正常运行(但在实际文件中)。

有什么想法吗?

(请注意,我已经了解了让git与UTF-16一起使用的各种解决方案。我特别试图解决为什么iconv本身有效的问题但是当它无法工作时由git调用。此外,这个错误最初是在尝试复制&#34;问题中的一个链接解决方案时遇到的。谢谢大家。)

3 个答案:

答案 0 :(得分:2)

仅使用diff,它应该有效:

*.rc diff=utf16

texteol会导致git在将数据传递给iconv之前替换行尾,之后它不再是有效的utf16,如noted in comments

答案 1 :(得分:1)

git最近已经开始理解编码,即实际上iconv在某种程度上已经内置。查看gitattributes文档,搜索working-tree-encoding

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

如果(说)该文件是Windows计算机上没有bom的utf-16,则将其添加到您的gitattributes文件中

some-utf-16-file.rc text working-tree-encoding=UTF-16LE eol=CRLF

如果在* nix上使用utf-16 little endinan(with bom)制作

some-utf-16-file.rc text working-tree-encoding=UTF-16 eol=LF

答案 2 :(得分:1)

Git 2.21(2019年2月)添加了新的编码 UTF-16LE-BOM :被发明为使用小尾数字节顺序将BOM强制编码为UTF-16,该编码不能通过使用来直接生成query string

请参见commit aab2a1aTorsten Bögershausen (tboegi)(2019年1月30日)。
(由Junio C Hamano -- gitster --commit 0fa3cc7中合并,2019年2月7日)

  

支持工作树编码“ UTF-16LE-BOM”

     

想要在工作树中使用UTF-16文件的用户可以这样设置iconv

.gitattributes
     

unicode标准本身定义了3种允许的UTF-16编码方式。   以下3个版本在UTF-8中将其全部转换回'g''i''t':

test.txt working-tree-encoding=UTF-16
     

Git使用a) UTF-16, without BOM, big endian: $ printf "\000g\000i\000t" | iconv -f UTF-16 -t UTF-8 | od -c 0000000 g i t b) UTF-16, with BOM, little endian: $ printf "\377\376g\000i\000t\000" | iconv -f UTF-16 -t UTF-8 | od -c 0000000 g i t c) UTF-16, with BOM, big endian: $ printf "\376\377\000g\000i\000t" | iconv -f UTF-16 -t UTF-8 | od -c 0000000 g i t 将索引中的UTF-8转换为索引中的ITF-16。   工作树。
  签出后,生成的文件具有BOM表,并以“ UTF-16”编码,   在上述(c)版本中。
  这是iconv生成的,下面有更多详细信息。

     

libiconv(和iconv)可以生成UTF-16,UTF-16LE或UTF-16BE:

libiconv
     

在Git工作树中无法从上方生成版本(b),   但这正是某些应用程序需要的。
  (所有完全具备Unicode意识的应用程序都应该能够读取所有3个变体,   但实际上,我们还没有到那里。

     

在生成UTF-16作为输出时,d) UTF-16 $ printf 'git' | iconv -f UTF-8 -t UTF-16 | od -c 0000000 376 377 \0 g \0 i \0 t e) UTF-16LE $ printf 'git' | iconv -f UTF-8 -t UTF-16LE | od -c 0000000 g \0 i \0 t \0 f) UTF-16BE $ printf 'git' | iconv -f UTF-8 -t UTF-16BE | od -c 0000000 \0 g \0 i \0 t 生成大端版本   与物料清单。 (可能出于历史原因选择了大端字节序。)

     

iconv可以通过使用“ UTF-16LE”来产生带有很少尾音的UTF-16文件   作为编码,并且该文件没有BOM。

     

并非所有用户(尤其是Windows用户)对此都感到满意。
  有些工具不完全支持Unicode,只能处理版本(b)。

     

如今,无法使用iconv(或iconv)来生成版本(b)。
  回顾libiconv的历史,似乎(c)版本将在以后的所有iconv版本中使用(出于兼容性原因)。

     

解决这个难题,并引入特定于Git的“ iconv”。
  libiconv无法处理编码,因此Git进行处理,处理BOM   并使用libiconv转换流的其余部分。 (添加了UTF-16BE-BOM以获得一致性)