建立于: 6年前 ( 更新: 6年前 )
不同中文编码时的乱码问题
这里举例,例如同时有三个不同编码的php档,会显示成怎样。我们直接透过
git log -p
来看一下结果,会发觉到有看不懂的乱码,如下图。在上方的个例字中,看不出到底修改了什么,因为编码不是utf-8。
但是透过Git属性的diff设置后,情况就不同了,画面如下,正常的显示出三种不同编码的文本档:
其时,这是透过git属性达成的。
关於Git属性
使用属性,你可以对个别文件或目录定义不同的合并策略,也可以让 Git 知道怎样比较非文本档,例如比较两个word文档变更,因为这样的特性,
我们也可以让不同编码的文档,统一使用一种编码显示於终端机上。
在本文中,我将示范透过git属性的功能,将不同编码的文件使用UTF-8编码,显示於终端机上。
Git属性可以透过新建
.gitattributes
档进行设置,通常放在项目的目录上,如果不想设置的Git属性被一起提交,也可以设置在自己
.git/info/attributes
上。一、先创建.git/info/attributes内容如下:
*.php diff=big5
*.html diff=big5
*.htm diff=big5
上例的语法,非常明显示,我针对了*.php、*.html及*.htm三种文件,在进行diff时,使用big5这个转码器。也就是说.php或是.html档,都会透过big5这个转换器,将编码采转换后,采用UTF-8的方式显示并比较。
二、手动编辑在.git/config文件中,添加如下设置:
[diff "big5"]
textconv = hkscs2utf8
或者我们也可以命令的方式新建设置
git config diff.big5.textconv hkscs2utf8
上方的hkscs2utf8是我写的简易版转码bash,用於将gb2312及big5转换成utf8显示。也就是说,当git进行diff时,都会采用我们在git属性中定义的副档为.php及.html或.html等文件,
经由hkscs2utf8这只自己写的bash档进转码,并比较结果。
三、将下方的bash,放入/usr/local/bin/hkscs2utf8。
可echo $PATH,确认这个路径/usr/local/bin是有设置的。
注: 这个bash只适合用於MacOS的系统上。当然这并代表Windows或Linux无法达到这个效果,
本文主要传达的是Git属性的概念及用例,您可采用不同的方式进行转码,例如Python,或在不同的平台上,
使用自己写出的更严谨的转码进程。
#!/bin/bash
file -I "$1" |grep utf-8 >/dev/null 2>&1
#判断文件为utf-8吗?
#ansi档会有不同的编码,或在Widnows上称为CodePage不好判定文件是Big5或Gb2312编码,
#DBCS中,因为不同字集两边的编码可能是一样的。
#所以我先判定文件是否为UTF-8
#这样回传的错误码为0代表,没有错误,那么直接将UTF-8编码的文档cat出来。
if [ $? -eq 0 ]; then
cat ${1}
exit 0;
fi
#上方的UTF-8判定失败了,开始尝试其他的编码。
#先尝试以gb2312简体转utf-8,将大於0的错误信息隐藏,
#失败了代表该档非GB2312,因此我们使用big5-hkscs进行转码。
#如果尝试转码成功,回传为0,我们就重新运行GB2312转码,变更为UTF-8输出。
iconv -f gb2312 -t utf-8 "$1" >/dev/null 2>&1
if [ $? -eq 1 ]; then
iconv -f big5-hkscs//IGNORE -t utf-8 "$1"
else
iconv -f gb2312 -t utf-8 "$1"
fi
记得哦,要chmod 700 hkscs2utf8
,否则该bash是不能被运行的。以上就完成设置了,如果打了
git log -p
,就可以看到正常中文本罗,magic.
四、另外,我也用Python写了另一只转码进程,效果应该比bash版的来较没问题哦
如果您电脑可以跑python可以试看看。
1.创建cv.py到/usr/local/bin目录下
2.设置使用cv.py,运行命令: git config diff.big5.textconv cv.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
#检测是否为UTF-8编码
def isUTF8(data):
try:
decoded = data.decode('UTF-8')
except UnicodeDecodeError:
return False
else:
for ch in decoded:
if 0xD800 <= ord(ch) <= 0xDFFF:
return False
return True
#取得binary的文件内容
def get_bytes_from_file(filename):
return open(filename, "rb").read()
#取得档名
filename = sys.argv[1]
data = get_bytes_from_file(filename)
#检测文件是否为UTF8
result = isUTF8(data)
#非UTF-8进行转码
if(result == False):
#udata = data.decode("hkscs")
try:
udata = data.decode("gb2312")
except:
udata = data.decode("hkscs")
data = udata.encode("utf-8","ignore")
print(data)
else:
print(data)
在utf-8的环境下,显示的注解是乱码,用下方命令就能正常了
git config --global i18n.logOutputEncoding utf8
No Comment
Post your comment