Git で開発をしている中でリポジトリによって設定を変えたいことがあります。たとえばコミット時の名前やメールアドレスなどを使い分けたいといったケースです。このような場合に有用な Git の Conditional includes を使った自動切り替えの方法について紹介します。
Gitでコミットする際の名前やメールアドレス、多くの場合は全体設定git config --global
にしているかと思います。通常は問題ないのですが、リポジトリによって設定を変えたいこともあります。そのような場合はgit config --local
を使いリポジトリ単体の設定ができます。
しかしながら、そのようなリポジトリが増えてくるとクローンするたびごとに設定が必要となり手間です。場合によっては設定忘れでエラーになったり、悪い場合はアカウント名を間違えてコミットすることもあり得ます。できればリポジトリをまとめるディレクトリ単位などで設定したいところです。
今回は特定のパスに配置したリポジトリへ設定をインクルードするConditional includesを使い、設定をリポジトリごとに自動で使い分けるような仕組みを紹介します。
環境
本記事の開発環境は以下となります。
- Windows 10 64bit + WSL Ubuntu 18.04.1 LTS
- Git 2.21.0.windows.1 (Windows 10 64bit)
Git 2.17.1 (WSL Ubuntu 18.04.1 LTS)
参考情報
Git Conditional includes とは
バージョン 2.13.0 から追加された機能で、条件へマッチした場合に指定された設定ファイルをインクルードします。
条件はgitdir
とgitdir/i
で指定します。
どちらも glob パターンでパスを指定して、現在のディレクトリがパターンにマッチするかで判定されます。違いはgitdir/i
が大文字小文字を区別せずに判定します。
自動切り替えの設定例
設定は git config –global includeIf.”<条件>”.path “<設定ファイル>” のコマンドを実行します。
(とはいえコマンドは分かりにくいので、設定ファイルを直接編集してます)
たとえば、ホームディレクトリ以下のrepos
にwork
とoss
を作り、その下に関連するリポジトリを配置しているとします。
1 | ~/repos |
それぞれのディレクトリ名をインクルードするファイル名の一部に使い以下のようにしました。
※ 末尾が/
で終わる場合は、暗黙的に/**
の glob パターンになります
1 | git config --global includeIf."gitdir:~/repos/work/".path ".gitconfig_work" |
上記コマンドを実行した際の設定ファイル~/.gitconfig
は以下のようになります。(必要箇所のみ抜粋)
※ 今回はユーザー名とメールアドレスを切り替える想定なのでuseConfigOnly = true
でデフォルトのユーザー名を無効にしています
1 | [user] |
続いてインクルードされるファイル~/.gitconfig_work
と~/.gitconfig_oss
を作ります。
~/.gitconfig_work
1 | [user] |
~/.gitconfig_oss
1 | [user] |
自動切り替えの確認
それぞれのリポジトリ用ディレクトリ~/repos/work/
と~/repos/oss/
の下にリポジトリを配置して設定を確認します。どの設定ファイルが使われたかわかるようにgit config --show-origin --get user.name
を実行します。
~/repos/work
1 | ~/repos/work/wondrous-product$ git config --show-origin --get user.name |
~/repos/oss
1 | ~/repos/oss/astounding-software$ git config --show-origin --get user.name |
設定が切り替わっていること、また参照しているファイルも異なることが確認できます。
今回はユーザー名とメールアドレスを切り替えましたが、他の設定項目も同様に切り替えることができます。
注意点
ローカルの設定が優先される
設定ファイルの優先度は、そのまま適用されるのでglobal
とlocal
ではlocal
が優先されます。今回の設定はglobal
にしているので、local
の設定がある場合はそちらが優先されます。1
2~/repos/oss/local-config-service$ git config --show-origin --get user.name
file:.git/config Hot account name configured in localシンボリックリンクの場合は両方設定しておく
現在のディレクトリのパスが判定されているので、シンボリックのパスと、オリジナルのパスで有効にするには両方設定しておきます。私の環境は Windows 10 64bit + WSL Ubuntu 18.04.1 LTS で、Visual Studio Code のターミナルは WSL です。
しかしながら Windows の Eclipse でも作業することがあり、リポジトリの実態は Windows 側にあり/mnt/c/develop/repos/
を~/repos
にシンボリックリンクして使っています。(特殊なケースではありますが。。。)Visual Studio Code でターミナルを開くとオリジナルパスの
/mnt/...
が使われますが、自分でコマンドを打っているときはcd ~/repos/...
のようにシンボリックリンクから移動することが多いです。このような場合にマッチするパスが変わるので両方指定しておかないと切り替えが機能しません。余談ですが、Eclipse は 2019年6月現在543171 – Support for includeif in git configが上がっており includeif に対応していません。
Windows の場合は、パスの大文字小文字を区別したくないので
gitdir/i
を使う
これはドライブレターのC:
とc:
のレベルですでに大文字小文字の違いが出てしまうので区別しないようにします。またパスの区切りは Windows の\
ではなく、Linuxt などで使われる/
です。1
2
3
4
5
6
7[user]
useConfigOnly = true
[includeIf "gitdir/i:C:/develop/repos/work/"]
path = .gitconfig_work
[includeIf "gitdir/i:C:/develop/repos/oss/"]
path = .gitconfig_oss
これで作業環境ごとにgit config --local
で設定を追加する必要がなくなりました。
とくにアカウント名やメールアドレスは、複数の作業グループがある時に間違えコミットしないように注意が必要です。そのためにuseConfigOnly = true
を設定しますが、そうするとリポジトリごとに設定が必要となります。その際に、今回の設定をしておくと特定のディレクトリ以下に配置しておくだけで設定が反映されるので便利です。
最近は「OSS-Friday 活動 - 2019年5月まとめ」に書きましたように、わずかながら OSS への貢献活動も始めたのでリポジトリのクローンをすることが増え、今回のようにディレクトリで自動に切り替わってくれるのは助かります。