1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Git Worktreeで複数ブランチを同時に扱う方法

Posted at

はじめに

「機能開発中に緊急のバグ修正が入った...」
「2つのブランチのコードを並べて比較したい...」
「ブランチ切り替えのたびにサーバーを再起動するのが面倒...」

こんな経験、ありませんか?

Git Worktreeを使えば、これらの問題が一気に解決します。この記事では、Git Worktreeの基本から実践的な使い方まで、図解を交えて徹底解説します。

対象読者

  • Gitの基本操作(commit, branch, checkout)を理解している方
  • 複数のブランチを頻繁に切り替える方
  • 開発効率を上げたい方

Git Worktreeとは?

Git Worktreeは、1つのGitリポジトリで複数の作業ディレクトリを同時に使える機能です。

通常のGitの問題点

通常、別のブランチで作業したい場合:

  1. 現在の作業をコミットまたはstash(退避)
  2. git checkoutでブランチを切り替え
  3. 作業完了後、元のブランチに戻る

これが頻繁に発生すると、かなり面倒ですよね。

Worktreeによる解決

Worktreeを使うと:

my-project/          # mainブランチ
├── .git/
├── index.html
└── style.css

my-project-feature/  # featureブランチ(同時に存在!)
├── .git → リンク
├── index.html
└── style.css

同じリポジトリの異なるブランチを、別々のディレクトリで同時に開けるようになります。

通常のブランチ切り替えとの比較

従来の方法

# mainブランチで作業中
$ git status
On branch main
Changes not staged for commit:
  modified: index.html

# 緊急バグ修正のためにブランチを切り替えたい
$ git stash  # 作業を退避
$ git checkout hotfix
# バグ修正...
$ git checkout main
$ git stash pop  # 作業を復元

Worktreeを使った方法

# mainブランチで作業中(そのまま継続可能!)
$ cd ~/projects/my-project

# 緊急バグ修正用のworktreeを作成
$ git worktree add ../my-project-hotfix hotfix

# 別のターミナルでhotfixディレクトリへ移動
$ cd ../my-project-hotfix
# バグ修正...

# 元のディレクトリでは作業継続!

Git Worktreeの内部構造

Cloneとは違う!

重要なポイント:Worktreeはclone(複製)ではありません

Cloneの場合(容量2倍)

元のリポジトリ: 1 GB (.git全体 + 作業ファイル)
Clone: 1 GB (.git全体 + 作業ファイル)
合計: 2 GB

Worktreeの場合(作業ファイル分のみ追加)

元のリポジトリ: 1 GB (.git全体 + 作業ファイル)
Worktree: 0.1 GB (作業ファイルのみ)
合計: 1.1 GB

仕組み:.gitディレクトリの共有

my-project/.git/          # 本体(すべてのデータ)
├── objects/              # ← 共有される
├── refs/                 # ← 共有される
├── worktrees/
│   └── feature/
│       ├── HEAD          # このworktreeのブランチ情報
│       └── gitdir        # リンク情報
└── config

my-project-feature/.git   # ファイル(ディレクトリではない!)
                          # 中身: gitdir: /path/to/my-project/.git/worktrees/feature

ポイント:

  • メインディレクトリの.gitディレクトリ
  • Worktreeの.gitファイル(リンク情報)
  • 履歴、設定、オブジェクトはすべて共有

実際に確認してみる

# メインディレクトリの.gitはディレクトリ
$ ls -la my-project/.git
drwxr-xr-x  12 user  staff  384 .

# Worktreeの.gitはファイル
$ ls -la my-project-feature/.git
-rw-r--r--   1 user  staff   62 .git

# 中身を見る
$ cat my-project-feature/.git
gitdir: /Users/user/projects/my-project/.git/worktrees/feature

基本的な使い方

1. Worktreeの作成

既存のブランチを使う場合:

$ git worktree add <ディレクトリパス> <ブランチ名>

# 例
$ git worktree add ../my-project-feature feature

新しいブランチを作成する場合:

$ git worktree add -b <新ブランチ名> <ディレクトリパス>

# 例:new-featureブランチを作成して、../my-project-new-featureディレクトリに配置
$ git worktree add -b new-feature ../my-project-new-feature

2. Worktreeの一覧表示

$ git worktree list

# 出力例
/Users/user/projects/my-project              abc1234 [main]
/Users/user/projects/my-project-feature      def5678 [feature]
/Users/user/projects/my-project-hotfix       ghi9012 [hotfix]

3. Worktreeの削除

まず、作業ディレクトリを削除:

# 方法1: Gitコマンドで削除(推奨)
$ git worktree remove ../my-project-feature

# 方法2: 手動削除後、情報をクリーンアップ
$ rm -rf ../my-project-feature
$ git worktree prune

4. Worktreeの移動

$ git worktree move <現在のパス> <新しいパス>

# 例
$ git worktree move ../my-project-feature ../renamed-feature

実践的な使用例

ケース1:緊急バグ修正

シナリオ: 機能開発中に本番環境でバグが見つかった

# 現在feature-loginブランチで開発中
$ pwd
/Users/user/projects/my-app

# 緊急修正用のworktreeを作成
$ git worktree add ../my-app-hotfix main

# 新しいターミナルでhotfixディレクトリへ移動
$ cd ../my-app-hotfix

# hotfixブランチを作成
$ git checkout -b hotfix-payment-bug

# バグ修正を実施
$ vim src/payment.js
$ git add .
$ git commit -m "Fix: Payment calculation error"
$ git push origin hotfix-payment-bug

# 元のディレクトリに戻る
$ cd ~/projects/my-app
# feature-loginの開発をそのまま継続!

メリット:

  • 作業中のコードをstashする必要なし
  • 未コミットの変更を保持したまま別作業が可能
  • コンテキストスイッチのストレスが激減

ケース2:コードレビュー・比較

シナリオ: PRのコードと現在のコードを並べて比較したい

# 現在のブランチ
$ pwd
/Users/user/projects/my-app

# レビュー対象のブランチをworktreeとして追加
$ git worktree add ../my-app-review feature/pr-123

# VSCodeで両方のディレクトリを開く
$ code ~/projects/my-app
$ code ~/projects/my-app-review

# 2つのウィンドウで並べて比較!

ケース3:デザインのA/Bテスト

シナリオ: 2つのデザイン案をブラウザで同時に確認したい

# デザインA(mainブランチ)
$ cd ~/projects/my-app
$ npm run dev
# → http://localhost:3000

# デザインB(新しいworktree)
$ git worktree add ../my-app-design-b design-b
$ cd ../my-app-design-b
$ PORT=3001 npm run dev
# → http://localhost:3001

# ブラウザで2つのタブを開いて比較!

localhostでのサーバー起動について

ポート番号の重複に注意

各worktreeは完全に独立したディレクトリなので、それぞれで別のサーバーを起動できます。ただし、同じポート番号は使えません

❌ エラーケース

# Terminal 1
$ cd my-project
$ npm run dev
# Server running at http://localhost:3000

# Terminal 2
$ cd my-project-feature
$ npm run dev
# Error: Port 3000 is already in use

✅ 正しい方法

# Terminal 1
$ cd my-project
$ npm run dev
# Server running at http://localhost:3000

# Terminal 2
$ cd my-project-feature
$ PORT=3001 npm run dev
# Server running at http://localhost:3001

主要フレームワークでのポート変更方法

Vite (React, Vue)

# コマンドライン
$ npm run dev -- --port 3001

# 環境変数
$ PORT=3001 npm run dev

# vite.config.js
export default {
  server: {
    port: 3001
  }
}

Next.js

# コマンドライン
$ npm run dev -- -p 3001

# 環境変数
$ PORT=3001 npm run dev

# package.json
"scripts": {
  "dev": "next dev -p 3001"
}

Create React App

# 環境変数
$ PORT=3001 npm start

# .envファイル
PORT=3001

Node.js (Express)

// app.js
const port = process.env.PORT || 3001;
app.listen(port, () => {
  console.log(`Server running on port ${port}`);
});
$ PORT=3001 node app.js

データベース接続の注意点

複数のworktreeで同じデータベースに接続すると、データの整合性に問題が出る可能性があります。

推奨:環境変数で接続先を分ける

# my-project/.env.local
DATABASE_URL=postgresql://localhost:5432/myapp_main

# my-project-feature/.env.local
DATABASE_URL=postgresql://localhost:5432/myapp_feature

Worktreeのメリット

1. ⚡ 高速な切り替え

ブランチ切り替え不要。ディレクトリを移動するだけで別の作業に切り替え可能。

2. 🔄 並行作業が可能

複数のタスクを同時進行でき、開発効率が大幅アップ。

3. 📊 比較が簡単

2つのブランチをエディタで並べて比較できる。

4. 💾 作業の安全性

未コミットの変更を保持したまま別作業が可能。

5. 🧪 同時テスト実行

異なるブランチで同時にテストを実行できる。

6. 💻 省容量

Cloneと違い、作業ファイル分の容量しか追加されない。

Worktreeの注意点

1. 同じブランチは複数のworktreeで同時にチェックアウトできない

$ git worktree add ../my-app-copy main
fatal: 'main' is already checked out at '/Users/user/projects/my-app'

理由: コンフリクトを防ぐため

解決策: 新しいブランチを作成する

$ git worktree add -b main-copy ../my-app-copy main

2. node_modulesは共有されない

各worktreeでnpm installが必要です。

$ git worktree add ../my-project-feature feature
$ cd ../my-project-feature
$ npm install  # 必要!

理由: node_modules.gitignoreに含まれるため、各ディレクトリで独立して管理されます。

3. ディスク容量の消費

作業ファイル + node_modules分の容量が各worktreeで必要です。

対策: 使い終わったworktreeはこまめに削除する

$ git worktree remove ../my-project-feature

4. 古いWorktreeの管理

削除したディレクトリの情報が残っている場合:

# クリーンアップ
$ git worktree prune

# 強制削除
$ git worktree remove --force <path>

ベストプラクティス

1. 命名規則を統一する

# プロジェクト名-ブランチ名の形式
my-app/              # メイン
my-app-feature-login # feature/loginブランチ
my-app-hotfix-123    # hotfix/123ブランチ

2. 定期的な管理

# 現在のworktreeを確認
$ git worktree list

# 不要なworktreeを削除
$ git worktree remove <path>

# 情報をクリーンアップ
$ git worktree prune

3. エイリアスの設定

頻繁に使うコマンドはエイリアスで短縮:

# ~/.gitconfig
[alias]
    wa = worktree add
    wl = worktree list
    wr = worktree remove
    wp = worktree prune

使用例:

$ git wa ../my-app-feature feature
$ git wl
$ git wr ../my-app-feature

4. スクリプト化

よく使うパターンをスクリプト化:

#!/bin/bash
# create-worktree.sh

BRANCH_NAME=$1
PROJECT_NAME=$(basename $(pwd))
WORKTREE_PATH="../${PROJECT_NAME}-${BRANCH_NAME}"

git worktree add -b $BRANCH_NAME $WORKTREE_PATH
cd $WORKTREE_PATH
npm install

echo "Worktree created at $WORKTREE_PATH"

使用例:

$ ./create-worktree.sh new-feature

トラブルシューティング

Worktreeが削除できない

$ git worktree remove ../my-project-feature
fatal: validation failed, cannot remove working tree: ...

解決策:

# 強制削除
$ git worktree remove --force ../my-project-feature

# または、手動削除後にprune
$ rm -rf ../my-project-feature
$ git worktree prune

ブランチがロックされている

$ git checkout feature
fatal: 'feature' is already checked out at '/path/to/worktree'

解決策:

# worktreeの一覧を確認
$ git worktree list

# 該当のworktreeを削除
$ git worktree remove <path>

Gitバージョンが古い

WorktreeはGit 2.5以降で利用可能です。

# Gitバージョン確認
$ git --version

# アップデート(macOS)
$ brew upgrade git

# アップデート(Ubuntu)
$ sudo apt update
$ sudo apt upgrade git

Clone vs Worktree 比較表

項目 Clone Worktree
容量 ❌ 2倍(.gitも複製) ✅ 作業ファイル分のみ追加
履歴の共有 ❌ 独立(同期が必要) ✅ 自動的に共有
コミットの可視性 ❌ pushしないと見えない ✅ 即座に見える
設定の共有 ❌ 独立 ✅ 共有
作成速度 ❌ 遅い(すべて複製) ✅ 速い(ファイルのみ)
用途 別プロジェクト、バックアップ 同じプロジェクトの並行作業

まとめ

Git Worktreeは、以下のような開発者におすすめの機能です:

  • ✅ 複数のブランチを頻繁に切り替える方
  • ✅ 緊急対応と通常作業を並行して行う必要がある方
  • ✅ コードレビューやデザイン比較を効率的に行いたい方
  • ✅ 開発サーバーを複数同時に起動したい方

最初の一歩

まずは簡単な例から試してみましょう:

# 1. 現在のリポジトリで
$ git worktree add ../my-project-test main

# 2. 新しいディレクトリに移動
$ cd ../my-project-test

# 3. 確認
$ git branch
$ ls -la

# 4. 使い終わったら削除
$ cd ../my-project
$ git worktree remove ../my-project-test

慣れてきたら、実際の開発フローに組み込んでみてください。きっと開発効率が大きく向上するはずです!

参考リンク

執筆者について

この記事が役に立ったら、ぜひLGTMお願いします!
質問やフィードバックがあれば、コメント欄でお気軽にどうぞ。


1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?