# Git Worktree Workspace

> `git worktree` で現在の GitHub リポジトリから追加ワークスペースを作成し、Codex の作業ディレクトリをその worktree に切り替えて作業したり、不要になった worktree を削除してメインのワークスペースへ戻ったりするときに使う。ブランチを作る感覚で一時ワークスペースへ移動したい依頼で使う。

- Skill: `satoru314/git-worktree-workspace` (Agent Skill)
- Install (CLI): `npx skillmds@latest add satoru314/git-worktree-workspace`
- Raw SKILL.md: https://api.skillmd.com/api/skills/satoru314/git-worktree-workspace/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: Satoru314 (https://skillmd.com/u/satoru314)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/satoru314/git-worktree-workspace

---


`git worktree` を「別リポジトリ」ではなく「同じリポジトリの追加ワークスペース」として扱う。  
新規 worktree の作成と切り替え、削除と復帰をこの skill でまとめて扱う。

## 基本方針

- まず現在位置のリポジトリルートを取得する。
- 以後のコマンドは、目的の worktree パスを `workdir` に指定して実行する。
- デフォルトでは、worktree はリポジトリ親ディレクトリ直下に `"<repo>-wt-<branch-slug>"` という名前で作る。
- ユーザーが基点ブランチや配置先を指定しない限り、現在の `HEAD` から新規ブランチを作る。
- 未コミット変更は新しい worktree へ引き継がれない。必要なら先に commit か stash を行う。
- 強制削除 (`git worktree remove --force` や `git branch -D`) は、ユーザーが明示したときだけ行う。

## 事前確認

```bash
ROOT=$(git rev-parse --show-toplevel)
REPO=$(basename "$ROOT")
MAIN_ROOT=$(git worktree list --porcelain | awk '/^worktree /{print $2; exit}')
```

- `ROOT` は現在の worktree のルート。
- `MAIN_ROOT` はメイン worktree。削除後に戻る先として使う。

## 追加ワークスペースを作って切り替える

### 使う場面

- 「新しい作業場所を作ってそこで作業したい」
- 「ブランチを切る感覚で別ワークスペースへ移動したい」
- 「今の tree は残したまま、別ブランチで並行作業したい」

### 手順

1. 現在のルートと作成先パスを決める。

```bash
ROOT=$(git rev-parse --show-toplevel)
REPO=$(basename "$ROOT")
BRANCH="<new-branch>"
BRANCH_SLUG=$(printf '%s' "$BRANCH" | sed 's#[/:]#-#g')
WT_PATH="$(dirname "$ROOT")/${REPO}-wt-${BRANCH_SLUG}"
```

2. 既存 branch / 既存 worktree の衝突を確認する。

```bash
git worktree list --porcelain
git show-ref --verify --quiet "refs/heads/$BRANCH"
```

- 同名 branch がまだ存在しないなら `-b` で作成する。
- 同名 branch が存在し、どの worktree でも使用中でなければその branch を使って worktree を作る。
- 同名 branch が別 worktree で使用中なら、別名 branch を提案するか、ユーザーの指定を待つ。

3. worktree を作る。

- 新規 branch を切るとき:

```bash
git worktree add -b "$BRANCH" "$WT_PATH"
```

- 既存 branch を使うとき:

```bash
git worktree add "$WT_PATH" "$BRANCH"
```

- 基点を明示されたとき:

```bash
git worktree add -b "$BRANCH" "$WT_PATH" "<start-point>"
```

4. 以後のコマンドは `WT_PATH` を `workdir` にして実行する。

報告例:

```text
worktree を作成しました: <WT_PATH>
以後の作業ディレクトリはこの worktree に切り替えます
```

### 最小コマンド例

```bash
ROOT=$(git rev-parse --show-toplevel)
REPO=$(basename "$ROOT")
BRANCH="feature/example"
BRANCH_SLUG=$(printf '%s' "$BRANCH" | sed 's#[/:]#-#g')
WT_PATH="$(dirname "$ROOT")/${REPO}-wt-${BRANCH_SLUG}"

if git show-ref --verify --quiet "refs/heads/$BRANCH"; then
  git worktree add "$WT_PATH" "$BRANCH"
else
  git worktree add -b "$BRANCH" "$WT_PATH"
fi

printf '%s\n' "$WT_PATH"
```

## worktree を消してメインへ戻る

### 使う場面

- 「この追加ワークスペースはもう不要」
- 「作業が終わったので worktree を片付けたい」
- 「メインのワークスペースへ戻したい」

### 手順

1. 削除対象 branch か worktree path を特定する。

```bash
git worktree list --porcelain
```

branch 名から path を引く例:

```bash
TARGET_BRANCH="<branch>"
TARGET_PATH=$(
  git worktree list --porcelain | awk -v target="$TARGET_BRANCH" '
    /^worktree / { wt=$2 }
    /^branch refs\/heads\// {
      br=$0
      sub(/^branch refs\/heads\//, "", br)
      if (br == target) {
        print wt
        exit
      }
    }
  '
)
```

2. 削除対象が dirty でないことを確認する。

```bash
git -C "$TARGET_PATH" status --short
```

- 出力があるなら、そのまま消さない。commit / stash / 破棄方針を決めてから進める。

3. 先にメイン worktree を戻り先として確定する。

```bash
MAIN_ROOT=$(git worktree list --porcelain | awk '/^worktree /{print $2; exit}')
```

4. 以後のコマンドは `MAIN_ROOT` を `workdir` にして実行し、対象 worktree を削除する。

```bash
git -C "$MAIN_ROOT" worktree remove "$TARGET_PATH"
```

5. branch も不要なら削除する。

```bash
git -C "$MAIN_ROOT" branch -d "$TARGET_BRANCH"
```

報告例:

```text
worktree を削除しました: <TARGET_PATH>
以後の作業ディレクトリはメイン worktree に戻します: <MAIN_ROOT>
```

### 最小コマンド例

```bash
TARGET_BRANCH="feature/example"
MAIN_ROOT=$(git worktree list --porcelain | awk '/^worktree /{print $2; exit}')
TARGET_PATH=$(
  git worktree list --porcelain | awk -v target="$TARGET_BRANCH" '
    /^worktree / { wt=$2 }
    /^branch refs\/heads\// {
      br=$0
      sub(/^branch refs\/heads\//, "", br)
      if (br == target) {
        print wt
        exit
      }
    }
  '
)

git -C "$TARGET_PATH" status --short
git -C "$MAIN_ROOT" worktree remove "$TARGET_PATH"
git -C "$MAIN_ROOT" branch -d "$TARGET_BRANCH"
printf '%s\n' "$MAIN_ROOT"
```

## 注意

- 削除対象の worktree 自身を `workdir` にしたまま消さない。先に `MAIN_ROOT` 側へ戻してから削除する。
- `git worktree remove` が `working trees contain modified or untracked files` で失敗したら、強制削除せず状態を報告する。
- 使い終わったら `git worktree list` で残存 worktree を確認する。
- ユーザーが「新しい repo」と言っていても、実際には同一 repo の追加ワークスペースとして扱う。

