worktree について
worktreeは、Git worktreeの作成と一覧表示を安全に行うスキルです。並行して作業する開発者向けに、現在のブランチと既定ブランチに基づいてベースを選び、リポジトリ外に作成します。
主な機能
- 01ルールに沿ったベースブランチ選択
- 02リポジトリ外へのworktree作成
- 03ブランチとパスの競合確認
- 04上限到達前の確認
- 05既存worktreeの一覧表示
- 06既定ではローカル参照を使い通信しない
活用シーン
- 01並行作業用の独立したディレクトリ作成
- 02現在の機能ブランチからworktreeを分岐
- 03リポジトリ内のworktreeとブランチを確認
- 04明示的な指定時にoriginからベースを更新
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ shipshitdev/ skills --skill worktreeインストール後、Claude Code で/worktreeを入力して読み込まれたか確認します。
詳細
Worktree
正しいベースブランチから、リポジトリの外部にあるディレクトリへ Git worktree を作成し、メインのチェックアウトとブランチを正しく保つための安全確認を行います。Worktree はリポジトリ内には作成しません。このスキルで行うのは worktree の作成と一覧表示のみです。マージ済み worktree の削除とプルーニングは git-cleanup の担当です(/git-cleanup)。ここでは削除しないでください。
Worktree のホーム
各エージェントは、すべてのアカウントで共有するホームを 1 つ保持します。手動で作成する worktree では、ユーザーレベルのホームを使用します。ディレクトリ構成は <home>/<owner-repo>/<name> です。
| 作成者 | ホーム |
|---|---|
| Claude Code | $HOME/.claude/worktrees |
| Codex | $HOME/.codex/worktrees |
| Grok | $HOME/.grok/worktrees |
| T3 Code | $HOME/.t3/worktrees |
| 手動/不明 | $HOME/worktrees |
GIT_WT_HOMEが設定されている場合は、ホームを上書きします。<owner-repo>はoriginリモートから取得します(owner/repoはowner-repoになります)。チェックアウトディレクトリ名はリポジトリ間で重複するため、使用しません。originがない場合に限り、チェックアウトディレクトリ名を使用します。- ハーネスがすでにセッションを独自のホーム配下の worktree(たとえば、管理対象の
.../worktrees/チェックアウト)に配置している場合は、その場所を維持します。セッションを移動したり、配置場所を理由に処理を中断したりしないでください。 - この規約に従う
git wt <name>エイリアスは、以下の手動コマンドの代わりに使用できます。解決されるパスは同一でなければなりません。
許可された範囲
ユーザーの依頼と既存の承認の範囲内でのみ作業してください。このスキルを読み込んでも、新たな権限は付与されません。レポートのみを求める依頼ではレポートのみを行い、呼び出し元が指定した対象、ホスト、プロバイダー、コスト制限を守り、範囲を広げる前に確認し、これらの制限を委任先にも伝えてください。
契約
入力:
- リポジトリのルート(git work tree 内である必要があります)
- 任意の worktree/ブランチ名(新たに作成するブランチ)
- 任意の明示的なベースブランチの上書き指定(
from <base>/--base <base>) - ベースをブランチ作成前に更新する任意の
--fetchフラグ
出力:
<home>/<owner-repo>/<name>に新しい worktree ディレクトリを作成し、新しいブランチをチェックアウト- 解決されたベースブランチと、その選択理由
- ベースがリモートより遅れている場合の警告(ローカルモードでは自動フェッチしません)
- リポジトリのリンクされた worktree 数と、ソフト上限およびハード上限との比較
- 並行セッションですぐに使用できる、
cdで移動するパス
作成/変更するもの:
<home>/<owner-repo>が存在しない場合は作成- 新しいブランチと worktree ディレクトリを作成
- 現在の作業ツリーの追跡対象ファイルには触れず、現在のブランチも切り替えません
外部への副作用:
- デフォルトではなし(ローカルの参照のみを使用し、ネットワークには接続しません)
--fetchを指定した場合のみ、ベース参照を更新するためにgit fetch origin <base>を 1 回実行
確認が必要な操作:
- リポジトリのリンクされた worktree 数がソフト上限の 5 に達している状態で worktree を作成する前
- 新しいブランチを作成せず、既存のブランチを再利用する前
- すでに存在する worktree パスを上書きまたは再利用する前
委任先:
- 姉妹ディレクトリにある
../<name>/SKILL.mdを読み、その指示に従って委任先を実行します。ここにあるスキルはユーザーが呼び出す場合にのみ使用するため、Skill ツールから読み込むことはできません。 - 昇格の確認、およびマージ済みの worktree とブランチのプルーニングには
git-cleanupを推奨します。 - worktree 内で使用する予定のブランチにシークレットが含まれる可能性がある場合は
git-safetyを推奨します。
ベースブランチの選択(中核となる動作)
ベースは次の順序で決定します。ローカルの参照先のみを使用し、自動フェッチは行いません。
- 明示的な指定。 ユーザーがベースを指定した場合(
/worktree fix-auth from developまたは--base release/1.4)、指定された値をそのまま使用します。 - フィーチャーブランチ上の場合 → 現在のブランチから分岐します。 現在のブランチが保護対象/統合ブランチでない場合、 そのブランチからワークツリーを分岐させます。これがデフォルトです。進行中の作業を続けながら、現在のチェックアウトに影響を与えずに、 並行する作業ラインを試せます。
- 保護対象ブランチ上または HEAD がデタッチ状態の場合 → デフォルト/トランクブランチから分岐します。
現在のブランチが
masterまたはmainの場合、あるいは HEAD がデタッチ状態の場合は、リポジトリのデフォルトブランチ (自動検出)から分岐します。トランクベースのワークフローでは、長期的な統合ベースとしてdevelopやstagingを使用しないでください。
current branch -> base the worktree forks from
---------------------- ----------------------------
feat/foo (feature) -> feat/foo (continue current work)
bugfix/x (feature) -> bugfix/x (continue current work)
master / main -> default branch (trunk)
detached HEAD -> default branch (trunk)
explicit "from <base>" -> <base> (always wins)
保護対象/トランクブランチの一覧(ステップ 2 では「フィーチャー」ベースとして使用しません):
master main
フェーズ 1:リポジトリを確認し、入力を解決する
git rev-parse --is-inside-work-tree # must be true; else STOP
TOPLEVEL="$(git rev-parse --show-toplevel)"
CURRENT="$(git symbolic-ref --quiet --short HEAD || echo DETACHED)"
git worktree list # show what already exists
新しいブランチ名を決定します。
- ユーザーが名前を指定した場合、それを新しいブランチ名とディレクトリ名にします。
- 名前が指定されていない場合は、ユーザーに確認します。仮の名前を勝手に付けないでください。
- ブランチ名からディレクトリ名を整形します(
feat/fooのようなブランチは、ブランチ名をfeat/fooのままにして、 ディレクトリを<home>/<owner-repo>/feat-fooにします)。
フェーズ 2:ベースブランチを決定する
PROTECTED='master|main'
# Default/trunk branch fallback — resolved to a ref that actually exists locally.
# Auto-detect the repo's default branch; never hardcode develop or staging.
DEF="$(git symbolic-ref --quiet --short refs/remotes/origin/HEAD 2>/dev/null | sed 's#^origin/##')"
DEF="${DEF:-$(git symbolic-ref --quiet --short HEAD 2>/dev/null)}"
DEF="${DEF:-master}"
git show-ref --verify --quiet "refs/heads/$DEF" && FALLBACK="$DEF" || FALLBACK="origin/$DEF"
# Apply the precedence. BASE is the start-point ref passed to `git worktree add`.
if [ -n "$EXPLICIT_BASE" ]; then
BASE="$EXPLICIT_BASE"
elif printf '%s\n' "$CURRENT" | grep -qxE "$PROTECTED" || [ "$CURRENT" = DETACHED ]; then
BASE="$FALLBACK" # on trunk or detached HEAD -> default/trunk branch
else
BASE="$CURRENT" # on a feature branch -> continue current work
fi
echo "Base: $BASE (current: $CURRENT)"
BASE は、常に具体的な開始点です(master のようなローカルブランチ、origin/main のような
リモート追跡参照、またはユーザーが明示したベース)。何かを作成する前に、決定したベースとその理由を報告します。
フェーズ 3:最新状態の確認(警告のみ。フェッチはしない)
デフォルトはローカルモードです。$BASE のローカルの先端からブランチを作成します。ベースに上流ブランチがあり、
その上流より遅れている場合は警告します。暗黙にフェッチしないでください。
if git rev-parse --verify --quiet "$BASE@{upstream}" >/dev/null; then
BEHIND="$(git rev-list --count "$BASE..$BASE@{upstream}" 2>/dev/null || echo 0)"
[ "$BEHIND" -gt 0 ] && echo "WARNING: local $BASE is $BEHIND commit(s) behind its remote. Using local tip. Pass --fetch to update first."
fi
ユーザーが --fetch を指定した場合に限り、次のようにします。
git fetch origin "$BASE"
git update-ref "refs/heads/$BASE" "origin/$BASE" # only when safe / fast-forward
デフォルトではフェッチしないでください。ローカルコミットがリモートにないベースブランチを書き換えないでください。 警告を出し、ローカルの先端を使用します。
フェーズ 4:ワークツリーのホームを決定し、上限を確認する
ワークツリーのディレクトリはリポジトリの外部にあるため、無視対象にしたりコミットしたりする必要はありません。 ホームと保存先を決定し、リンクされたワークツリーの数を数えます。
# Home: GIT_WT_HOME wins; else the running agent's shared home; else ~/worktrees.
# AGENT is the running agent: claude, codex, grok or t3 (empty for a manual run).
case "${AGENT:-}" in
claude) HOME_DIR="$HOME/.claude/worktrees" ;;
codex) HOME_DIR="$HOME/.codex/worktrees" ;;
grok) HOME_DIR="$HOME/.grok/worktrees" ;;
t3) HOME_DIR="$HOME/.t3/worktrees" ;;
*) HOME_DIR="$HOME/worktrees" ;;
esac
HOME_DIR="${GIT_WT_HOME:-$HOME_DIR}"
# owner-repo from the origin remote, lowercased.
URL="$(git -C "$TOPLEVEL" remote get-url origin 2>/dev/null | sed -E 's#/+$##; s#\.git$##')"
SLUG="$(printf '%s' "$URL" | sed -nE 's#.*[/:]([^/:]+)/([^/:]+)$#\1-\2#p')"
SLUG="$(printf '%s' "${SLUG:-$(basename "$TOPLEVEL")}" | tr '[:upper:]' '[:lower:]')"
# Guard: the destination must be outside the repository.
case "$HOME_DIR/" in "$TOPLEVEL"/*) echo "Worktree home is inside the repository: $HOME_DIR"; exit 1 ;; esac
# Caps: soft 5 (warn and confirm), hard 25 (stop). The primary checkout is not linked.
LINKED="$(( $(git worktree list --porcelain | grep -c '^worktree ') - 1 ))"
echo "Linked worktrees: $LINKED"
[ "$LINKED" -ge 25 ] && { echo "Hard cap (25) reached. Run /git-cleanup before creating another."; exit 1; }
[ "$LINKED" -ge 5 ] && echo "WARNING: soft cap (5) reached. Confirm, or remove merged worktrees with /git-cleanup first."
ルール:
- タスクごとにセッションは 1 つです。PR のマージ後は、未コミットの作業を保持したうえでワークツリーを削除します(
/git-cleanup)。 - リポジトリ内にある従来の
.worktrees/ディレクトリは、リポジトリですでに無視対象になっている場合、そのまま無視対象にしておけます。 新たに作成したり、新しい作業のために.gitignoreに.worktrees/を追加したりしないでください。
フェーズ 5:ワークツリーを作成する
NAME="<sanitized-name>"
BRANCH="<new-branch-name>"
DEST="$HOME_DIR/$SLUG/$NAME"
# Guard: destination must not already exist
[ -e "$DEST" ] && { echo "Path exists: $DEST — choose another name or remove it first."; exit 1; }
mkdir -p "$(dirname "$DEST")"
if git show-ref --verify --quiet "refs/heads/$BRANCH"; then
# Branch already exists: confirm, then attach it (no -b, no new branch)
git worktree add "$DEST" "$BRANCH"
else
# New branch off the resolved local base tip
git worktree add -b "$BRANCH" "$DEST" "$BASE"
fi
git worktree list
ルール:
- 新しいブランチを作成する場合にのみ
-bを使用します。ブランチがすでに存在する場合はそれを紐付け、そのことを伝えます。 既存のブランチを黙ってリセットしないでください。 - ブランチは同時に 1 つのワークツリーでのみチェックアウトできます。
$BRANCHが別の場所ですでにチェックアウトされている場合は、 その場所を報告して中止します。 --forceは絶対に指定しないでください。git に拒否された場合は、その理由を伝え、ユーザーの判断に委ねます。
フェーズ 6:結果を報告し、作業を引き継ぐ
次の項目を報告します。
- ワークツリーのパス:
<home>/<owner-repo>/<name>(リポジトリの外部) - 新しいブランチと、そこから分岐したベース(およびそのベースを選んだ理由)
- フェーズ 3 で最新状態に関する警告があった場合は、その内容
- そこで作業を開始する方法:そのパスに
cdし、そのディレクトリで並行セッションを開きます。各ワークツリーは、 1 つの.gitを共有する独立したチェックアウトです。 - プロジェクトに依存関係が必要な場合は、何かを実行する前にワークツリー内でインストールします(ワークツリー間で
node_modulesは共有されません)。
モード
worktree <name>— 上記のスマートルールで解決したベースから、新しいブランチ<name>を作成し、<name>という名前のワークツリーを作成します。(デフォルト)worktree <name> from <base>/worktree <name> --base <base>— ベースを指定して固定します。worktree <name> --fetch— ブランチ作成前に、ベースを origin から更新します。worktree list— 既存のワークツリーとブランチを一覧表示します。何も作成しません。
ユーザーがスコープを別途指定した場合(「master から」「現在のブランチを使う」など)は、その指定に従いつつ、ワークツリーをリポジトリの外に配置し、既存のブランチやパスを上書きしないための安全確認は維持してください。
安全モデル
- 現在のブランチを切り替えたり、現在の作業ツリーで追跡対象となっているファイルを変更したりすることはありません。ワークツリーの作成は追加のみです。
- ワークツリーをリポジトリ内に作成しないため、追跡対象になることはありません。作成先がリポジトリの外にあることを事前に確認します。
- デフォルトではローカルの先端を使用します。ネットワークへのアクセスは
--fetchを明示した場合に限ります。 --forceは使用せず、既存のブランチをリセットしたり、既存のパスを上書きしたりしません。競合が発生した場合は報告して停止します。- 削除とプルーニングは対象外です。
git-cleanup(/git-cleanup)に引き継いでください。