アイデア
マルチエージェントでのコーディングにおいて、Git の worktree は有用である。
worktree を追加する際、.gitignore に指定されて Git の追跡対象外となっているディレクトリやファイルは無視される。
しかし、ビルド済みのフレームワークのような、ファイルサイズが大きく、かつビルドで不可欠なファイルこそ、往々にして .gitignore に指定されがちである。その場合、worktree での作業のためには、ひと工夫必要となる。
ファイルをコピーするのも手だが、ファイル数が大量であるか大容量ファイルが多ければ、処理に時間を要してしまう。
ならば、元のディレクトリやファイルへのシンボリックリンクを作成するのが良いのではないか。
考えた末、git worktree add の実行に加えて、引数で指定されたディレクトリやファイルについて、そのシンボリックリンクを worktree の作業ディレクトリ内に作成するシェルスクリプトを作成した。
コード
create_worktree_and_link.sh
#!/bin/bash
set -e # エラーが発生したら停止
# 使用方法を表示
usage() {
echo "Usage: $0 <branch_name> <worktree_path> <link_targets...>"
echo ""
echo "Arguments:"
echo " branch_name : ブランチ名(既存または新規)"
echo " worktree_path : worktreeを作成するパス"
echo " link_targets : シンボリックリンクを作成するディレクトリまたはファイル(複数指定可)"
echo ""
echo "Example:"
echo " $0 feature/new-feature ../my-worktree node_modules .env DerivedData"
exit 1
}
# 引数のチェック
if [ $# -lt 3 ]; then
echo "エラー: 最低3つの引数が必要です"
usage
fi
branch_name=$1
worktree_path=$2
shift 2
link_targets=("$@")
# Gitリポジトリのルートディレクトリを取得
repo_root=$(git rev-parse --show-toplevel 2>/dev/null)
if [ -z "$repo_root" ]; then
echo "エラー: Gitリポジトリ内で実行してください"
exit 1
fi
echo "=== Worktree作成スクリプト ==="
echo "ブランチ名: $branch_name"
echo "Worktreeパス: $worktree_path"
echo "リポジトリルート: $repo_root"
echo "リンク対象: ${link_targets[*]}"
echo ""
# Step 1: Worktreeの作成
echo "Step 1: Worktreeを作成中..."
if git worktree add "$worktree_path" "$branch_name"; then
echo "✓ Worktreeの作成が完了しました"
else
echo "エラー: Worktreeの作成に失敗しました"
exit 1
fi
echo ""
# worktreeの絶対パスを取得
worktree_abs_path=$(cd "$worktree_path" && pwd)
# カレントディレクトリを保存
original_dir=$(pwd)
# リポジトリルートに移動
cd "$repo_root"
# Step 2: シンボリックリンクの作成
echo "Step 2: シンボリックリンクを作成中..."
link_count=0
skip_count=0
for target in "${link_targets[@]}"; do
# ソースパス(元のリポジトリ内)
source_path="$repo_root/$target"
# ターゲットパス(worktree内)
target_path="$worktree_abs_path/$target"
# ソースが存在するかチェック
if [ ! -e "$source_path" ]; then
echo " 警告: $target が見つかりません。スキップします。"
((skip_count++))
continue
fi
# ターゲットパスの親ディレクトリを取得
parent_dir=$(dirname "$target")
# 親ディレクトリを作成(必要な場合)
if [ "$parent_dir" != "." ] && [ ! -d "$worktree_abs_path/$parent_dir" ]; then
mkdir -p "$worktree_abs_path/$parent_dir"
fi
# 既にリンクまたはファイルが存在する場合
if [ -e "$target_path" ] || [ -L "$target_path" ]; then
echo " 警告: $target は既に存在します。スキップします。"
((skip_count++))
continue
fi
# シンボリックリンクを作成
if ln -sf "$source_path" "$target_path"; then
((link_count++))
if [ -d "$source_path" ]; then
echo " ✓ ディレクトリリンク作成: $target"
else
echo " ✓ ファイルリンク作成: $target"
fi
else
echo " エラー: $target のリンク作成に失敗しました"
((skip_count++))
fi
done
echo ""
echo "=== 処理完了 ==="
echo "✓ 作成されたリンク数: $link_count"
echo "✓ スキップされた数: $skip_count"
echo ""
echo "Worktreeは以下に作成されました: $worktree_abs_path"
# 元のディレクトリに戻る
cd "$original_dir"
使い方
※ chmod +x create_worktree_and_link.sh を実行し、スクリプトの実行権限を付与しておく
./create_worktree_and_link.sh [展開するブランチ名] [worktreeの展開先のディレクトリパス] [「一緒に持っていきたい」ディレクトリやファイルのパス(スペース区切りで複数指定可)]