Answers:
我已经为这个问题苦苦挣扎了一段时间,并且(为我)发现了一个完美的解决方案:
$ 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(在我的情况下vim
为diff模式),然后使用git difftool
代替git diff
。
查找“ difftool”太长而无法键入?没问题:
$ git config --global alias.dt difftool
$ git dt commit1 commit2
吉特岩石。
有一个非常简单的解决方案可以在Unices上使用。
例如,仅使用Apple的.strings
文件:
使用以下.gitattributes
命令在存储库的根目录中创建一个文件:
*.strings diff=localizablestrings
将以下内容添加到您的~/.gitconfig
文件中:
[diff "localizablestrings"]
textconv = "iconv -f utf-16 -t utf-8"
资料来源:Git中的Diff .strings文件(以及2010年以来的旧文章)。
iconv
是“另一个工具”,与Vim或Beyond Compare是相同的方式(不是git套件的一部分)。
vimdiff
和iconv
都已经出现在MacOS,所以你不必费心琢磨让他们在哪里,他们做的工作
默认情况下,它似乎git
不适用于UTF-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
编辑
这个答案基本上表明,与UTF-16甚至UTF-8兼容的GNU效果不是很好。如果您想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")
请注意,转换为UTF-8也可能适用于合并,您只需要确保已在两个方向上都完成了。
至于查看UTF-16文件的差异时输出到终端:
尝试像这样进行比较会导致二进制垃圾涌入屏幕。如果git使用的是GNU diff,那么看来GNU diff不支持unicode。
GNU diff并不真正在乎unicode,因此当您使用diff --text时,它只是进行diff并输出文本。问题是您使用的终端无法处理发出的UTF-16(与ASCII字符的差异标记结合使用)。
解决的办法是过滤cmd.exe /c "type %1"
。cmd的type
内置函数将进行转换,因此您可以将其与git diff的textconv功能一起使用,以启用UTF-16文件的文本差异(尽管未经测试,也应与UTF-8一起使用)。
引用gitattributes手册页:
有时希望看到一些二进制文件的文本转换版本的差异。例如,可以将文字处理器文档转换为ASCII文本表示形式,并显示文本的差异。即使此转换丢失了一些信息,所得的差异对于人类查看也是有用的(但不能直接应用)。
textconv config选项用于定义执行此转换的程序。该程序应采用一个参数,即要转换的文件名,并在stdout上生成结果文本。
例如,要显示文件的exif信息的差异而不是二进制信息(假设您安装了exif工具),请在$GIT_DIR/config
文件(或$HOME/.gitconfig
文件)中添加以下部分:
[diff "jpg"]
textconv = exif
对于mingw32的解决方案,cygwin粉丝可能不得不更改方法。问题在于传递文件名以转换为cmd.exe,它将使用正斜杠,而cmd假定使用反斜杠目录分隔符。
创建单个参数脚本,它将执行到标准输出的转换。c:\ path \ to \ some \ script.sh:
#!/bin/bash
SED='s/\//\\\\\\\\/g'
FILE=\`echo $1 | sed -e "$SED"\`
cmd.exe /c "type $FILE"
设置git使其能够使用脚本文件。在您的git config中(~/.gitconfig
或.git/config
参见man git-config
),将其放入:
[diff "cmdtype"]
textconv = c:/path/to/some/script.sh
通过使用.gitattributes文件指出要将此工作对象应用到的文件(请参见man gitattributes(5)):
*vmc diff=cmdtype
然后git diff
在您的文件上使用。
cmd //c type "${1//\//\\}"
。
textconv = powershell -NoProfile -Command \"& {Get-Content \\$args[0]}\"
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
类型的文件需要处理)
在@Hackslash之后,可能会发现这是不够的
*.vmc text working-tree...
要获得漂亮的文本差异,您需要
*.vmc diff working-tree...
这也很好
*.vmc text diff working-tree...
但这可以说是多余的(eol = ...表示文本)和冗长的(大型项目可能很容易拥有数十种不同的文本文件类型!)
我建议的解决方案是在gitattributes文件的早期使用:
[attr]textfile text diff
然后对于所有需要是文本和差异的路径
path textfile working-tree-encoding= eol=...
请注意,在大多数情况下,我们希望使用默认编码(utf-8)和默认eol(本机),因此可能会被删除。
免责声明:由于我们生活在离奇的时代,我没有工作的git。因此,我目前无法检查。如果有人发现问题,我会修改/删除。
注意:为什么不只使用diff?
实用:在大多数情况下,我们希望使用天然eol。这意味着没有“ eol = ...”。因此,文本不会被隐含,需要明确地放置。
概念上:文本与二进制是基本区别。eol,encoding,diff等只是其中的一些方面。
*.vmc diff working-tree-encoding=UTF-16LE-BOM eol=CRLF
text
一个人没得到很好的文字差异吗?能否请您检查有两个 text
和diff
一切工作正常?在这种情况下,我会提出不同的建议
text
单独会导致二进制比较。我可以做diff
或者text diff
和它的作品。我只需要添加-BOM
文件是因为我的文件具有BOM表,即YMMV。
我已经编写了一个小的git-diff驱动程序,to-utf8
该驱动程序应该可以轻松区分所有非ASCII / UTF-8编码的文件。您可以按照以下说明进行安装:https : //github.com/chaitanyagupta/gitutils#to-utf8(该to-utf8
脚本在同一仓库中可用)。
请注意,此脚本需要file
和iconv
命令都可以在系统上使用。
最近在Windows上出现了这个问题,而git附带的Windows的bins dos2unix
和unix2dos
bins 解决了这个问题。默认情况下,它们位于中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...