3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Git Submoduleで「誰がコミットしたか」がぐちゃぐちゃになる問題を解決するVSCode拡張を作った

3
Last updated at Posted at 2025-12-23

この記事は git Advent Calendar 2025 24日目の記事です。

TL;DR

  • Git Submoduleを使うと、メインリポジトリで設定した user.name / user.email がSubmoduleに反映されない
  • 複数のGitHubアカウント(個人+会社EMUなど)を使い分けていると、間違ったidentityでコミットしてしまう事故が起きる
  • ワンクリックでidentityを切り替え、Submoduleにも再帰的に適用するVSCode拡張を作った

この記事で解決する問題

問題1: Submoduleのidentity地獄

Hugoのテーマや依存ライブラリをSubmoduleで管理していると、こんな経験はないでしょうか。

# メインリポジトリでidentityを設定
git config user.name "Work Account"
git config user.email "work@company.com"

# Submodule内でコミット
cd themes/my-theme
git commit -m "fix: テーマ修正"

# → あれ、Personal Accountでコミットされてる...

Gitの --local 設定はリポジトリごとに独立しているため、Submoduleには自動で伝播しません。

問題2: SSH鍵の切り替え忘れ

複数のGitHubアカウントを使っていると:

# 会社リポジトリをcloneしようとして...
git clone git@github.com:company/internal-repo.git

# ERROR: Repository not found.
# → 個人アカウントのSSH鍵が使われている

問題3: GPG署名の設定漏れ

コミット署名を有効にしている場合、identity切り替え時にGPG鍵の設定も変える必要があります。

git config user.signingkey XXXXXXXX
git config commit.gpgsign true

これらを毎回手動でやるのは現実的ではありません。

解決策: Git ID Switcher

上記の問題をすべて解決するVSCode拡張を作りました。

主な機能

機能 説明
ワンクリック切り替え ステータスバーからidentityを選択するだけ
SSH鍵の自動切り替え ssh-agentの鍵を自動で入れ替え
GPG署名の自動設定 signingkeyと commit.gpgsign を自動設定
Submodule対応 再帰的にidentityを適用(深度5まで対応)
17言語対応 VSCodeがサポートする全言語に対応

インストール

VS Code Marketplace または Open VSX Registry からインストールできます。

VS Code Marketplace版:https://marketplace.visualstudio.com/items?itemName=nullvariant.git-id-switcher

Open VSX Registry版:https://open-vsx.org/extension/nullvariant/git-id-switcher

セットアップ

1. SSH鍵の準備

# 個人用
ssh-keygen -t ed25519 -C "personal@example.com" -f ~/.ssh/id_ed25519_personal

# 会社用
ssh-keygen -t ed25519 -C "work@company.com" -f ~/.ssh/id_ed25519_work

2. SSH configの設定

~/.ssh/config:

# 個人用(デフォルト)
Host github.com
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_ed25519_personal
    IdentitiesOnly yes

# 会社用
Host github-work
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_ed25519_work
    IdentitiesOnly yes

3. 拡張機能の設定

settings.json:

{
  "gitIdSwitcher.identities": [
    {
      "id": "personal",
      "icon": "🏠",
      "name": "Your Name",
      "email": "personal@example.com",
      "service": "GitHub",
      "description": "個人プロジェクト用",
      "sshKeyPath": "~/.ssh/id_ed25519_personal"
    },
    {
      "id": "work",
      "icon": "💼",
      "name": "Your Name",
      "email": "work@company.com",
      "service": "GitHub Enterprise",
      "description": "会社用(EMU)",
      "sshKeyPath": "~/.ssh/id_ed25519_work",
      "sshHost": "github-work"
    }
  ],
  "gitIdSwitcher.defaultIdentity": "personal",
  "gitIdSwitcher.autoSwitchSshKey": true,
  "gitIdSwitcher.applyToSubmodules": true
}

4. 使う

ステータスバーのアイコンをクリック → identityを選択 → 完了

技術的な仕組み

なぜSubmoduleに設定が伝播しないのか

Gitの設定には3つのレイヤーがあります:

System (/etc/gitconfig)
    ↓
Global (~/.gitconfig)
    ↓
Local (.git/config)  ← 最優先

git config --local はそのリポジトリの .git/config にのみ書き込まれます。

Submoduleは独立したリポジトリなので、メインリポジトリの --local 設定は参照しません。結果、Submodule内では --global の設定(または未設定)が使われます。

Git ID Switcherの解決方法

identity切り替え時に、以下を実行します:

  1. メインリポジトリの .git/config を更新
  2. git submodule foreach で全Submoduleを列挙
  3. 各Submoduleの .git/config を更新
  4. ネストしたSubmoduleがあれば再帰的に処理(設定した深度まで)
// 簡略化した実装イメージ
async function applyToSubmodules(identity: Identity, depth: number) {
  if (depth <= 0) return;
  
  const submodules = await getSubmodules();
  for (const submodule of submodules) {
    await setGitConfig(submodule.path, identity);
    await applyToSubmodules(identity, depth - 1); // 再帰
  }
}

おまけ: 17言語対応について

VSCodeがサポートする17言語すべてに対応しました。さらにREADMEはアイヌ語ハワイ語琉球諸語にも対応しています。

I value the existence of minorities.
I don't want to discard them just because they are small in number.

マイノリティ言語を「ユーザー数が少ないから」という理由で切り捨てたくなかったので、やりすぎかもしれませんが対応しました。AIの時代がきてよかったです。

対応言語一覧: https://github.com/nullvariant/nullvariant-vscode-extensions/blob/main/extensions/git-id-switcher/docs/LANGUAGES.md

まとめ

  • Git Submodule + 複数アカウント運用は設定が煩雑
  • Git ID SwitcherでワンクリックでSSH/GPG/Submoduleまで一括切り替え
  • 間違ったidentityでコミットする事故を防げる
  • 複数のリモート(GitHub、GitLab、Bitbucketなど)リポジトリの認証情報が異なっても一発切り替え

VSCode、ハードフォーク系(Antigravity、Cursor、Windsurf等)のIDEで動作します。
ぜひ使ってみてください。Issue/PRも歓迎です。

関連記事

この拡張機能を作った個人的な想いと経緯はnoteに書きました:
https://note.com/nullvariant/n/nfa0ba1170223

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?