close

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 介面亂碼


Update(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


Update(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

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

指令: 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)


Update(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 發表在 痞客邦 留言(0) 人氣()