Claude Code の -w(worktree)オプションで並行作業をしていたら、PR でコンフリクトが大量に出た。原因を調べたら、ローカルブランチがリモートより24コミットも遅れていた。
claude code -w は git worktree add でローカルブランチの HEAD から分岐するが、事前に git fetch や git pull は実行しない。なのでローカルが古ければ、そのまま古いコードで worktree が作られる。GitHub Issue #28958 にもなっている既知の制限だ。
毎回手動で git pull してから -w するのは面倒なので、Claude Code の Hooks 機能(公式ドキュメント)で自動化した。
やったこと
~/.claude/hooks/session-start-pull.sh を作成する。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
#!/bin/bash
# SessionStart hook: リモートの最新を自動取得し、ローカルを最新化する
# stdin の JSON を読み捨て(hook プロトコル上送られてくるが不要)
cat > /dev/null
# git リポジトリでなければスキップ
git rev-parse --is-inside-work-tree > /dev/null 2>&1 || exit 0
# リモートの最新 ref を取得
git fetch origin 2>/dev/null || exit 0
# 追跡ブランチがある場合は pull(通常セッション向け)
git pull --ff-only 2>/dev/null
# 追跡ブランチがない場合(worktree 向け):
# HEAD が origin/branch の祖先なら ff-merge で最新化
for branch in develop main master; do
if git merge-base --is-ancestor HEAD "origin/$branch" 2>/dev/null; then
git merge "origin/$branch" --ff-only 2>/dev/null
break
fi
done
# ローカルのブランチ ref をリモートに追従(次回 worktree 作成時に最新がベースになる)
# +プレフィックスなし = 非強制更新: ローカルに独自コミットがある場合は失敗する(安全)
for branch in develop main master; do
git fetch origin "$branch:$branch" 2>/dev/null
done
exit 0
|
1
|
chmod +x ~/.claude/hooks/session-start-pull.sh
|
~/.claude/settings.json に Hook を登録する。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
{
"hooks": {
"SessionStart": [
{
"hooks": [
{
"type": "command",
"command": "bash /path/to/.claude/hooks/session-start-pull.sh",
"timeout": 30
}
]
}
]
}
}
|
command のパスは環境に合わせて絶対パスで指定する。Windows (Git Bash) なら /c/Users/username/.claude/hooks/session-start-pull.sh のような形式になる。
何をやっているか
セッション開始のたびに以下を実行する。
git fetch origin でリモートの最新 ref を取得
git pull --ff-only で追跡ブランチがあれば更新(通常セッション向け)
- worktree ブランチの場合、親ブランチ(develop/main/master)からの ff-merge を試みる
git fetch origin branch:branch でローカルのブランチ ref をリモートに追従させる(次回の worktree 作成に備える)
すべて --ff-only または非強制更新なので、ローカルに独自コミットがある場合は何もしない。エラーは 2>/dev/null で抑制し、exit 0 で終了するため、オフラインやマージ不可でもセッション開始を妨げない。
動作確認
1
2
|
echo '{"session_id":"test","hook_event_name":"SessionStart","source":"startup"}' \
| bash ~/.claude/hooks/session-start-pull.sh
|
worktree が古い場合、以下のような出力が出て最新化される。
1
2
|
Updating abc1234..def5678
Fast-forward
|
これで -w 実行前に git pull を忘れる心配がなくなった。