建立於: 7年前 ( 更新: 7年前 )
不同中文編碼時的亂碼問題
這裡舉例,例如同時有三個不同編碼的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