git-worktree
複数のブランチで同時に作業する際、stashやクローンなしで効率的に切り替え、並行して開発を進めるためのSkillです。
📜 元の英語説明(参考)
Git worktrees for working on multiple branches simultaneously without stashing or cloning. Use when user mentions "git worktree", "multiple branches", "work on two branches", "parallel branches", "switch branches without stashing", "worktree", "isolated branch work", needing to work on a hotfix while a feature is in progress, "bare repo worktree", "dotfiles bare repo", "worktree vs stash", "worktree vs clone", "orphaned worktree", or "worktree prune".
🇯🇵 日本人クリエイター向け解説
複数のブランチで同時に作業する際、stashやクローンなしで効率的に切り替え、並行して開発を進めるためのSkillです。
※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。
下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o git-worktree.zip https://jpskill.com/download/6091.zip && unzip -o git-worktree.zip && rm git-worktree.zip
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/6091.zip -OutFile "$d\git-worktree.zip"; Expand-Archive "$d\git-worktree.zip" -DestinationPath $d -Force; ri "$d\git-worktree.zip"
完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。
💾 手動でダウンロードしたい(コマンドが難しい人向け)
- 1. 下の青いボタンを押して
git-worktree.zipをダウンロード - 2. ZIPファイルをダブルクリックで解凍 →
git-worktreeフォルダができる - 3. そのフォルダを
C:\Users\あなたの名前\.claude\skills\(Win)または~/.claude/skills/(Mac)へ移動 - 4. Claude Code を再起動
⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。
🎯 このSkillでできること
下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。
📦 インストール方法 (3ステップ)
- 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
- 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
- 3. 展開してできたフォルダを、ホームフォルダの
.claude/skills/に置く- · macOS / Linux:
~/.claude/skills/ - · Windows:
%USERPROFILE%\.claude\skills\
- · macOS / Linux:
Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。
詳しい使い方ガイドを見る →- 最終更新
- 2026-05-17
- 取得日時
- 2026-05-17
- 同梱ファイル
- 1
📖 Skill本文(日本語訳)
※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。
Git Worktree
コアコンセプト
Git のワークツリーは、同じリポジトリにリンクされた追加の作業ディレクトリです。すべてのリポジトリは1つのワークツリー(メインワークツリー)から始まります。同じ .git オブジェクトストア、参照、および設定を共有するリンクされたワークツリーを追加できます。
すべてのワークツリーで共有されるもの: オブジェクトデータベース、参照(ブランチ、タグ)、設定、フック、リモートトラッキング情報、rerere キャッシュ。
ワークツリーごとに分離されるもの: 作業ツリーファイル、インデックス(ステージングエリア)、HEAD、MERGE_HEAD、REBASE_HEAD、CHERRY_PICK_HEAD、.env ファイル、node_modules、ビルド成果物。
メインワークツリーは git init または git clone によって作成されるものです。リンクされたワークツリーは git worktree add で作成されます。メインワークツリーは git worktree remove で削除できません。これは永続的です。リンクされたワークツリーは自由に追加および削除できます。
内部的には、各リンクされたワークツリーは .git/worktrees/<name>/ の下にディレクトリを持ち、その中に独自の HEAD、index、およびトラッキングファイルが含まれます。リンクされたワークツリーの作業ディレクトリには、この場所を指す .git ファイル(ディレクトリではない)が含まれています。
Worktree vs Stash vs Branch Switching vs Clone
| アプローチ | 良い点 | 欠点 |
|---|---|---|
git stash |
5分未満の急な中断に最適 | 線形ワークフロー、スタッシュがたまる、ポップ時にマージコンフリクト |
git switch |
クリーンな作業ツリー、高速なブランチ切り替え | まずコミットまたはスタッシュが必要、未コミットのコンテキストが失われる |
git worktree |
並行作業、複数のコンテキストを維持 | 余分なディスクスペース、複数のディレクトリを管理する必要がある |
git clone |
完全に分離された環境、異なる設定 | オブジェクトのディスク使用量が倍増、参照の共有なし |
スタッシュは線形的なコンテキスト切り替えを強制します。ワークツリーを使用すると、複数のブランチを別々のディレクトリで同時にチェックアウトしたままにできます。シリアル化も、忘れられたスタッシュも、ポップ時のコンフリクトもありません。
Clone に対するパフォーマンス上の利点
ワークツリーはオブジェクトデータベースを共有します。クローンはそれを複製します。2 GB の履歴を持つリポジトリの場合、2番目のワークツリーは作業ツリーのサイズ(ソースファイル)しかかかりません。2番目のクローンは2 GB + 作業ツリーのコストがかかります。
参照が共有されているため、ブランチとタグはワークツリー間で瞬時に更新されます。クローンの場合、それぞれで個別にフェッチする必要があります。
ワークツリーはフックと設定も共有するため、ツールは重複することなく一貫性を保ちます。
ワークツリーの作成
既存のブランチから:
git worktree add ../hotfix-login hotfix/login
これは hotfix/login を ../hotfix-login にチェックアウトします。
新しいブランチから:
git worktree add -b feature/search ../feature-search main
main をベースに feature/search を作成し、../feature-search にチェックアウトします。
特定のコミットから(detached HEAD):
git worktree add --detach ../investigate-crash abc1234
ブランチを作成せずに特定のコミットを調査するのに便利です。
ローカルで追跡したいリモートブランチから:
git fetch origin
git worktree add ../review-pr42 origin/pr-42
ワークツリーの管理
ワークツリーのリスト表示
git worktree list
出力には、各ワークツリーのパス、その HEAD コミット、およびブランチ名が表示されます。機械で解析可能な出力には --porcelain を追加してください。
ワークツリーの削除
正しい方法です。ディレクトリと内部トラッキングの両方を処理します。
git worktree remove ../hotfix-login
破棄したい未コミットの変更がある場合は --force を使用してください。
ワークツリーの移動
git worktree move ../hotfix-login ../hotfix-auth
ワークツリーディレクトリを移動し、内部トラッキングを更新します。メインワークツリーは移動できません。
ロックとアンロック
git worktree prune による削除を防ぐためにワークツリーをロックします(リムーバブルドライブやネットワークマウント上のワークツリーに便利です)。
git worktree lock ../usb-worktree --reason "on external drive"
git worktree unlock ../usb-worktree
古いエントリの削除
git worktree prune
ディレクトリが存在しなくなったワークツリーの内部トラッキングを削除します。何が削除されるかを確認するには、まず --dry-run を付けて実行してください。詳細については、以下の「孤立したワークツリーのクリーンアップ」を参照してください。
ディレクトリレイアウト戦略
兄弟ディレクトリ(推奨)
~/projects/
myapp/ # メインワークツリー
myapp-hotfix/ # ホットフィックスワークツリー
myapp-review/ # PRレビューワークツリー
フラットな状態を保ちます。ファイルマネージャーやターミナルタブで簡単に見つけられます。各ディレクトリは自己完結型です。
サブディレクトリレイアウト
~/projects/myapp/
main/ # メインワークツリー(ベアリポジトリが親)
hotfix/
review/
ベアリポジトリパターン(下記参照)とうまく機能します。すべてのワークツリーが1つの親の下にグループ化されます。
プロジェクトごとに1つの慣例を選び、それに従ってください。
一般的なワークフロー
機能開発中にホットフィックス
未コミットの変更がある機能ブランチの作業中に、本番環境で問題が発生しました。
# 機能ワークツリーからホットフィックスワークツリーを作成します
git worktree add -b hotfix/crash ../myapp-hotfix main
# ホットフィックスディレクトリに移動します
cd ../myapp-hotfix
# バグを修正し、コミットしてプッシュします
git commit -am "fix null pointer in auth handler"
git push origin hotfix/crash
# 機能作業に戻ります。作業は中断したままの状態です
cd ../myapp
ブランチがダーティな状態でPRをレビュー
git fetch origin
git worktree add ../myapp-review origin/feature/new-api
cd ../myapp-review
# コードを読み、テストを実行し、コメントを残します
# メインワークツリーでの進行中の作業は手つかずのままです
完了したら:
git worktree remove ../myapp-review
あるブランチでテストを実行しながら、別のブランチでコーディング
ターミナル1: 機能ワークツリーでコードを記述します。ターミナル2: 別々のワークツリーでテストを実行します。
git worktree add ../myapp-test main
cd ../myapp-test && npm test -- --watch
複数のブランチの動作を並べて比較
異なるポートで2つのワークツリーからアプリを実行します。
# ターミナル1 # ターミナル2
cd ~/projects/myapp cd ~/projects/myapp-main
PORT=3000 npm start PORT=3001 npm start
共有と分離された依存関係および成果物
各
📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開
Git Worktree
Core Concepts
A git worktree is an additional working directory linked to the same repository. Every repo starts with one worktree (the main worktree). You can add linked worktrees that share the same .git object store, refs, and config.
Shared across all worktrees: object database, refs (branches, tags), config, hooks, remote tracking info, rerere cache.
Isolated per worktree: working tree files, index (staging area), HEAD, MERGE_HEAD, REBASE_HEAD, CHERRY_PICK_HEAD, .env files, node_modules, build artifacts.
The main worktree is the one created by git init or git clone. Linked worktrees are created with git worktree add. The main worktree cannot be removed with git worktree remove -- it is permanent. Linked worktrees can be added and removed freely.
Internally, each linked worktree gets a directory under .git/worktrees/<name>/ containing its own HEAD, index, and tracking files. The linked worktree's working directory contains a .git file (not a directory) pointing back to this location.
Worktree vs Stash vs Branch Switching vs Clone
| Approach | Good When | Downsides |
|---|---|---|
git stash |
Quick one-off interruptions under 5 minutes | Linear workflow, stashes pile up, merge conflicts on pop |
git switch |
Clean working tree, fast branch change | Must commit or stash first, loses uncommitted context |
git worktree |
Parallel work, keeping multiple contexts alive | Extra disk space, must manage multiple directories |
git clone |
Fully isolated environments, different configs | Doubles disk usage for objects, no shared refs |
Stashing forces linear context switching. Worktrees let you keep multiple branches checked out simultaneously in separate directories -- no serialization, no forgotten stashes, no pop conflicts.
Performance Benefits Over Clone
Worktrees share the object database. A clone duplicates it. On a repo with 2 GB of history, a second worktree costs only the working tree size (source files). A second clone costs 2 GB + working tree.
Branches and tags update instantly across worktrees because refs are shared. With clones, you must fetch separately in each.
Worktrees also share hooks and config, so tooling stays consistent without duplication.
Creating Worktrees
From an existing branch:
git worktree add ../hotfix-login hotfix/login
This checks out hotfix/login into ../hotfix-login.
From a new branch:
git worktree add -b feature/search ../feature-search main
Creates feature/search based on main and checks it out in ../feature-search.
From a specific commit (detached HEAD):
git worktree add --detach ../investigate-crash abc1234
Useful for inspecting a specific commit without creating a branch.
From a remote branch you want to track locally:
git fetch origin
git worktree add ../review-pr42 origin/pr-42
Worktree Management
Listing Worktrees
git worktree list
Output shows each worktree path, its HEAD commit, and the branch name. Add --porcelain for machine-parseable output.
Removing Worktrees
The correct way -- handles both the directory and internal tracking:
git worktree remove ../hotfix-login
Use --force if the worktree has uncommitted changes you want to discard.
Moving Worktrees
git worktree move ../hotfix-login ../hotfix-auth
Moves the worktree directory and updates internal tracking. Cannot move the main worktree.
Lock and Unlock
Lock a worktree to prevent git worktree prune from removing it (useful for worktrees on removable drives or network mounts):
git worktree lock ../usb-worktree --reason "on external drive"
git worktree unlock ../usb-worktree
Pruning Stale Entries
git worktree prune
Removes internal tracking for worktrees whose directories no longer exist. Run with --dry-run first to see what would be pruned. See "Cleaning Up Orphaned Worktrees" below for more detail.
Directory Layout Strategies
Sibling directories (recommended)
~/projects/
myapp/ # main worktree
myapp-hotfix/ # hotfix worktree
myapp-review/ # PR review worktree
Keeps things flat. Easy to spot in file managers and terminal tabs. Each directory is self-contained.
Subdirectory layout
~/projects/myapp/
main/ # main worktree (bare repo is parent)
hotfix/
review/
Works well with the bare repo pattern (see below). All worktrees grouped under one parent.
Pick one convention per project and stick with it.
Common Workflows
Hotfix while mid-feature
You are deep in a feature branch with uncommitted changes. Production breaks.
# From your feature worktree, create a hotfix worktree
git worktree add -b hotfix/crash ../myapp-hotfix main
# Move to the hotfix directory
cd ../myapp-hotfix
# Fix the bug, commit, push
git commit -am "fix null pointer in auth handler"
git push origin hotfix/crash
# Go back to your feature work -- it is exactly as you left it
cd ../myapp
Review a PR while your branch is dirty
git fetch origin
git worktree add ../myapp-review origin/feature/new-api
cd ../myapp-review
# Read the code, run tests, leave comments
# Your in-progress work in the main worktree is untouched
When done:
git worktree remove ../myapp-review
Run tests on one branch while coding on another
Terminal 1: write code in your feature worktree. Terminal 2: run tests in a separate worktree:
git worktree add ../myapp-test main
cd ../myapp-test && npm test -- --watch
Compare behavior across branches side-by-side
Run the app from two worktrees on different ports:
# Terminal 1 # Terminal 2
cd ~/projects/myapp cd ~/projects/myapp-main
PORT=3000 npm start PORT=3001 npm start
Shared vs Separate Dependencies and Artifacts
Each worktree gets its own working tree -- separate node_modules, dist, build, .env, and generated files. You must run npm install (or your package manager) in each worktree independently. Build caches are not shared. If disk matters, use pnpm with a shared store. Symlink .env files across worktrees if they share the same config.
Bare Repo + Worktree Setup
Cloning with --bare gives you a repo with no default worktree. You then create all working directories as worktrees. This avoids the "main is already checked out" problem for the default branch.
git clone --bare git@github.com:user/myapp.git myapp/.bare
cd myapp
# Tell git where the bare repo lives
echo "gitdir: ./.bare" > .git
# Create worktrees for the branches you need
git worktree add main main
git worktree add develop develop
git worktree add feature/auth feature/auth
Dotfiles with bare repo
# Initial setup
git init --bare $HOME/.dotfiles
alias dotfiles='git --git-dir=$HOME/.dotfiles --work-tree=$HOME'
dotfiles config status.showUntrackedFiles no
dotfiles add ~/.zshrc ~/.gitconfig
dotfiles commit -m "add shell and git config"
# On a new machine
git clone --bare git@github.com:user/dotfiles.git $HOME/.dotfiles
alias dotfiles='git --git-dir=$HOME/.dotfiles --work-tree=$HOME'
dotfiles checkout
Handling Submodules with Worktrees
Worktrees do not automatically initialize submodules. Run git submodule update --init --recursive in each new worktree. Each worktree has its own index tracking submodule commits, so different branches can have different submodule states without conflict.
git worktree add ../myapp-hotfix hotfix/crash
cd ../myapp-hotfix
git submodule update --init --recursive
CI/CD Patterns with Worktrees
Test multiple branches in a single CI job without multiple clones:
git fetch origin main feature/new-api
git worktree add /tmp/test-main main
git worktree add /tmp/test-feature origin/feature/new-api
# Run tests in parallel
(cd /tmp/test-main && npm ci && npm test) &
(cd /tmp/test-feature && npm ci && npm test) &
wait
# Clean up
git worktree remove /tmp/test-main
git worktree remove /tmp/test-feature
Saves CI time and disk compared to multiple full clones.
IDE Integration
VS Code: code ../myapp-hotfix opens a new window with independent file state, terminal, and git status. Multi-root workspaces can combine multiple worktrees in one window.
JetBrains: File > Open the worktree directory. Opens as a separate project with shared git history detected automatically.
Vim/Neovim: cd into the worktree and open your editor. Fugitive and other git plugins pick up worktree context automatically.
Every worktree is a normal directory on disk -- any editor that can open a folder works without special configuration.
Worktree-Aware Scripts and Aliases
# List worktrees with short names
alias gwl='git worktree list'
# Quick-create a worktree for a branch
gwa() {
local branch="$1"
local dir="../$(basename "$(pwd)")-$(echo "$branch" | tr '/' '-')"
git worktree add "$dir" "$branch" && cd "$dir"
}
# Quick-create a worktree with a new branch from main
gwn() {
local branch="$1"
local dir="../$(basename "$(pwd)")-$(echo "$branch" | tr '/' '-')"
git worktree add -b "$branch" "$dir" main && cd "$dir"
}
# Remove current worktree and go back to main
gwr() {
local current="$(pwd)"
local main="$(git worktree list | head -1 | awk '{print $1}')"
cd "$main" && git worktree remove "$current"
}
# Check if inside a linked worktree
is_linked_worktree() {
[ -f "$(pwd)/.git" ] && echo "linked worktree" || echo "main worktree or not a worktree"
}
Common Mistakes
Deleting the directory without git worktree remove. Leaves orphaned entries in .git/worktrees/. Fix with git worktree prune --dry-run then git worktree prune. Always prefer git worktree remove -- it handles both the directory and tracking in one step.
Trying to check out the same branch in two worktrees. Git prevents this to avoid conflicting work on the same ref.
# This will fail if 'main' is already checked out somewhere
git worktree add ../myapp-second main
# fatal: 'main' is already checked out at '/path/to/myapp'
Workaround: use --detach to check out the commit without the branch, or commit changes and use a temporary branch.
Forgetting to install dependencies in new worktrees. Each worktree has its own node_modules / venv / etc. Always run your install step after creating a worktree.
Running git gc aggressively. Objects are shared, so git gc in any worktree affects all of them. Aggressive pruning can remove objects still referenced by another worktree's index. Generally safe with default settings.
Expecting worktree-specific config. git config writes to the shared config by default. Use git config --worktree (Git 2.20+) after enabling extensions.worktreeConfig for per-worktree settings.
Quick Reference
| Action | Command |
|---|---|
| Create from existing branch | git worktree add <path> <branch> |
| Create with new branch | git worktree add -b <new-branch> <path> <start-point> |
| Create detached HEAD | git worktree add --detach <path> <commit> |
| List all worktrees | git worktree list |
| List (machine-readable) | git worktree list --porcelain |
| Remove a worktree | git worktree remove <path> |
| Move a worktree | git worktree move <old-path> <new-path> |
| Clean stale entries | git worktree prune |
| Preview prune | git worktree prune --dry-run |
| Lock a worktree | git worktree lock <path> |
| Lock with reason | git worktree lock <path> --reason "why" |
| Unlock | git worktree unlock <path> |