2026/06/23(火)MSYS2のGitを高速化する

投稿日:

MSYS2のGitって遅いよな~とつぶやいていたら公式から早くする方法があるよと紹介されたので、その時にやったこと。

この手順は私個人の環境に深く紐づいている。

確認環境

Env Ver
MSYS2 msys2-x86_64-20260322

手順

  1. 起動スクリプトを直す
     @echo off
    -set MSYSTEM=MSYS
    +set MSYSTEM=UCRT64
     set MSYS2_PATH_TYPE=inherit
     set CHERE_INVOKING=1
     C:\env\msys64\usr\bin\zsh.exe -l %*
    
  2. パッケージのアップグレードを行う
    pacman -Syu
    
  3. もっかいやる
    pacman -Syu
    
  4. 既存のgitを消す
    pacman -S git
    
  5. UCRT用のgitを入れる
    pacman -S mingw-w64-ucrt-x86_64-git
    
  6. MSYS2用のGitプロンプトを廃止

参考リンク

あとがき

Windows側に入ってるGit for windowsも消していい気がしてきた。まぁそもそもGit作業は今のところUbuntu実機で行っている関係もあり、滅多に使わないのだが…。ただVSCodeでパスフレーズ付きのカギを扱うときにはあった方が良さそうだし、コミット用にはあった方が良さそうな気もする。

しかし過去情報の断面を残したいがために、出来るだけ過去記事の状態を保っているが、MECEでなくなりすぎていて大変なので、そろそろWiki的な何かを作った方がいい気がしてきた。

絶対に次にフルセットアップするときにこの状態に戻せない気がしている。

ところでMSYS2公式から助言をもらえたのはFediverseをやっていたお陰な気がするので、これはとても良い出来事だったと思う。

実行環境的にMSYSはCygwinでUCRT64はWindowsネイティブで速そうなので実行環境はMSYSTEMよりUCRT64のがいいのかなとか思った。

2026/04/22(水)WindowsTerminalとVSCodeからMSYS2のzshでHomeキーやEndキーが効かなくなっていた問題を対応した

更新日:
投稿日:

起きていた問題

WindowsTerminalやVSCodeでMSYS2のzshを使用しているときにHome, Endを押しても.zshrcで定義したコマンドが発動しない状態で、WindowsTerminalではブザーマークが表示される状態だった。

msys2-x86_64-20210725では起きていなかったはずだが、msys2-x86_64-20260322では起きていた。

問題が起きていた時の.zshrc上の定義

# Home
bindkey "\e[H" beginning-of-line
# End
bindkey "\e[F" end-of-line

解決した方法

.zshrc上の定義を以下に変更した。

# Home
bindkey "^[[H" beginning-of-line
# End
bindkey "^[[F" end-of-line

変更差分

 # Home
-bindkey "\e[H" beginning-of-line
+bindkey "^[[H" beginning-of-line
 # End
-bindkey "\e[F" end-of-line
+bindkey "^[[F" end-of-line

あとがき

ググっても当該現象が引っかからず(最近のGoogleはアホである)、Claude Opus 4.6に調べさせても見当違いの結果しか返ってこなかったが、GitHubのIssueを漁ったところ、Shift+Arrow keys insert characters in WSL/Bash; Windows Terminal rewrites explicit selection keybindings to "id": null #18921というものがあり、そのIssueに貼ってあった設定コメントに、動きそうなコードがあったため、試してみたら動いたというのが解決の道筋である。

# Home/End (both CSI and SS3)
bindkey -M emacs '^[[H'  _home_nosel
bindkey -M emacs '^[OH'  _home_nosel
bindkey -M emacs '^[[F'  _end_nosel
bindkey -M emacs '^[OF'  _end_nosel

これで動くなら -M emacs を抜いて、_home_noselのアサインを変えればいいだけの話である。^[OH'^[OF'はLinux用[1]なのでMSYS2では考慮しなくてよいから、結果として前述にある「解決した方法」の内容でよくなるという寸法だ。

参考までにFreeBSDと同じコードになっているため、FreeBSDと設定を共有できる。なお、少なくともUbuntuとは異なるため、Linuxとは共有できないと思う。知らんけど。


  1. 私はMSYS2, FreeBSD, Linux用の.zshrcを作っているため、これを判断できたという話

2022/02/28(月)MSYS2のセットアップメモ

更新日:
投稿日:

確認環境

msys2-x86_64-20260322

セットアップ

MSYS2から落としてインストールする。

pacman -Syuu

入れとくと便利なものたち

pacman

2023以前の古いMSYS2ではpacman -sS パッケージ名を毎回入れないとインストールできないケースがあるかもしれない。

pacman -S --noconfirm unzip
pacman -S --noconfirm diffutils
pacman -S --noconfirm openssh
pacman -S --noconfirm patch
pacman -S --noconfirm perl
pacman -S --noconfirm zsh
pacman -S --noconfirm git
pacman -Sy --noconfirm openbsd-netcat
# prompt用に退避させる
mv /usr/bin/git /usr/bin/msys2_git

バイナリ追加

dotfileの設定

https://github.com/Lycolia/my-dotfiles

呼び出しを簡略化する

毎回こんな感じで呼ぶのは面倒なので簡略化する。

C:/env/msys64/msys2_shell.cmd -defterm -here -use-full-path -no-start -msys -shell zsh

C:/env/msys64/run_zsh.cmdのようなファイルを作り、以下の内容を書くことでC:/env/msys64/run_zsh.cmd '/c/path/to/hoge.sh'のようにしてシェルスクリプトを実行できるようになる。

@echo off
set MSYSTEM=MSYS
set MSYS2_PATH_TYPE=inherit
set CHERE_INVOKING=1
C:\env\msys64\usr\bin\zsh.exe -l %*

外部連携

呼び出しを簡略化している前提

VSCode連携

{
  "terminal.integrated.defaultProfile.windows": "MSYS2",
  "terminal.integrated.profiles.windows": {
    "MSYS2": {
      "overrideName": true,
      "path": ["C:\\env\\msys64\\run_zsh.cmd"]
    }
  }
}

Windows Terminal連携

{
  "defaultProfile": "{17da3cac-b318-431e-8a3e-7fcdefe6d114}",
  "profiles": {
    "defaults": {},
    "list": [
      {
        "commandline": "C:/env/msys64/run_zsh.cmd",
        "font": {
          "face": "Consolas",
          "size": 11
        },
        "guid": "{17da3cac-b318-431e-8a3e-7fcdefe6d114}",
        "icon": "C:/env/msys64/mingw64.ico",
        "name": "MINGW64 / MSYS2",
        "colorScheme": "VSCode"
      }
    ]
  },
  "schemes": [
    {
      "name": "VSCode",
      "background": "#1e1e1e",
      "foreground": "#d4d4d4",
      "black": "#000000",
      "blue": "#2472c8",
      "brightBlack": "#666666",
      "brightBlue": "#3b8eea",
      "brightCyan": "#29b8db",
      "brightGreen": "#23d18b",
      "brightPurple": "#d670d6",
      "brightRed": "#f14c4c",
      "brightWhite": "#e5e5e5",
      "brightYellow": "#f5f543",
      "cyan": "#11a8cd",
      "green": "#0dbc79",
      "purple": "#bc3fbc",
      "red": "#cd3131",
      "white": "#e5e5e5",
      "yellow": "#e5e510"
    }
  ]
}

msys2_shell.cmdのCLI Optionsの意味合い

msys2_shell.cmdの中身を読んで机上で書いているだけなので実際そう動くのかの検証はしていない。

起動パラメーターについては、:checkparamsラベルの中のループして合致するものがあれば環境変数を立て、既知の環境変数であればmsys2_shiftCounterという変数をインクリメントして、MSYS2用のパラメーターと、ユーザーパラーメーターの教会の切り分けをする実装となっている。これはつまり後続処理でmsys2_shiftCounter個分のパラメーターを読み飛ばし、それ以降のパラメーターを処理するためにある。

-mingw32 | -mingw64 | -ucrt64 | -clang64 | -msys[2]

それぞれで実行環境が変わるが、MSYS2用アプリケーションの開発環境用設定のため、-msysで基本的に問題ない。

内部的には環境変数MSYSTEMに対して、対応する値を設定している。-msys-msys2は等価。

-defterm | -mintty | -conemu

開くターミナルの指定。

  • -defterm
    • 標準ターミナルで開く
    • Windows TerminalやVSCodeで開く場合はこれを指定する
  • -mintty
    • Minttyが起動する
  • -conemu
    • Conemuが起動する

内部的にはシェルを直に蹴るか、minttyやconemuにシェルの起動パラメーターを渡しているかの違いがある。

-here

現在の作業フォルダをカレントディレクトリとして開く。

内部的には環境変数CHERE_INVOKINGに対しenabled_from_argumentsを設定している。

MSYS2公式ではCHERE_INVOKINGには1を設定するそうだが、手元で見た限りenabled_from_argumentsを設定しても動作は変わらなかった。恐らく単純に変数値が設定されているか、そうでないかで処理が分かれていると思われる。

参考までにCHERE_INVOKINGを未設定にするとMSYS2のホーム(~)で起動した。

-where DIRECTORY

指定ディレクトリをカレントディレクトリとして開く。

内部的にはcmdでシェルを起動する前にcdしてるだけ。

-[use-]full-path

Windowsのパスを継承する。

内部的には環境変数MSYS2_PATH_TYPEinheritを設定している。

-no-start

新窓で開かない。

内部的には指定した場合はシェルが直に起動し、指定しない場合startコマンドでシェルが起動するようになっている。

-shell SHELL

ログインシェルを指定する。

例えば-shell zshならzshがログインシェルになる。未指定の場合、bashがログインシェルになる。これはmsys2_shell.cmdでデフォルト値がbashになっているため。

参考までにmsys2_shell.cmdset "LOGINSHELL=bash"を書き換えるとアップデート時に上書きされて消えるので、しないほうがいい。

-help | --help | -? | /?

ヘルプの表示。

内部的にはprinthelpラベルに飛んでいる。

トラブルシューティング

zsh-newuser-install: startup files exist, aborting. Use the argument -f if you want to force the function to be run again.と出る

zsh-newuser-install: startup files exist, aborting.

Use the argument -f if you want to force the function to be run again.>

と出る場合の対処方法。

msys64/usr/share/zsh/scripts/newuserというファイルを消せば出なくなる。

2022/02/13(日)MSYS2でzshのGitプロンプトを快適に使う方法

更新日:
投稿日:

MSYS2でzsh使いたくない?使いたいよね?そう、使いたい!
しかしその上で一つ大きな障害があります
MSYS2のzshでプロンプトにGitのブランチを表示させようとすると微妙に上手くいきません

問題

.zshrcを使ってPROMPTに現在のGitブランチの状態を表示させようとするとフリーズするケースがあります
具体的には以下のような設定を書くとターミナルのサイズ変更時にシェルがフリーズします
原因は不明ですがPROMPT='$(git)'だけでフリーズするのでGit for Windowsとの相性がなにか良くないのだと思っています

# git functions

current_git_branch() {
  (git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/')
}

parse_git_dirty() {
  local DIRTY=$(git status -s | tail -1)
  if [[ -n $DIRTY ]]; then
    echo "%{$fg_bold[magenta]%})%{$fg_bold[red]%}✗"
  else
    echo "%{$fg_bold[magenta]%})%{$fg_bold[blue]%}✓"
  fi
}

print_git_prompt() {
  local FIND_BRANCH=$(git branch 2> /dev/null | tail -1)
  if [[ -n $FIND_BRANCH ]]; then
    echo "%{$fg_bold[magenta]%}(%{$reset_color%}%{$fg_bold[yellow]%}"$(current_git_branch)$(parse_git_dirty)" %{$reset_color%} "
  else
    echo ""
  fi
}

# setting propmt

PROMPT="
%{$fg_bold[cyan]%}%n%{$reset_color%}%{$fg_bold[blue]%}@%m%{$reset_color%}:%{${fg_bold[green]}%}%~%{$reset_color%}
%(?:%{$fg_bold[green]%}➜:%{$fg_bold[red]%}➜)  %{${reset_color}%}"'$(print_git_prompt)'

RPS1="%(?..%{$fg_bold[red]%} [ %? ]%{$reset_color%}) %D - %*"

解決策1

プロンプト表示に使うgitバイナリだけmsys2の物に差し替えると上手くいくようになります
具体的には以下のようにしてGit for Windowsと競合しないようにMSYS2のGitを構成しPROMPT='$(msys2_git)'のように呼び出してやると上手くいきます

pacman -S git
mv /usr/bin/git /usr/bin/msys2_git

課題

  • msys2/gitをアップデートするときに毎回リネームをする必要がある
  • ここが面倒で脆弱性に繋がる可能性がゼロではない

解決策2

Git for Windowsだけでやる場合の方法です
add-zsh-hook precmdでプロンプトに出したいコマンドを呼び出し、変数の値を書き換えてそれを表示するスタイルでやると上手くいきます

課題

  • プロンプトの速度が遅い
  • プロンプトする時に一瞬フォーカスが飛ぶ(別プロセルがコールされ一瞬窓ができている気がする

2021/03/18(木)MSYS2でのzshのread -qエラー対策

更新日:
投稿日:

MSYS2のzshで.zshを叩いたときに次のエラーが出るときの対策

./test.zsh: 2 行: read: -q: 無効なオプションです
read: 使用法: read [-ers] [-a array] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [name ...]

動かないシェルスクリプトのサンプル

  • 但しこれは動く
    • echo "yes or no (y/N): "; if read -q; then; echo hello; else echo abort; fi
echo 'yes or no (y/N): '
if read -q; then
  echo y
else
  echo n
fi

解決方法

  • 次のようにshebangを入れてやる
    • 多分shが呼ばれているのだと思う
#!/bin/zsh

echo 'yes or no (y/N): '
if read -q; then
  echo y
else
  echo n
fi