ski*_*ppy 135 git unicode diff utf-16 character-encoding
我在git中跟踪虚拟PC虚拟机文件(*.vmc),在进行更改后,git将该文件识别为二进制文件并且不会为我进行区分.我发现该文件是用UTF-16编码的.
可以教git识别这个文件是文本并适当处理它吗?
我在Cygwin下使用git,core.autocrlf设置为false.如果需要,我可以在UNIX下使用mSysGit或git.
Sam*_*kes 81
我一直在努力解决这个问题,并且刚刚发现(对我来说)一个完美的解决方案:
$ git config --global diff.tool vimdiff # or merge.tool to get merging too!
$ git difftool commit1 commit2
Run Code Online (Sandbox Code Playgroud)
git difftool采用相同的参数git diff,但运行你选择的diff程序而不是内置的GNU diff.因此,选择一个多字节识别差异(在我的情况下,vim在diff模式下),而只是使用git difftool而不是git diff.
找到"difftool"太长,无法输入?没问题:
$ git config --global alias.dt difftool
$ git dt commit1 commit2
Run Code Online (Sandbox Code Playgroud)
Git岩石.
IlD*_*Dan 62
有一个非常简单的解决方案,在Unices上开箱即用.
例如,Apple的.strings文件只是:
使用以下.gitattributes命令在存储库的根目录中创建文件:
*.strings diff=localizablestrings
Run Code Online (Sandbox Code Playgroud)将以下内容添加到您的~/.gitconfig文件中:
[diff "localizablestrings"]
textconv = "iconv -f utf-16 -t utf-8"
Run Code Online (Sandbox Code Playgroud)来源:Git中的Diff .strings文件(以及2010年的旧文章).
Che*_*ion 37
您是否尝试过.gitattributes将其视为文本文件?
例如:
*.vmc diff
Run Code Online (Sandbox Code Playgroud)
有关详细信息,请访问http://www.git-scm.com/docs/gitattributes.html.
Jar*_*aus 30
默认情况下,它似乎git不适用于UTF-16; 对于这样的文件,你必须确保没有CRLF对它进行处理,但你想要diff并merge作为普通文本文件工作(这忽略了你的终端/编辑器是否可以处理UTF-16).
但是查看.gitattributes联机帮助页,以下是自定义属性binary:
[attr]binary -diff -crlf
Run Code Online (Sandbox Code Playgroud)
所以,在我看来,你可以定义你的顶级定制属性.gitattributes的utf16(注意,我添加合并在这里,以确保它被视为文本):
[attr]utf16 diff merge -crlf
Run Code Online (Sandbox Code Playgroud)
从那里你可以在任何.gitattributes文件中指定类似的东西:
*.vmc utf16
Run Code Online (Sandbox Code Playgroud)
另请注意,您仍然可以diff使用文件,即使git认为它是二进制文件:
git diff --text
Run Code Online (Sandbox Code Playgroud)
编辑
这个答案基本上说GNU diff与UTF-16甚至UTF-8都不能很好地工作.如果您想git使用不同的工具来查看差异(通过--ext-diff),那么答案就是Guiffy.
但您可能需要的只是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")
Run Code Online (Sandbox Code Playgroud)
请注意,转换为UTF-8也可能适用于合并,您只需要确保它在两个方向上完成.
至于查看UTF-16文件的差异时到终端的输出:
试图像这样的差异导致二进制垃圾喷射到屏幕上.如果git使用GNU diff,那么GNU diff似乎不是unicode.
GNU diff并不真正关心unicode,所以当你使用diff --text时它只是差异并输出文本.问题是你正在使用的终端无法处理发出的UTF-16(与ASCII字符的diff标记结合).
小智 8
解决方案是过滤cmd.exe /c "type %1".cmd的type内置将进行转换,因此您可以将其与git diff的textconv功能一起使用,以启用UTF-16文件的文本差异(尽管未经测试,也应该与UTF-8一起使用).
从gitattributes手册页引用:
有时需要查看某些二进制文件的文本转换版本的差异.例如,可以将文字处理器文档转换为ASCII文本表示,并显示文本的差异.即使这种转换失去了一些信息,生成的差异对人类观看也很有用(但不能直接应用).
textconv配置选项用于定义用于执行此类转换的程序.程序应该采用单个参数,要转换的文件的名称,并在stdout上生成结果文本.
例如,要显示文件的exif信息的差异而不是二进制信息(假设您已安装exif工具),请将以下部分添加到您的$GIT_DIR/config文件(或$HOME/.gitconfig文件)中:
[diff "jpg"]
textconv = exif
Run Code Online (Sandbox Code Playgroud)
对于mingw32的解决方案,cygwin粉丝可能不得不改变这种方法.问题是传递文件名转换为cmd.exe - 它将使用正斜杠,cmd假定反斜杠目录分隔符.
创建将转换为stdout的单个参数脚本.C:\路径\为\一些\ script.sh:
#!/bin/bash
SED='s/\//\\\\\\\\/g'
FILE=\`echo $1 | sed -e "$SED"\`
cmd.exe /c "type $FILE"
Run Code Online (Sandbox Code Playgroud)
设置git以便能够使用脚本文件.在你的git配置(~/.gitconfig或.git/config或看到man git-config)里面,把这个:
[diff "cmdtype"]
textconv = c:/path/to/some/script.sh
Run Code Online (Sandbox Code Playgroud)
通过使用.gitattributes文件指出要应用此工作区的文件(请参阅man gitattributes(5)):
*vmc diff=cmdtype
Run Code Online (Sandbox Code Playgroud)
然后使用git diff你的文件.
git最近开始了解utf16等编码。查看gitattributes文档,搜索working-tree-encoding
[确保您的手册页匹配,因为这是相当新的!]
如果(比如说)文件是 UTF-16,在 Windows 机器上没有 BOM,然后添加到您的.gitattributes文件
*.vmc text working-tree-encoding=UTF-16LE eol=CRLF
Run Code Online (Sandbox Code Playgroud)
如果 *nix 上的 UTF-16(带 bom)使它:
*.vmc text working-tree-encoding=UTF-16-BOM eol=LF
Run Code Online (Sandbox Code Playgroud)
(替换*.vmc用*.whatever的whatever类型的文件需要处理)
关注@Hackslash,你可能会发现这是不够的
*.vmc text working-tree...
Run Code Online (Sandbox Code Playgroud)
要获得漂亮的文本差异,您需要
*.vmc diff working-tree...
Run Code Online (Sandbox Code Playgroud)
把两者都工作
*.vmc text diff working-tree...
Run Code Online (Sandbox Code Playgroud)
但可以说是
eol=...暗示textGit 有一个宏属性 binary,这意味着-text -diff. 相反+text +diff的不是内置的,但 git 提供了合成它的工具(我认为!)
Git 允许定义新的宏属性。
我建议.gitattributes你拥有的文件顶部
[attr]textfile text diff
Run Code Online (Sandbox Code Playgroud)
然后对于所有需要是 text 和 diff 的路径
path textfile working-tree-encoding= eol=...
Run Code Online (Sandbox Code Playgroud)
请注意,在大多数情况下,我们希望使用默认编码 (utf-8) 和默认 eol(本机),因此可能会被删除。
大多数行应该看起来像
*.c textfile
*.py textfile
Etc
Run Code Online (Sandbox Code Playgroud)
实用:在大多数情况下,我们需要原生 eol。这意味着没有eol=...。所以text不会被暗示,需要明确地提出。
概念:文本与二进制是根本区别。eol、编码、差异等只是它的一些方面。
由于我们生活的奇怪时代,我没有一台带有当前工作 git 的机器。所以我目前无法检查最新添加的内容。如果有人发现有问题,我会修改/删除。
| 归档时间: |
|
| 查看次数: |
56051 次 |
| 最近记录: |