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 で main が「借りっぱなし」になる罠 — 図書館の本にたとえて、小学生から上級者までやさしく解説します

1
Posted at

「マージは成功したのに、最後の後片付けだけ失敗する」——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. ある日、マージの後片付けが失敗した

私の環境で実際に起きたことです。

  1. 機能ブランチを GitHub で PR にした
  2. マージボタン相当のコマンド(gh pr merge --squash --delete-branch)を実行
  3. マージ自体は成功
  4. なのに最後にこう言われた
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 のあいだで動きながら、現場目線で発信中です。

質問・情報提供・コラボ提案、いつでも歓迎です。

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?