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 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 包裹 windows 原生的指令就沒有亂碼了
相關連結
- 問題出處: StackExchange 網站, superuser 這一篇問題及解答
- 維基百科 pty 解說: https://en.wikipedia.org/wiki/Pseudoterminal
- Winpty 自己的說明 https://github.com/rprichard/winpty
連結
- 有用的 Git Bash 小抄: Git bash note
大陸 推酷網站 文章 切换到MSYS2這個網站倒了, 原 POST 好像是這個 切换到MSYS2