
TL;DR(結論)
WSL2の/mnt/c
配下(Windowsファイルシステム)でClaude Codeの初期レスポンスが遅い場合、WSL側のgitではなくWindows側のgit.exeを使うように設定することで劇的に改善します。
具体的には、~/bin/git
等にラッパースクリプトを配置し、/mnt/c
配下では自動的にgit.exe
を呼び出すようにします:
# ラッパースクリプトの作成
cat > ~/bin/git << 'EOF'
#!/bin/bash
if [[ "$PWD" == /mnt/c/* ]]; then
git.exe "$@"
else
/usr/bin/git "$@"
fi
EOF
chmod +x ~/bin/git
この設定により、起動時間が10分→10秒に短縮されました。
以下、詳しい調査経緯と解説です。
問題の症状
WSL2環境でClaude Codeを起動する際、以下のような症状が発生していました
/mnt/c
配下(Windowsファイルシステム)でClaude Codeを起動すると、最初のレスポンスまで10分以上かかる- 同じプロジェクトを
/home
配下(Linuxファイルシステム)で起動すると数秒で返答が来る - 同じ
/mnt/c
配下でも、別のプロジェクトは数十秒で起動する
この差の原因を調査し、解決に至った経緯をまとめます。
環境情報
- OS: WSL2 (Ubuntu on Windows)
- Claude Code: 2.0.15
- Git: WSL側 2.43.0 / Windows側 2.35.1.windows.2
- プロジェクト: Laravel ベースのCMS(約15,000ファイル、Git管理)
原因の調査
1. 基本的な仮説の検証
最初に疑ったのは、ファイル数やディレクトリサイズの違いでした。
# ファイル数の比較
find /home/user/work/project -type f | wc -l
# => 15,763ファイル
find /mnt/c/Users/user/project -type f | wc -l
# => 32,136ファイル
一時ファイルなどの関係で/mnt/c
側の方がファイル数が多いものの、2倍程度の差では10分の遅延は説明できません。
2. Git関連の調査
次に、最初のレスポンスが速いプロジェクトとの違いを調査しました
# 遅いプロジェクトのGit管理ファイル数
cd /mnt/c/Users/user/slow-project
git ls-files | wc -l
# => 15,734ファイル
# 速いプロジェクトのGit管理ファイル数
cd /mnt/c/Users/user/fast-project
git ls-files | wc -l
# => 0(Gitリポジトリではなかった)
重要な発見:速いプロジェクトは.git
ディレクトリが存在せず、Gitリポジトリではありませんでした。
3. .gitディレクトリの影響を検証
実験として、.git
ディレクトリを一時的にリネームして起動時間を測定:
cd /mnt/c/Users/user/your-project
mv .git .git.backup
# Claude Codeを起動
# => 約10秒で起動!
# 元に戻す
mv .git.backup .git
# => また10分かかる
.gitディレクトリの有無で60倍の差が発生することを確認しました。
4. Git処理の詳細トレース
Claude Codeが起動時にどんなGit操作を行っているか、GIT_TRACE
を使って調査しました:
# トレースを有効化
export GIT_TRACE=/tmp/git-trace.log
export GIT_TRACE_PERFORMANCE=/tmp/git-perf.log
# Claude Code起動
cd /mnt/c/Users/user/your-project
claude
ログを確認すると、決定的な証拠が見つかりました:
10:24:56.438569 git rev-parse --show-toplevel
10:24:57.072362 git worktree list
10:24:57.649510 git rev-parse --is-inside-work-tree
10:24:57.809066 git branch --show-current
10:24:57.828875 git log --oneline -n 5
10:24:57.830062 git status --short
10:25:02.120939 git worktree list
10:25:13.336711 git rev-parse --abbrev-ref HEAD
パフォーマンスログには:
10:24:56.478310 performance: 0.039763796 s: git rev-parse --show-toplevel
10:24:57.163686 performance: 0.255129326 s: git worktree list
...
10:27:06.285245 performance: 128.296797596 s: preload index ← ★ここ!
preload index
に128秒(2分8秒)もかかっていました。
根本原因
WSL2のv9fsファイルシステムの特性
/mnt/c
はWSL2からWindowsファイルシステムにアクセスするための仮想ファイルシステム(v9fs)です。このファイルシステムには以下の特性があります:
- ファイル1個あたりのI/O操作に数ms〜数十msのオーバーヘッド
- 大量の小さなファイルへのアクセスで顕著な性能劣化
Git preload indexの処理
Gitのpreload index
は、.git/index
ファイルに記録されている全ファイルの状態を確認する処理です:
- 15,734ファイルすべてをチェック
- 各ファイルのメタデータ(タイムスタンプ、サイズ等)を読み取る
- v9fs経由だと1ファイルあたり数十ms
- 15,734 × 数十ms = 数分
なぜ別のプロジェクトは速かったのか
速いプロジェクトは.git
ディレクトリが存在しないため:
- Git関連の処理がすべてスキップされる
- 単純なファイルスキャンのみで完了
- 結果として数十秒で起動
解決方法
実は、WSL上のgitでwindows側の操作をすると遅いことは以前から分かっていたので、.bashrcに既に以下の設定がしてありました。
# Windowsドライブで作業している場合にgit.exeを呼び出す関数
git_win_alias() {
if [[ "$(pwd -P)" == /mnt/c* ]]; then
git.exe "$@"
else
command git "$@"
fi
}
alias git='git_win_alias'
しかし、Claude Codeはbashのaliasを経由せず、直接git
コマンドを実行しているため、この設定が効きませんでした。
解決策:~/bin/gitラッパースクリプト
PATHで/usr/bin
より優先される場所に、git
という名前のラッパースクリプトを配置すれば、Claude Codeからも使われます。
# ラッパースクリプトの作成
cat > ~/bin/git << 'EOF'
#!/bin/bash
# Git wrapper: Use git.exe on /mnt/c, WSL git elsewhere
if [[ "$PWD" == /mnt/c/* ]]; then
# Windows側のgit.exeを使用
git.exe "$@"
else
# WSL側のgitを使用
/usr/bin/git "$@"
fi
EOF
# 実行権限を付与
chmod +x ~/bin/git
動作確認
# どのgitが使われるか確認
which git
# => /home/user/bin/git
# /mnt/c配下でテスト
cd /mnt/c/Users/user/your-project
git --version
# => git version 2.35.1.windows.2 (Windows側)
# Linux側でテスト
cd ~
git --version
# => git version 2.43.0 (WSL側)
完璧に動作します!
効果の検証
ラッパースクリプト導入後、再度GIT_TRACE
で計測しました:
export GIT_TRACE=/tmp/git-trace-new.log
export GIT_TRACE_PERFORMANCE=/tmp/git-perf-new.log
cd /mnt/c/Users/user/your-project
claude
結果:
項目 | 改善前 | 改善後 | 改善率 |
---|---|---|---|
preload index | 128秒 | 数秒 | 約40倍高速化 |
起動時間(体感) | 10分 | 10秒 | 60倍高速化 |
|
まとめ
原因
- Claude Codeは起動時にGitリポジトリ情報を取得する
- WSL側の
git
を使うと、v9fs経由で大量のファイルのメタデータを読み取る preload index
処理で2分以上かかる- さらに追加のインデックス作成で数分かかり、合計10分に
解決方法
~/bin/git
にラッパースクリプトを配置し、/mnt/c
配下では自動的にWindows側のgit.exe
を使うようにする。
重要なポイント
- bashのaliasはClaude Codeでは効かない(プロセスから直接コマンド実行されるため)
- PATHの優先順位を利用して、
~/bin/git
でラッパーを配置 - Windows側の
git.exe
はWindowsネイティブファイルシステムにアクセスするため、v9fsのオーバーヘッドがない
副次的な効果
この設定により、Claude Code以外のツール(VS Code、その他のCLIツール等)も、/mnt/c
配下で自動的にWindows側のGitを使うようになり、全体的なパフォーマンスが向上します。
参考:調査に使用したコマンド
# ファイル数の調査
find ディレクトリ -type f | wc -l
# Git管理ファイル数
git ls-files | wc -l
# ファイルシステムタイプの確認
stat -f -c "%T" ディレクトリ
# Git処理のトレース
export GIT_TRACE=/tmp/git-trace.log
export GIT_TRACE_PERFORMANCE=/tmp/git-perf.log
# パフォーマンスボトルネックの確認
grep "preload index" /tmp/git-perf.log
おわりに
WSL2環境での開発では、Windowsファイルシステム(/mnt/c
)とLinuxファイルシステム(/home
)のパフォーマンス特性を理解し、適切にツールを使い分けることが重要です。
特に、Git操作のような大量のファイルI/Oが発生する処理では、ネイティブのファイルシステムを使うことで劇的な性能改善が得られます。
この事例が、同様の問題に直面している方の参考になれば幸いです。
コメント