Git for windows 疑難雜症


這一篇會不定期附加新的問題解決方法. Enjoy it!

Git Bash 介面設定(2022/02/27)


Git for Windows 裡的 Git Bash 介面一般是由 MinTTY 帶出來的 (安裝時的預設值), MinTTY 的設定檔案為 ~/.minttyrc. 需要的話你可以選擇備份一下這個檔案. 沒有更動過為空白檔案, 更動了才會附加更動的內容. 例如: 我更動了字型的字體及大小的設定, 設定檔就會變成如下:

Font=Microsoft YaHei Mono
FontHeight=14

再更動 Locale 成 zh_TW 及 Charset 設定 UTF-8:

Font=Microsoft YaHei Mono
FontHeight=14
Locale=zh_TW
Charset=UTF-8

再把 Locale 及 Charset 設定改回原來的 "(Default)", 內容就會變成如下這樣:

Font=Microsoft YaHei Mono
FontHeight=14
Locale=
Charset=

由於版本更迭, 目前建議大家只動字型設定就好, Locale 及 Charset 可以不必更動了.

bash 介面亂碼


更新 2022/02/26

目前新版的 git for windows (ver 2.33.0.2) 貌似沒有這個問題了. MinTTY 預設帶出來的 Git Bash 介面是 Windows 的預設 chcp 頁碼, Windows 內建指令是中文輸出, 但都已經可以正確顯示了. 如果你換用 65001 頁碼, 則 Windows 內建指令是英文輸出.

如果你的 bash shell 設定使用 locale:zh_TW, Character set:UTF-8, 那在使用一些 windows 的內建指令時, 往往都會出現亂碼, 你可以使用以下的指令 (將 windows console 切換為 utf-8 字集), 把大部份的問題解決:

cmd //C "chcp 65001"
  • 如果不想每次開啟bash都要重新打一遍, 可以把它加在自己的.bashrc裡.
    echo 'cmd //C "chcp 65001"' >> ~/.bashrc
    
  • 如果你想直接用熟悉的 windows 編輯工具來修改它, 那麼檔案.bashrc的目錄路徑應該是在 C:\Users\<自己的 windows 帳號名稱>底下.
  • 還有要注意一下: 該目錄下是否也有.profile檔. 一般.bashrc是經由.profile呼叫的.

至於為什麼更換了 code page 之後只是解決大部份的問題呢? 那是因為有部份指令輸出的資料並非來自指令本身, 例如: ipconfig輸出的介面卡中文名稱有些還是用 big5 編碼. 遇到這種資料 Windows CMD看得懂, 但是bash看不懂啊!

不過, 你也可以利用 winpty 指令, 來包裹原始的 windows 指令 (sorry, 僅限於.exe指令. .com 指令包裹後會出現錯誤), winpty可以完美的將原本的 big5 編碼輸出訊息, 轉換成正確的 utf-8 編碼訊息並顥示出來. (請參看 利用 winpty 指令 段落)


另一種讓 windows 指令可以正確顯示的方法是使用 Windows(7) 中文版預設的 950 字集, 如下圖 (選用第一項 default 即可):

字集設定

使用 chcp 950 避免 windows 指令輸出的中文亂碼

不過現今大多數程式都已經偏向採用 utf-8 字集了, 這會使得你在處理有使用 utf-8 中文的程式遇到困難. 所以我比較建議使用上面的第一種方法. 或者你也可以臨時再開一個 bash, 改成使用 950 字集

指令: ln


更新 2023/03/27

最近發現如何解決這個問題. 不過使用上, 還是有點麻煩. 二個條件:

  • 使用 "以系統管理者身份執行" 開啟 git bash (使用 Windows Terminal 時要在設定裡把這個選項打開).
  • 加上環境變數 MSYS
    export MSYS=winsymlinks:nativestrict
    

如果 git repository 也要啟用 symlinks 則還要再一個 git 設定:

  • 安裝 git for windows 時啟用 symlinks. 這個是系統層級 (--system) 的設定.
  • 如果安裝時未啟用 symlinks 可以直接修改 git 的 system 設定檔 C:/Program Files/Git/etc/gitconfig.
    git config --system core.symlinks true
    
  • 不全面啟用也可以將 --system 換成 --global (User 所有的 git repository), 或者省略不加 --system (只有目前所在位置的 git repository 有效).

請你不要使用 MSYS2 原本的ln指令, 它會進行拷貝動作而不是連結.

MSYS2 承襲自 cygWin 無法在 Windows 不支援連結功能的舊檔案系統上 (FAT, FAT32, exFAT32) 提共連結 (link) 的功能. 雖然 NTFS 檔案系統已經具備連結功能 (NTFS v3.0以上), 但 MSYS2 對於連結的處理能力依然不完整. 不過, 我們可以利用 windows 原本的指令來達成部份功能:

  • Windows 7/8/10 都有提供mklink指令可以在 NTFS 檔案系統上完成連結的動作.
  • Windows XP 則需要下載 Windows 2003 Resource kit 並將指令名稱改為linkd.

關於這個問題的詳細說明在這個連結: git for windows 在 github 上有關 symbolic links 的說明文件.

如果你想要整合度好一些, 則可以參考 stackoverflow 上的這一段解答所提供的作法: git-bash-shell-fails-to-create-symbolic-links

另外: 如果你在 VM 上使用 bash (不論是 MSYS2 或者 git for windows 的) 則遠端的連結還有一些額外的問題.

  • 雖然 guest OS (Windows) 本身對於本地端或者是遠地端的連結都可以正確連結. 但刪除遠地端的連結會將原本的內容刪除, 而不是移除連結本身.
  • 同時, 經由 bash shell 我們只能存取本地端的連結; 遠地端的連結則都無法存取 (access).
  • 所謂本地端指的是 guest OS 自身的磁碟空間. 而所謂遠地端就是經由網路協定存取的, 不論是 host OS 分享給 guest OS 的, 或者經由其他網路主機分享給 guest OS 的.

總之如果要在 VM 上使用連結, 你得小心測試無誤了再使用.

指令: more


更新 2022/02/27

雖然 Git for Windows 裡沒有 more 指令, 但是 git for Windows SDK 裡有喔. 你可以使用指令 pacman -S util-linux 加裝 util-linux 這個 package 就可以取得 more 指令了.

如何安裝 pacman? 請參閱我的貼文 Git:給 git for windows 裝個翅膀 (安裝 pacman 及其他工具).

MSYS2 有less指令, 沒有more指令. 請用less來替代more. 真的不習慣或者有需要的話可以建一個 link 來替代. 指令如下:

cmd //C 'mklink D:\Git\usr\bin\more.exe D:\Git\usr\bin\less.exe'

請把其中的D:\Git更換成你的 Git for windows (或者是 MSYS2) 的安裝目錄.

指令: chmod


(2019/01/09) 今天發現 msys2 的 chmod 指令竟然無效: 想要為 .sh 檔加執行權限, 竟然一直加不上去 (雖然是一樣可以執行). Google 大神拜了二下下總算解決. 原來 cygwin 移植時引發的問題. 有人建議修改/etc/fstab/的權限由noacl改為acl即可, 不過個人認為這不是好方法: 因為原本沒有加執行權限時, .sh 檔和 .py 檔已經可以執行了, 我只是想要為 ls 的輸出上色. 所以比較好的方案是: 修改檔案的第一行. 如果是 shell script, 就加上這一行
#!/usr/bin/bash
(哈! 以前一直不知道這一行的用途到底是什麼, 現在總算明白.)

如果是python程式, 則換成
#!/usr/bin/python

不過要注意的是/usr/bin/...不是依樣畫葫蘆就好, 必需真實的有該指令存在才行啊! 否則像是要執行.py檔, 你想直接輸入你的.py檔名, 省略指令最前面的python , 這樣是沒辦法執行的啊! 其實它的意思是叫 shell 用我指定的那一個指令來執行 (或是解譯) 檔案的內容.

不過有一個替代辦法是指定指令但是不指定路徑. 像這樣:
#! python
或者
#! /usr/bin/env python

還有, 這一行務必要放在第一行.

指令: git 中文路徑/檔名亂碼


如果你的git status, git log, git diff...等指令輸出時, 中文路徑/檔名出現的是亂碼 (utf-8 編碼的怪字), 請以下列指令修改 git 的設定.

$ git config --global core.quotepath false
git for windows 中文亂碼

git for windows 中文路徑/檔名亂碼

目前我使用過的版本 (git for windows 2.14.1 ~ 2.20.1) 都只要修改這個即可. 如果你用的版本還是有中文亂碼的問題, 又不便更新的話, 其他可能需要更動的部份還有:

$ git config --global i18n.commit.encoding utf-8    # 提交信息的編碼
$ git config --global i18n.logoutputencoding utf-8  # log 的編碼
$ git config --global gui.encoding utf-8            # 圖形界面的編碼

上述這些設定更動你也可以直接修改檔案C:\ProgramData\Git\config(註一). 我們需要更動的部份顯示如下:

[core]
	quotepath = false
[gui]
	encoding = utf-8
[i18n]
	commitencoding = utf-8
	logoutputencoding = utf-8

另外, 如果git log指令的輸出也有亂碼的話, 需要修改less指令 (訊息分頁指令) 的預設編碼:

$ export LESSCHARSET=utf-8

這個修改可以加在./bashrc裡.

註一: 目前 (2022/03/11) 的新版本裡已經沒有這個設定檔了, 它搬到了 C:\Program Files\Git\etc\gitconfig 這個檔案了.

bash 環境: 相關設定(2021/05/20)


設定之一:
目前預設的 git-bash 設定有一個令人不悅的狀況: 就是錯誤提醒音從 beep 變成整個螢幕一閃了, 如果你很在意這個改變可以在 git-bash 視窗裡執行下列指令, 然後重開 git-bash 即可.

echo "set bell-style none" >> ~/.inputrc

或者是在 Windows CMD 視窗裡, 以下指令效果也一樣:

echo set bell-style none >> %USERPROFILE%\.inputrc

bell-style 的值可以設定成 none, audible, visible 三個其中之一.

設定之二:
我印象中, git-bash 預設在輸入檔案路徑時, 只要輸入少數幾個字元, 再按下 Tab 鍵就會不分大小寫幫們找到最相近的路徑, 後來 (不知是從哪一版開始) 卻是會分大小寫, 必需大小寫一致才行, 讓我這個被慣壞了的老人家不知如何是好, 好在這個也是可以設定的. 如果你也是很在意這個改變, 可以在 git-bash 視窗裡執行下列指令, 然後重開 git-bash 即可.

echo "set completion-ignore-case On" >> ~/.inputrc

或者是在 Windows CMD 視窗裡, 以下指令效果也一樣:

echo set completion-ignore-case On >> %USERPROFILE%\.inputrc

利用 winpty 指令(2019/04/10)


更新 2022/02/27

目前新版 git for windows (ver 2.33.0.2 之後, 不知從哪一版開始) 的終端機已經改用 pty 開頭的, 整合到 windows terminal 視窗裡時則使用 cons 開頭的. Windows 內建指令輸出亂碼的問題, 大致上算是解決了.

以下我把目前的幾個使用環境及其設定組合整理如下:

環境 MinTTY (即原 git for windows 環境)
MinTTY 設定 Locale=zh_TW; Charset=Big5
環境變數 LC_ALL zh_TW.Big5 無設定 zh_TW.UTF-8
chcp 頁碼 950 65001 950 65001 950 65001
ls/dir 中文
目錄/檔案名
正確 正確 正確 正確 亂碼 亂碼
Windows
內建指令輸出
中文, 正確. 英文 中文, 正確. 英文 中文, 正確. 英文
中文內容
Big5 編碼
正確 正確 正確 正確 正確 正確
中文內容
UTF-8 編碼
亂碼 亂碼 亂碼 亂碼 亂碼 亂碼
環境 MinTTY (即原 git for windows 環境)
MinTTY 設定 無設定(預設)或
Locale=zh_TW; Charset=UTF-8
環境變數 LC_ALL zh_TW.Big5 無設定 zh_TW.UTF-8
chcp 頁碼 950 65001 950 65001 950 65001
ls/dir 中文
目錄/檔案名
亂碼 亂碼 正確 正確 正確 正確
Windows
內建指令輸出
中文, 正確 英文 中文, 正確 英文 中文, 正確 英文
中文內容
Big5 編碼
亂碼 亂碼 亂碼 亂碼 亂碼 亂碼
中文內容
UTF-8 編碼
正確 正確 正確 正確 正確 正確

 

環境 在 Windows Terminal 整合 Git Bash
環境變數 LC_ALL zh_TW.Big5 無設定 zh_TW.UTF-8
chcp 頁碼 950 65001 950 65001 950 65001
ls/dir 中文
目錄/檔案名
正確 正確 正確 正確 正確 正確
Windows
內建指令輸出
中文, 正確 英文 中文, 正確 英文 中文, 正確 英文
中文內容
UTF-8 編碼
亂碼 亂碼 正確 正確 正確 正確
中文內容
Big5 編碼
正確 正確 亂碼 亂碼 亂碼 亂碼
  • 使用 cmd //c chcp 指令在 950 頁碼和 65001 頁碼之間切換只是讓 Window 內建指令輸出在中文英文之間切換.
  • 目前的狀況是 Big5 編碼和 UTF-8 編碼只能二選一: 需要顯示另一種編碼時, 請利用利用 iconv 指令轉換.
    • Big5 轉 UTF-8: iconv -f cp950 -t utf-8 some_big5.txt
    • UTF-8 轉 Big5: iconv -c -f utf-8 -t cp950 some_utf.txt (需要多一個參數 -c 以防檔頭有 BOM)
    • iconv 指令請用 cp950 勿用 big5. 使用 big5 會有缺字: 碁銹裏墻恒粧嫺
  • 使用 MinTTY (即 git for windows 原始的 Git Bash 介面)
    • 將 MinTTY 的設定改成使用 Locale: zh_TW 及 Charset: Big5: 可直接顯示中文 BIG5 (cp950) 檔案的內容 (例如: cat some_big5.txt), 但 utf-8 的文字檔則無法正常顯示中文.
    • 將 MinTTY 的設定改成預設值, 或 Locale: zh_TW 及 Charset: UTF-8: 無法顯示中文 BIG5 (cp950) 的檔案內容, 但 utf-8 的文字檔則可以正常顯示.
    • 更動 MinTTY 設定後請關閉目前使用的 bash session, 動啟 Git Bash 否則中文顯示可能會不正常 (變成亂碼).
  • Windows Terminal 無法像 MinTTY 設定 Charset 為 Big5, 此時可以改成在 Bash 裡設定環境變數 LC_ALL. 此法不建議在 MinTTY 環境下使用, 因 MinTTY 環境設定和 LC_ALL 設定不一致時 ls (或 dir) 指令輸出中文檔名會變成亂碼:
    • export LC_ALL=zh_TW.UTF-8: 螢幕輸出使用 UTF-8 編碼. 這是 Windows Terminal 預設值.
    • export LC_ALL=zh_TW.Big5: 螢幕輸出使用 Big5 編碼.
  • git for windows v2.35.1 的 release note 依舊寫著非 MSYS2 的 (經查: 應該是原 MSYS 編譯的, 如: 早期的 anaconda 所提供的?) python, PHP, Node, OpenSSL 等等的 console 輸出依然需要用 winpty 指令包裹才不會出現亂碼.

有許多原本 linux/unix 的指令或者程式需要搭配正確的 tty 才能正常運作. 通常作這類程式移值到 windows 時會 console 沒有輸出或者沒有輸入, 遇到這種情況最簡單的方法即是 '利用 winpty 提供它執行時所需要的 tty 環境'. 方法很簡單: 在原本使用的指令前面加上 winpty 即可. 例: winpty /path/to/python.exe abcxyz.py

另外有一個可以大推 winpty 的點是, 利用它來包裹 windows 原生的指令, 就不會出現亂碼的現象了.

winpty

使用 winpty 包裹 windows 原生的指令就沒有亂碼了

相關連結

連結


arrow
arrow
    創作者介紹
    創作者 MagicJackTing 的頭像
    MagicJackTing

    傑克! 真是太神奇了!

    MagicJackTing 發表在 痞客邦 留言(0) 人氣()