パソコンでプログラミングしよう ウィンドウズC++プログラミング環境の構築
1.6.3.6(15)
Git for Windows

バージョン管理システムとして導入されるGit for Windowsを説明する。

Git for Windowsは専用のカスタムMSYS2を持つが、このカスタムMSYS2を先に導入した正規MSYS2ウィンドウズ環境で共存させるための注意が必要になる。

Gitは分散型バージョン管理システムで、ソフトウェアリモートホスティングサイトGitHubやBitbucketなどのクライアントとして使われる事が多い。

本サイトはあくまでもローカル運用に限定し、個人ベースのアプリケーション開発に利用する。

msys/gitとGit for Windows

本サイトで導入できるGitは以下のいずれかである。

名称 導入環境 導入方法 実行環境
msys/git MSYS2 MSYS2パッケージ(pacman -S git) 正規MSYS2のmsys2サブシステム
Git for Windows ウィンドウズ インストーラのダウンロード実行 カスタムMSYS2のmingw32/mingw64サブシステム

両者の関係について整理された情報が乏しく、上記リンクを含め混乱する。先ずは以下を留意する。

  • Git for Windowsの古いバージョンはmsysGitと呼ばれていた。この呼称はmsys/gitと容易に混乱する。
  • Git for WindowsのMSYS2パッケージとしてgit-for-windows/mingw-w64-i686-gitおよびgit-for-windows/mingw-w64-x86_64-gitが存在する(らしい)。

以下はサイト作成者の確信の持てない理解で、誤解があれば指摘いただきたい。

  1. Gitはユニックスライクをターゲットに開発された。
  2. GitはMSYS2へ移植されmsys/gitとしてmsys2サブシステムへ導入できる。これはレイヤーDLL(msys2.0.dll)依存でウィンドウズネイティブでない。
  3. msys/gitはウィンドウズ環境での稼働で多くの不具合を抱える。
    • 遅い。
    • ウィンドウズパス名を正しく扱えない。
    • ...
  4. 不具合を解決するためmingw32/mingw64サブシステムへ導入するGitウィンドウズネイティブ版(git-for-windows/mingw-w64-i686-git、git-for-windows/mingw-w64-x86_64-git)が開発された。
  5. しかしGitはbashとperlのスクリプトを用いるなどでウィンドウズネイティブ版であってもmsys2サブシステムに大きく依存する。
  6. 従って不具合の完全解決にはmsys2サブシステム(msys2.0.dllなど)を修正する必要があった。
  7. MSYS2のフォークを作成しmsys2サブシステムを修正して不具合を満足できるレベルで解決した。
  8. フォーク(カスタムMSYS2)をメインブランチ(正規MSYS2)へプルリクエストするための努力を長く続けたが、不可能と判断しフォークのまま維持していく事とした。
  9. Gitウィンドウズネイティブ版はフォークされているカスタムMSYS2と共にウィンドウズインストーラでGit for Windowsとして配布される。
  10. 正規MSYS2にGitウィンドウズネイティブ版パッケージを導入する事は可能だが、その場合はMSYS2に独力で非正規パッチを当てる必要がある。
覚え書き
Git for Windowsはbash.exe/perl.exeを通しmsys2.0.dllを利用する。msys2.0.dllが修正されていることは間違いないが、bash.exe/perl.exeが修正されているかどうかはっきりしない。またGitが関わるスクリプトも修正されているらしい。これらの修正を明記するドキュメントは変更履歴以外に存在せず、面倒なので修正されているファイルを"msys2.0.dllなど"で一括する。

なぜ修正を正規MSYS2へプルリクエストできなかったかを知るには変更履歴を読めとの事で、例えばPOSIXとウィンドウズ相互のパス名マングリングがGitリグレッションテストをパスするためのパッチがMSYS2の基準に合わないそうだ(Integrate our mingw-w64-git into MSYS2 proper:dscho commented on 29 Mar 2016)。

なおGit for WindowsはDLLアドレッシングに不具合を発生する可能性があり64ビット版の使用が推奨されている(リンク先を読む限りMSYS2の問題に見えるが)。

複数MSYS2の共存

本サイトのMSYS2導入を整理する。

目的 MSYS2 インストールディレクトリ POSIXホーム サブシステム ビット ディレクトリ binサブディレクトリ
コンパイラ 正規 C:\msys64 /home/user msys2 64ビット /usr msys2.0.dll, bash.exe, perl.exeなど
mingw32 32ビット /mingw32 i686-w64-mingw32-g++.exeなど
mingw64 64ビット /mingw64 x86_64-w64-mingw32-g++.exeなど
Git for Windows カスタム C:\Program Files\Git /c/Users/user msys2 64ビット /usr msys2.0.dll, bash.exe, perl.exeなど
mingw64 64ビット /mingw64 git.exeなど

各POSIXサブシステムのランチャーはウィンドウズ上にPOSIX互換ターミナルを起動し、それぞれの定めるコマンドサーチパスの下にPOSIX互換シェルの"コマンドプロンプト(コマンド受け入れ準備を示す文字列)"を表示する。従ってそれぞれの環境は他のPOSIXサブシステムおよびウィンドウズ環境と基本的に干渉しない。問題はこれらをウィンドウズ環境から利用する場合で、例えばカスタムMSYS2のmingw64サブシステムにあるGit for Windowsの実行ファイルgit.exeを起動したとしよう。仮に環境変数PATHなどが定めるコマンドサーチパスでC:\msys64\msys2\usr\binがC:\Program Files\Git\msys2\usr\binより前にあるとすれば、カスタムMSYS2ではなく正規MSYS2のmsys2.0.dllなどをコールしてしまう事になる。

git.exeラッパー

Git for Windowsはこの問題を回避するためgit.exeのラッパーとなる同名の実行ファイルを用意する。Git for Windowsにインストールされているgit.exeという名称のファイルを以下にまとめる。

相対パス名 サイズ 内容 備考
mingw64\bin\git.exe 2.83MiB git.exe(本物)
mingw64\libexec\git-core\git.exe 2.83MiB git.exe(本物) mingw64\bin\git.exeのコピー
bin\git.exe 42.52KiB git.exeラッパー
cmd\git.exe 42.52KiB git.exeラッパー bin\git.exeのコピー

git.exeラッパーは環境変数PATHなどに必要な修正を加えてgit.exe(本物)を子プロセスとして起動するため、いかなる環境からも安全にgit.exeが実行される事を保証する。ウィンドウズ環境からの実行は、従ってgit.exe(本物)ではなくgit.exeラッパーを使用する。以下はmsysGit時代の古いリンクで一部の記述が現在のGit for Windowsと合わないが、開発者は明確に付属するPOSIX互換ターミナル以外からGit for Windowsを利用するにはgit.exeラッパーを用いるものとしている。

C:\Program Files\Git\binディレクトリとC:\Program Files\Git\cmdディレクトリを示す。古いバージョンはラッパーをスクリプトで実装していたため、その互換性からcmdディレクトリにもコピーが配置される。それぞれのディレクトリにおいてgit.exe以外のラッパー実行ファイル(例えばbash.exeラッパー)が存在する。

C:\Program Files\Git\bin>dir
ドライブ C のボリューム ラベルがありません。
ボリューム シリアル番号は 2E9E-F9B2 です
C:\Program Files\Git\bin のディレクトリ
2019/07/06 14:57 <DIR> .
2019/07/06 14:57 <DIR> ..
2019/06/08 06:14 44,064 bash.exe
2019/06/08 06:14 43,544 git.exe
2019/06/08 06:14 44,064 sh.exe
3 個のファイル 131,672 バイト
2 個のディレクトリ 85,526,999,040 バイトの空き領域
C:\Program Files\Git\cmd>dir
ドライブ C のボリューム ラベルがありません。
ボリューム シリアル番号は 2E9E-F9B2 です
C:\Program Files\Git\cmd のディレクトリ
2019/07/06 14:57 <DIR> .
2019/07/06 14:57 <DIR> ..
2019/06/08 06:14 151,584 git-gui.exe
2019/06/08 06:14 43,544 git.exe
2019/06/08 06:14 151,576 gitk.exe
2019/06/08 06:14 3,022 start-ssh-agent.cmd
2019/06/08 06:14 2,723 start-ssh-pageant.cmd
5 個のファイル 352,449 バイト
2 個のディレクトリ 85,526,794,240 バイトの空き領域

なおPOSIX環境の/binディレクトリは/usr/bin(msys2サブシステム)へのリンクで、ウィンドウズ環境C:\Program Files\Git\binディレクトリと全く異なる。

Sourcetree

本サイトはSourcetreeをGit for Windowsのグラフィカルインターフェースとして使用する。Sourcetreeは最初の実行時にディレクトリを探索しC:\Program Files\Git\cmd\git.exeをGit for Windows実行ファイルとして記憶する。