Xcode CLTのgitでconfig -l --systemがエラー → Apple-Gitの設定ファイルの扱いについて少し調べた
Xcode CLT(Command Line Tools)でインストールされるgitを使って初期設定をしている際、systemレベルの最初から設定されているconfigがどこに書かれているのか分からず少しハマった。
% xcode-select --print-path
/Library/Developer/CommandLineTools
% which git
/usr/bin/git
% xcrun --find git
/Library/Developer/CommandLineTools/usr/bin/git
% git --version
git version 2.39.3 (Apple Git-145)
% git config -l
credential.helper=osxkeychain
init.defaultbranch=main
% git config -l --system
fatal: unable to read config file '/etc/gitconfig': No such file or directory
% git config -l --global
fatal: unable to read config file '/Users/***/.gitconfig': No such file or directory
結局、--show-origin
オプションで指定場所を確認できることがわかったので解決。
% git config -l --show-origin
file:/Library/Developer/CommandLineTools/usr/share/git-core/gitconfig credential.helper=osxkeychain
file:/Library/Developer/CommandLineTools/usr/share/git-core/gitconfig init.defaultbranch=main
% cat /Library/Developer/CommandLineTools/usr/share/git-core/gitconfig
[credential]
helper = osxkeychain
[init]
defaultBranch = main
ただ、git config -l --system
を叩いた時にも指定内容が表示されるのが正しい動作な気もするんだけど、どうなんだろう。
少し古いが、こちらのGistにconifgがどのファイルから読まれるかまとめられていた。
これによると、built-inのデフォルト(これはgit config -l
では表示されない)と--system
との間に"Core" configurationとして読み込まれるもので、--system
、--global
、--local
のいずれも指定しなかった時のみ一緒に表示され、"Core"だけを表示するオプションはない(し、書き込む際に無指定だとlocalになるのでgit config
で書き込む手段はない)、らしい。
Appleのソースリポジトリが公開されてることに気づいたので上流のgit/gitとの差分を眺めてみた。
(斜め読みしただけでデバッガを動かしたりはしてないので間違いがあったらコメントで指摘いただければ幸いです)
対応するバージョンのソースツリーはこの2つ。
まず、config.h
に設定のスコープとしてCONFIG_SCOPE_XCODE
が追加されている。
config.c
にある設定ファイル読み込みシーケンスdo_git_config_sequence()
に、このスコープをセットして行う処理が追加になっている。
git_xcode_gitconfig()
は実行ファイルのパスから求めたprefixを相対パスに加えるもの。
まとめると、Apple-Gitの設定読み込みでは
- まず
xcode-select
で設定されたパス以下にあるXcode付属のgitconfigがCONFIG_SCOPE_XCODE
スコープで読み込まれ、 - 次に通常のsystemレベルの設定ファイルが
CONFIG_SCOPE_SYSTEM
スコープで読み込まれる。 -
GIT_CONFIG_NOSYSTEM
環境変数(git_config_system()
でチェックされる)はこの両者を抑制する。
一方、builtin/config.c
にあるgit config
サブコマンドの処理では特にXCODEスコープ追加への対応はなされていない。
なので、--system
指定時はSYSTEMスコープのものだけに絞られ、XCODEスコープのものは無視される。
見落としていたが、git config
には設定ファイルの場所を出力する--show-origin
以外にスコープを出力する--show-scope
オプションもある。
% xcrun --run git config -l --show-scope
unknown credential.helper=osxkeychain
unknown init.defaultbranch=main
...
うーん思いっきりunknownになってた。
これはconfig.c
のconfig_scope_name()
がCONFIG_SCOPE_XCODE
に対応していないため。