Open4

Xcode CLTのgitでconfig -l --systemがエラー → Apple-Gitの設定ファイルの扱いについて少し調べた

oddstroddstr

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を叩いた時にも指定内容が表示されるのが正しい動作な気もするんだけど、どうなんだろう。

oddstroddstr

少し古いが、こちらのGistにconifgがどのファイルから読まれるかまとめられていた。

https://gist.github.com/ChrisTollefson/ab9c0a5d1dd4dd615217345c6936a307

これによると、built-inのデフォルト(これはgit config -lでは表示されない)と--systemとの間に"Core" configurationとして読み込まれるもので、--system--global--localのいずれも指定しなかった時のみ一緒に表示され、"Core"だけを表示するオプションはない(し、書き込む際に無指定だとlocalになるのでgit configで書き込む手段はない)、らしい。

oddstroddstr

Appleのソースリポジトリが公開されてることに気づいたので上流のgit/gitとの差分を眺めてみた。
(斜め読みしただけでデバッガを動かしたりはしてないので間違いがあったらコメントで指摘いただければ幸いです)

対応するバージョンのソースツリーはこの2つ。

https://github.com/git/git/tree/v2.39.3
https://github.com/apple-oss-distributions/Git/tree/Git-145/src/git

まず、config.hに設定のスコープとしてCONFIG_SCOPE_XCODEが追加されている。

https://github.com/git/git/blob/v2.39.3/config.h#L38-L46

https://github.com/apple-oss-distributions/Git/blob/Git-145/src/git/config.h#L38-L47

config.cにある設定ファイル読み込みシーケンス‎do_git_config_sequence()に、このスコープをセットして行う処理が追加になっている。

https://github.com/git/git/blob/v2.39.3/config.c#L2132-L2143

https://github.com/apple-oss-distributions/Git/blob/Git-145/src/git/config.c#L2140-L2156

git_xcode_gitconfig()は実行ファイルのパスから求めたprefixを相対パスに加えるもの。

https://github.com/apple-oss-distributions/Git/blob/Git-145/src/git/config.c#L2095-L2101

まとめると、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スコープ追加への対応はなされていない。

https://github.com/apple-oss-distributions/Git/blob/Git-145/src/git/builtin/config.c#L639-L675

なので、--system指定時はSYSTEMスコープのものだけに絞られ、XCODEスコープのものは無視される。

https://github.com/apple-oss-distributions/Git/blob/Git-145/src/git/builtin/config.c#L699-L702

oddstroddstr

見落としていたが、git configには設定ファイルの場所を出力する--show-origin以外にスコープを出力する--show-scopeオプションもある。

% xcrun --run git config -l --show-scope
unknown credential.helper=osxkeychain
unknown init.defaultbranch=main
...

うーん思いっきりunknownになってた。

これはconfig.cconfig_scope_name()CONFIG_SCOPE_XCODEに対応していないため。

https://github.com/apple-oss-distributions/Git/blob/Git-145/src/git/config.c#L3822-L3840