Technically Impossible

Lets look at the weak link in your statement. Anything "Technically Impossible" basically means we haven't figured out how yet.

Visual StudioとGitHubの連携、証明書に関するエラー - 複数のgitconfigに起因する問題


ITに関わりのあるユーザーにGitHubが普及し、彼らが利用するツールやサービスも、その連携を意識するようになった。ツールや製品によっては、それ専用のGitをインストールくらいだ。

同時に、これが無用なトラブルを招く間接的な原因にもなっている気がしている。その典型例が、冒頭に掲載した画像が示すエラーだ。Visual StudioGitHubと同期する際に問題が発生している。

この問題が生じる<直接的>な原因は、エラー・メッセージが示すように、「指定パスに証明書が保存されていない」ことに起因している。あえて<直接的>と強調しているのは、このエラーが生じる間接的な原因が存在するからだ。いうなれば「原因の原因」だ。それは冒頭に触れた事柄が関係している。

この投稿では、次の事柄について触れる。

根本的な原因の特定 コマンド”git config”
直接的な原因に対する対応 ファイル”gitconfig”の編集
ありがちな対応と、その問題点 証明書のコピー
「原因の原因」に対する対応  

根本的な原因の特定

証明書(CRTファイル)と、その保存先は、ファイル”gitconfig”の[http]セクションに記述されている。まずVisual StudioとともにインストールされたGitが、どのように設定されているのかを確認する。

Visual StudioとともにインストールされたGitは、次のフォルダに格納されている。

C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer\Git\mingw32\bin

該当フォルダにて、次のコマンドを実行する。

git config -l --show-origin

コマンドの出力

file:C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/TeamFoundation/Team Explorer/Git/etc/gitconfig	core.symlinks=false
file:C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/TeamFoundation/Team Explorer/Git/etc/gitconfig	core.autocrlf=true
file:C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/TeamFoundation/Team Explorer/Git/etc/gitconfig	color.diff=auto
file:C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/TeamFoundation/Team Explorer/Git/etc/gitconfig	color.status=auto
file:C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/TeamFoundation/Team Explorer/Git/etc/gitconfig	color.branch=auto
file:C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/TeamFoundation/Team Explorer/Git/etc/gitconfig	color.interactive=true
file:C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/TeamFoundation/Team Explorer/Git/etc/gitconfig	pack.packsizelimit=2g
file:C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/TeamFoundation/Team Explorer/Git/etc/gitconfig	help.format=html
file:C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/TeamFoundation/Team Explorer/Git/etc/gitconfig	http.sslcainfo=%(prefix)/ssl/certs/ca-bundle.crt
file:C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/TeamFoundation/Team Explorer/Git/etc/gitconfig	diff.astextplain.textconv=astextplain
file:C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/TeamFoundation/Team Explorer/Git/etc/gitconfig	rebase.autosquash=true
file:C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/TeamFoundation/Team Explorer/Git/etc/gitconfig	filter.lfs.clean=git-lfs clean -- %f
file:C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/TeamFoundation/Team Explorer/Git/etc/gitconfig	filter.lfs.smudge=git-lfs smudge -- %f
file:C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/TeamFoundation/Team Explorer/Git/etc/gitconfig	filter.lfs.process=git-lfs filter-process
file:C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/TeamFoundation/Team Explorer/Git/etc/gitconfig	filter.lfs.required=true
file:C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/TeamFoundation/Team Explorer/Git/etc/gitconfig	credential.helper=manager-core
file:C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/TeamFoundation/Team Explorer/Git/etc/gitconfig	credential.https://dev.azure.com.usehttppath=true
file:C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/TeamFoundation/Team Explorer/Git/etc/gitconfig	include.path=C:/Program Files (x86)/Git/etc/gitconfig
file:C:/Program Files (x86)/Git/etc/gitconfig	core.symlinks=false
file:C:/Program Files (x86)/Git/etc/gitconfig	core.autocrlf=true
file:C:/Program Files (x86)/Git/etc/gitconfig	color.diff=auto
file:C:/Program Files (x86)/Git/etc/gitconfig	color.status=auto
file:C:/Program Files (x86)/Git/etc/gitconfig	color.branch=auto
file:C:/Program Files (x86)/Git/etc/gitconfig	color.interactive=true
file:C:/Program Files (x86)/Git/etc/gitconfig	pack.packsizelimit=2g
file:C:/Program Files (x86)/Git/etc/gitconfig	help.format=html
file:C:/Program Files (x86)/Git/etc/gitconfig	http.sslcainfo=/bin/curl-ca-bundle.crt
file:C:/Program Files (x86)/Git/etc/gitconfig	sendemail.smtpserver=/bin/msmtp.exe
file:C:/Program Files (x86)/Git/etc/gitconfig	diff.astextplain.textconv=astextplain
file:C:/Program Files (x86)/Git/etc/gitconfig	rebase.autosquash=true
file:C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/TeamFoundation/Team Explorer/Git/etc/gitconfig	include.path=C:/Program Files/Git/etc/gitconfig
file:C:/Users/%USERNAME%/.gitconfig	filter.lfs.clean=git-lfs clean -- %f
file:C:/Users/%USERNAME%/.gitconfig	filter.lfs.smudge=git-lfs smudge -- %f
file:C:/Users/%USERNAME%/.gitconfig	filter.lfs.process=git-lfs filter-process
file:C:/Users/%USERNAME%/.gitconfig	filter.lfs.required=true
file:C:/Users/%USERNAME%/.gitconfig	user.name=espio999
file:C:/Users/%USERNAME%/.gitconfig	user.email=espio999@users.noreply.github.com

この出力を確認すると、異なる複数の”gitconfig”を参照していることが分かる。次の3つだ。ちなみに、Visual StudioとともにインストールされたGitを「VSGit」と呼んでいる。

  • VSGitのシステム設定
C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/TeamFoundation/Team Explorer/Git/etc/gitconfig
  • VSGitのユーザー設定
C:/Users/%USERNAME%/.gitconfig
  • Gitのシステム設定
C:/Program Files (x86)/Git/etc/gitconfig

それぞれの[http]セクションの設定値を確認すると、システム設定に食い違いがあるのが分かる。

VSGit sslCAinfo = %(prefix)/ssl/certs/ca-bundle.crt
Git sslCAinfo = /bin/curl-ca-bundle.crt

ここで問題に気付く。本来のパスはVSGitのものであるべきなのだが、VSGitとGitの設定が合成された結果、あり得ないパスが生成される。Visual Studioは、あり得ないパスを参照し、結果として問題が生じている。

  • あり得ないパス。
C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer\Git\mingw32\bin\curl-ca-bundle.crt
  • あるべきパス。
C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer\Git\mingw32\ssl\certs\ca-bundle.crt

直接的な原因に対する対応

gitconfigの設定は継承されるので、優先される方の設定が有効となる。継承は避けられないので、あり得ないパスを修正するのではなく、あり得ないパスが「生成されない」ようにするのが、率直な対応となるだろう。
つまり、Gitのgitconfigを編集し、次のように該当箇所をコメントにすればよい。

[http]
	;sslCAinfo = /bin/curl-ca-bundle.crt

ありがちな対応と、その問題点

Gitが指定するパスに証明書(CRTファイル)が存在しないのだから、そのパスへ証明書をコピーする、という方法もある。具体的には、前述の「あるべきパス」で指定されているCRTファイルを、「あり得ないパス」へコピーするのだ。しかし、この方法は推奨しない。

例えば、新しいVisual Studioをインストールしたとき、そのフォルダ配下に、さらに異なるGitが、新たに生成された証明書とともに導入される可能性がある。このとき、再び

  • あるべきパス
  • あり得ないパス

が生成されることになる。証明書をコピーするならば、新しいVisual Studioインストール後に生成された証明書を、「あり得ないパス」へコピーすることになる。

「あるべきパス」での運用を前提とするならば、対処すべきは証明書ではなく、そのパスを正確に維持し続けることだと思うのだ。

余談:「原因の原因」に対する対応

特定のツールやサービスの導入に際し、それが連携するツールも一緒にインストールしてくれるのは、その場面に限っては便利でお手軽だ。しかし将来、問題となり得る原因を、自ら意図せず仕掛けることにも通じている。

例えば、Gitの場合、

  • 個別インストールのGit
  • GitHub Desktop*1がインストールするGit
  • Visual StudioがインストールするGit

さらにひどいのはPythonだ。思いつくだけでも、

などなど、

便利さとお節介の結果、無用に重複した環境が混在することになる。最良なのは、パッケージ・ベンダーが配慮して、個別インストールしたものとの連携を強化する、あるいはそれらと連携させるための設定をオープンにすることだが、現状では便利さとお節介の「押しつけ」が、彼らのやり方だ。
そもそも今回の問題はVisual Studio 2017のころから発生しており*3、いまだに継承され続けている問題なのだ。

ユーザーのできる対応方法は、何を残して、何を消すか、取捨選択を伴う環境整備を怠らないことだろう。