Gitで有効な設定を確認したい


Gitの設定は三つの異なるファイルに格納できます.
用途によって設定値を使い分けることができ大変便利な反面、設定項目が増えてくると「有効な設定値は何？」「どのファイルから読み込まれた設定値なの？」といった混乱が生じます.

git config --valid-listのような標準機能は提供されていない[^1]ため、`--name-only`と `--show-origin`のオプションで対処したいと思います.

## 結論

* [有効な設定だけを重複なく一覧する方法(Mac)](http://qiita.com/dhun/items/d794699158eb35aa572c#%E6%9C%89%E5%8A%B9%E3%81%AA%E8%A8%AD%E5%AE%9A%E3%81%A0%E3%81%91%E3%82%92%E9%87%8D%E8%A4%87%E3%81%AA%E3%81%8F%E4%B8%80%E8%A6%A7%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95mac)
* [有効な設定だけを重複なく一覧する方法(Mac：完全版)](http://qiita.com/dhun/items/d794699158eb35aa572c#%E3%81%8A%E3%81%BE%E3%81%91%E6%9C%89%E5%8A%B9%E3%81%AA%E8%A8%AD%E5%AE%9A%E3%81%A0%E3%81%91%E3%82%92%E9%87%8D%E8%A4%87%E3%81%AA%E3%81%8F%E4%B8%80%E8%A6%A7%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95mac%E5%AE%8C%E5%85%A8%E7%89%88)
* [有効な設定だけを一覧する方法(Windows)](http://qiita.com/dhun/items/d794699158eb35aa572c#%E6%9C%89%E5%8A%B9%E3%81%AA%E8%A8%AD%E5%AE%9A%E3%81%A0%E3%81%91%E3%82%92%E4%B8%80%E8%A6%A7%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95windows)

## git config --listの振る舞い

システム設定＞グローバル設定＞リポジトリ設定の順番に、設定項目を一覧します.
重複した設定項目はすべて出力され、最後に表示された設定値が有効な設定値となります.

```bash:~/.gitconfig
[core]
  ignorecase = false
  whitespace = trailing-space,space-before-tab
```
```bash:.git/config
[core]
  ignorecase = true
  whitespace = trailing-space
```
```bash
$ git config --list
core.ignorecase=false
core.whitespace=trailing-space,space-before-tab
core.ignorecase=true           # これが有効
core.whitespace=trailing-space # これが有効
```

## --name-onlyオプション

git config --listに指定すれば、設定項目の名前だけを一覧できます.

```bash
$ git config --list --name-only
core.ignorecase
core.whitespace
core.ignorecase
core.whitespace
```

## --show-origin(Mac/Linux限定)

git config --listに指定すれば、設定項目が定義されたファイル名と有効な設定値を一覧できます.
※Git for Windows[^2]に同梱されたGitではこのオプションはありませんでした

```bash
$ git config --list --show-origin
file:/Users/xxx/.gitconfig	core.ignorecase=false
file:/Users/xxx/.gitconfig	core.whitespace=trailing-space,space-before-tab
file:.git/config	core.ignorecase=true
file:.git/config	core.whitespace=trailing-space
```


## 有効な設定だけを重複なく一覧する方法(Mac)

このスクリプトで、設定項目を解決したファイル名と有効な設定値を重複なく一覧できます.

```bash:list_valid-gitconfig.sh
for KEY in `git config --list --name-only | sort | uniq`; do
    VALUE=(`git config --show-origin $KEY`)
    FILE=${VALUE[0]}
    unset VALUE[0]
    [ ${#VALUES[*]} = 0 ] && VALUE="" || VALUE=${VALUES[*]}
    echo -e "$FILE\\t$KEY=[$VALUE]"
done
```
```bash:出力
file:/Users/xxx/.gitconfig	core.ignorecase=[true]
file:.git/config	core.whitespace=[trailing-space]
```

一覧する項目を指定できる完全版は [こちら](http://qiita.com/dhun/items/d794699158eb35aa572c#%E3%81%8A%E3%81%BE%E3%81%91%E6%9C%89%E5%8A%B9%E3%81%AA%E8%A8%AD%E5%AE%9A%E3%81%A0%E3%81%91%E3%82%92%E9%87%8D%E8%A4%87%E3%81%AA%E3%81%8F%E4%B8%80%E8%A6%A7%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95mac%E5%AE%8C%E5%85%A8%E7%89%88)

## 有効な設定だけを一覧する方法(Windows)

Windowsでは `--show-origin`オプションが使えないため、設定項目を解決したファイル名は確認できません.
`uniq`コマンドも使えないため設定項目の重複も解消できませんが、有効な設定値だけを一覧表示することはできます.
あまり便利ではありませんが、有効な値を探さなくても良くなるため一応掲載します.

```bat:list_valid-gitconfig.bat
for /f "usebackq" %%i in (`git config --list --name-only`) do (
    call :ECHO_CONFIG %%i
)
goto :eof

:ECHO_CONFIG
    set KEY=%~1
    set /p NULL=%KEY% = < nul
    git config %KEY%
    goto :eof
```
```DOS:出力
core.ignorecase = true
core.whitespace = trailing-space
core.ignorecase = true
core.whitespace = trailing-space
```

## aliasとのコラボレーション

前述した処理をファイルに保存してエイリアス定義すれば、もう少し幸せになれます.

```bash
git config alias.configv '!/usr/local/bin/list-valid-gitconfig.sh' # 外部コマンドを示す `!`が必要
git configv
```
```bash:出力
file:/Users/xxx/.gitconfig	core.ignorecase=[true]
file:.git/config	core.whitespace=[trailing-space]
```

## おまけ：有効な設定だけを重複なく一覧する方法(Mac：完全版)

このスクリプトで、設定項目を解決したファイル名と有効な設定値を重複なく一覧できます.
設定項目名のパターンをパラメータに渡すことで、指定した設定項目だけを一覧することもできます.

```bash:list_valid-gitconfig.sh
#!/bin/bash -u
# ##########################################################
# 機  能：有効なGit設定を一覧する
# 引  数：$1 省略可）一覧する設定名のパターンを正規表現で指定する
#                    省略された場合は、すべての設定を一覧する
# 戻り値：なし
[ $# = 0 ] && PATTERNS=(".") || PATTERNS=($*)

for KEY in `git config --list --name-only | sort | uniq`; do
    while :
    do
        for PATTERN in ${PATTERNS[*]}; do
            [[ "$KEY" =~ .*$PATTERN.* ]] && break 2
        done
        continue 2
    done

    VALUE=(`git config --show-origin $KEY`)
    FILE=${VALUE[0]}
    unset VALUE[0]
    [ ${#VALUES[*]} = 0 ] && VALUE="" || VALUE=${VALUES[*]}
    echo -e "$FILE\\t$KEY=[$VALUE]"
done
```
```bash:出力
$ git configv
file:/Users/xxx/.gitconfig	core.ignorecase=[true]
file:.git/config	core.whitespace=[trailing-space]
```
```bash:出力
$ git configv ignore
file:/Users/xxx/.gitconfig	core.ignorecase=[true]
```

[^1]: 標準機能で提供してほしいなぁ
[^2]: Git for Windows v2.7.2で確認しました