😺

SSHコマンドを切り替える .gitconfig の工夫

に公開

前回の記事では、1PasswordのSSHエージェント機能を活用して、WSL環境でWindows側のssh.exeを使用する設定について紹介しました。

git config --global core.sshCommand ssh.exe

https://zenn.dev/ashita_team/articles/5b9d7f374d17ac

これでWSL上からでも、Windowsに保存されたSSHキーを使ってGitHubなどにアクセスできるようになりました。
しかし、開発環境で devcontainer を利用している場合には、少し問題が発生します。

devcontainerでの問題

VS Codeのdevcontainer内からGitを利用しようとすると、ssh.exe が存在しないためエラーになります。

たとえば、git fetch をすると以下のような感じで失敗します。

ssh.exe: command not found

解決方法

ここで役立つのがGitの includeIf 機能です。

.gitconfig に以下のように書いておくと、特定のディレクトリ配下でのみ別の設定ファイルを読み込むことができます。

[includeIf "gitdir:/workspaces/*/"]
    path = ~/.gitconfig-devcontainer

ここでは /workspaces 以下を条件にしています。
これは、devcontainerを利用するときに /workspaces/リポジトリ名/ という構造になることが多いためです。

devcontainer用の .gitconfig

次に、~/.gitconfig-devcontainer を用意して以下のように記述します。

[core]
    sshCommand = ssh

この設定により
通常は ssh.exe を使う(WSL → WindowsのSSHキーを利用)
/workspaces/* 配下では ssh を使う(devcontainer内で動作)
という切り替えが自動的に行われます。

なお、Gitの設定は「後勝ち」なので、最後に読み込まれた sshCommand が有効になります。

includeIf の詳細

includeIf にはいくつかの条件指定があり、用途によって使い分けられます。

gitdir

リポジトリのパスが指定パターンに一致する場合に読み込む。
例:

[includeIf "gitdir:~/work/project/"]
    path = ~/.gitconfig-project

~/work/project/ 以下のリポジトリでだけ有効。

onbranch

特定のブランチにいる場合に読み込む。
例:

[includeIf "onbranch:feature/*"]
    path = ~/.gitconfig-feature

feature/* ブランチのときだけ有効。

hasconfig:remote.*.url

リポジトリに特定のremoteが設定されている場合に読み込む。
例:

[includeIf "hasconfig:remote.*.url:git@github.com:myorg/**"]
    path = ~/.gitconfig-github

→ GitHubの特定リポジトリを扱うときだけ有効。

💡 このように、includeIf を使えば ディレクトリ・ブランチ・リモート先 に応じて設定を柔軟に切り替えることができます。

まとめ

  • WSLでは ssh.exe を使うことでWindows側の1PasswordのSSHエージェントを利用できる
  • しかしdevcontainer内からは ssh.exe が存在せずエラーになる
  • .gitconfig の includeIf を利用して環境ごとに sshCommand を切り替えることで解決できる
    これで、WSLとdevcontainerを併用した開発環境でも、ストレスなくGitを利用できます

💡 この仕組みは sshCommand に限らず、環境ごとに異なるGit設定を切り替えたいときにも応用できます。

参考リンク

Git Documentation - Conditional includes

あしたのチーム Tech Blog

Discussion