「マージは成功したのに、最後の後片付けだけ失敗する」——git worktree で並列開発をしていると、ある日突然こんなエラーに出会います。
fatal: 'main' is already used by worktree at '/Users/xxx/repo-sub'
私も実際にこれを踏みました。この記事では、この現象を 図書館の本のたとえ で小学生でもわかるところから始めて、最後は git の内部構造まで潜ります。
自分の学び直しを兼ねて整理しているシリーズです。全部いきなり理解しなくて大丈夫。一歩ずついきましょう。
1. git worktree って結局何?(一言で)
ひとことで言うと「1つのリポジトリを、複数のフォルダで同時に開ける機能」です。
🔰 「リポジトリ」って何?
プロジェクトの すべての歴史が入った保管庫 です。学校の「学級文庫の棚」だと思ってください。棚には過去のノートが全部とってあります。
🔰 「ブランチ」って何?
作業の 枝分かれ です。たとえるなら「ノートのコピー」。本物のノート(main)を汚さないように、コピーに下書きして、うまく書けたら本物に清書(マージ)します。
🔰 「worktree」って何?
ふつう、リポジトリは 1 フォルダ = 1 作業場所です。worktree を使うと、同じ棚から本を何冊も、別々の机に持っていける ようになります。
- 机A(フォルダA)では「新機能のノート」を開く
- 机B(フォルダB)では「バグ修正のノート」を開く
- どちらも同じ棚(同じ歴史)につながっている
VS Code を机ごとに開けば、複数の作業を切り替えなしで並行できます。私は 9 個の worktree(机)を色分けして並列開発しています。
2. ある日、マージの後片付けが失敗した
私の環境で実際に起きたことです。
- 機能ブランチを GitHub で PR にした
- マージボタン相当のコマンド(
gh pr merge --squash --delete-branch)を実行 - マージ自体は成功
- なのに最後にこう言われた
failed to run git: fatal: 'main' is already used by worktree at '/Users/xxx/repo-sub'
🔰 「マージ」って何?
下書きノート(ブランチ)の内容を、本物のノート(main)に 合体させること です。
🔰 「squash マージ」って何?
下書きの細かい書き直し履歴を 1 ページにまとめてから 合体させる方式です。本物のノートがすっきりします。
エラーの意味はこうです。
「後片付けとして、あなたの手元の main も最新にしようとしたけど、main は別の机が借りてるから触れませんでした」
つまり リモート(GitHub 側)は成功、ローカルの後処理だけ失敗 という中途半端な状態になります。
3. 原因:ブランチは「図書館に 1 冊しかない本」
ここがこの記事でいちばん大事なところです。
git worktree には「同じブランチを同時に 2 つの机で開けない」というルールがあります。
図書館にたとえると:
- ブランチ = 図書館に 1 冊しかない本
- worktree = 閲覧席(机)
- 誰かが
mainという本を机に持って行ったら、返すまで他の人は借りられない
| たとえ | git の言葉 |
|---|---|
| 図書館の棚 | リポジトリ(.git) |
| 1 冊しかない本 | ブランチ |
| 閲覧席の机 | worktree(フォルダ) |
| 本を机に持っていく | checkout |
| 本を返す | 別ブランチに switch する |
私の場合、サブの worktree(机B)が main を借りっぱなし でした。しかもその机の上には、まだ記録していないファイルが 23 枚散らかっていました。
🔰 「checkout / switch」って何?
机の上に どの本(ブランチ)を広げるか選ぶ操作 です。git switch ブランチ名 で本を取り替えられます。
🔰 「untracked(未追跡)ファイル」って何?
机の上にあるけど まだ棚(git)に記録されていないプリント です。git はその存在を知らないので、消えても git は復元できません。放置は危険です。
4. なぜ「main を机で借りっぱなし」が悪いのか
3 つの実害があります。
その 1:他の場所で main が使えない
マージの後片付け、git checkout main、main への追従……全部「already used by worktree」で止まります。
その 2:main 直上の作業は事故のもと
main は「本物の清書ノート」。ここに直接書くと、未完成の変更が本番リリースに混ざる事故が起きえます。作業は必ず「下書きノート(feature ブランチ)」でやるのが鉄則です。
その 3:散らかった untracked ファイルが宙に浮く
main の上に未記録ファイルを溜めると、「これはどの作業の一部?」が誰にもわからなくなります。
5. 直し方は 3 ステップ(実録)
私が実際にやった手順です。ファイルは 1 つも消えません。
# 机B(main を借りっぱなしの worktree)に移動
cd ~/repo-sub
# ① 新しい下書きノートを作る(この瞬間、main が返却される!)
git switch -c feature/workspace
# ② 机の上のプリントを記録する
git add -A
git commit -m "chore: 散らかっていた未追跡ファイルを作業ブランチへ退避"
# ③ main が解放されたか確認
git worktree list
# → どの机にも [main] が表示されなければ成功
ポイントは ① です。git switch -c(新ブランチ作成)は 机の上のファイルをそのまま残して、開いている本だけ差し替える 操作。untracked ファイルは 1 枚も動きません。安心してください。
🔰 「git worktree list」って何?
どの机がどの本を開いているかの一覧表 です。トラブル時はまずこれを見ます。
/Users/xxx/repo abc1234 [feature/new-ui]
/Users/xxx/repo-sub def5678 [feature/workspace] ← main じゃなくなった!
補足:大事なデータの扱い
記録の前に 1 つだけ手間をかけました。大事なデータ(連絡先など)を含むファイルは、そもそも git に入らない専用フォルダ(.gitignore 済みの .private/)で扱う仕組みにしています。 もし作業ファイルに混ざっていても、記録前に専用フォルダへ移してから commit する——最初からこの流れにしておくと、「うっかり歴史に刻んでしまった」が起きません。
6. 上級者向け:内部で何が起きているか
ここからは深掘りです。お急ぎの方はまとめへどうぞ。
worktree の実体は .git/worktrees/<名前>/ にあります。各 worktree は自分専用の HEAD ファイルを持ち、そこに「いま開いているブランチ」への参照(ref: refs/heads/main など)が書かれています。
git が「already used」と判定するのは、全 worktree の HEAD を走査して、同じ ref を指す机が既にあるか を見ているからです。二重 checkout を許すと、同じブランチ先端に対して 2 か所から別々の commit ができてしまい、片方が迷子(先端の付け替え競合)になるためのガードです。
回避オプションも一応あります(推奨はしません):
-
git worktree add --detach ~/tmp main— ブランチを「借りず」に中身だけ広げる(detached HEAD)。読み取り専用の確認用途なら合法です。 -
--forceでの二重 checkout は競合の危険をそのまま引き受けることになるのでやめましょう。
squash マージ後の後片付けでこのエラーが出た場合、リモートは既に成功しています。慌てず git ls-remote やマージコミットの存在確認で「どこまで成功したか」を切り分けてから、ローカルだけ直せば OK です。
設計としての教訓はこうです:
main はどの机にも置かない。 main は「棚の中の正本」として扱い、各机は必ず feature ブランチだけを開く。統合作業も
origin/main基準(git fetch+git rebase origin/main)で行えば、ローカル main を checkout する必要はほぼありません。
7. 再発防止チェックリスト
-
git worktree listを定期的に見る(朝 1 回でOK) - main を開いている机がないか確認する
- 作業は必ず feature ブランチで(main 直上に書かない)
- untracked ファイルを 3 日以上放置しない(下書きでも commit する)
- 大事なデータは最初から git 外の専用フォルダで扱う
- マージ後に後片付けエラーが出たら、まず「リモートは成功しているか」を確認
まとめ — 「1 冊しかない本」は不便ではなく安全装置
「同じブランチは 1 つの机でしか開けない」というルールは、最初は不便に感じます。
でも裏返せば、「本物のノートに、2 か所から同時に書き込んで壊す」事故を git が体を張って止めてくれている ということです。
エラーメッセージは敵ではなく、安全装置の作動音。意味がわかれば、直すのは 3 行のコマンドでした。
worktree での並列開発はとても快適です。全部いきなり完璧にしなくて大丈夫。まずは git worktree list を 1 回眺めるところから始めてみてください。
参考資料
著者について
臨床工学技士 × AI エンジニア。教育関係の仕事もしています。
医療と IT のあいだで動きながら、現場目線で発信中です。
- note: https://note.com/taichi_endoh
- Qiita: https://qiita.com/TaichiEndoh
- X: https://x.com/endoh_taichi
質問・情報提供・コラボ提案、いつでも歓迎です。