🌲

Git worktreeをVS Codeでかんたんに作りたくて拡張作った

に公開

Git worktreeをvs codeでかんたんに作りたくて拡張作った

Git の worktree を VS Code からいい感じに扱いたい──その勢いだけで GitPortree という拡張を作り、ついでに VS Code Marketplace に初公開しました。モノレポで Next.js / backend / admin を同時起動するときの「ポート地獄」と「どのウィンドウがどのブランチ?」問題を一気に片付けるのが目標です。

Marketplace: https://marketplace.visualstudio.com/items?itemName=tatsuro13.gitportree
GitHub: https://github.com/tatsuro13/gitportree


1. そもそも何がつらかった?

  • ポート衝突祭り: worktree を 3 つ並べるだけで 3000, 3001, 3002… が埋まっていき、.env.local を手修正する羽目に。複数ブランチを行き来していると「昨日の port なんだっけ?」で時間が溶ける。
  • ブランチ誤爆: VS Code ウィンドウがずらっと並び、どれが hotfix/xxx でどれが feature/yyy なのか一瞬で判別できない。deploy 直前に別ブランチを直していた…という事故を本当にやらかしました。
  • CLI の往復: git worktree add/removelsof.env.local の編集… カーソルが VS Code とターミナルの間を無限に往復して、思考が切れる。

この「小さなストレス」を全部なくすために、見える化・ポート自動化・カラー切替 の 3 点セットを作ろう、と勢いで決めました。


2. 初めての Marketplace 公開でやったこと

「とりあえず GitHub に置くだけ」と違い、Marketplace 公開はちょっと儀式があります。今回やった手順はこんな感じでした。

  1. Publisher 登録: Microsoft アカウントで Partner Center にログインし、VS Code Publisher を作成。意外とここが一番緊張しました。
  2. アイコン準備: 128/64/32 の PNG を揃える必要があったので scripts/generate-icon.js を書いて、単色ベースにロゴを載せる形で自動生成。
  3. README を英語化: Marketplace に並ぶので英語で伝わるようにリライト。今回 README も完全英語版にしたのはこのためです。
  4. .vsix ビルド: pnpm run compilevsce package。リリースタグごとに gitportree-0.0.x.vsix を出力して、README の手動インストール手順にも添付。
  5. Publish: vsce publish を叩くと 1〜2 分で Marketplace に反映。初回は「Validation 失敗しました」と怒られ、galleryBanner.color が設定されていないのが原因だと気づくまで 30 分ほどハマりました。

大きく詰まったのは「README 英語版どうしよう?」と「Marketplace の審査エラーがどこで出ているか全然分からない」あたり。vsce のログを --logLevel trace にしてようやくエラー箇所に気付いたので、これから挑戦する人は最初からログを濃く出したほうが平和です。


3. Worktree Explorer で全部見えるように

まずは「CLI を開かなくても状況が分かる」ことをゴールにしました。git worktree list --porcelain の結果を WorktreeScanner が解析し、以下の情報をまとめて VS Code の TreeView に流し込みます。

  • ブランチ名 / パス / HEAD / 経過日数 (.git/worktrees/<name>/config → fallback に fs.stat).
  • git status --porcelain の行数を Δ3 のようなバッジにして表示。
  • サービス(frontend/backend/api 等)と割り当てポートを子ノードで表示。
  • ホバーすると offset / base branch / 更新日時 / status が見えるよう WorktreeItem で tooltip を生成。

スタイリングとはいえ、port 情報までツリーに並べておくと「この worktree で backend を起動すると 4012 番ポートね」と即分かります。小ネタだけど地味に効く UI でした。


4. 100 ポートゾーンという発想

frontendbackend のポートがぶつかるのを避けるには「ゾーン」を決めるしかないと思い、サービスごとに 100 ポート幅のブロックを確保しました。

frontend → 3000–3099
backend  → 4000–4099
admin    → 5000–5099
api      → 5500–5599
unknown  → 6000–6099
  • サービス名を 31 ベースのハッシュにかけ zoneSize = 100 で mod を取る。これで「サービス内の席順」が決まる。
  • Worktree offset も offset % zoneSize で正規化し、ゾーンの中だけで回す。
  • 最終ポートは base + ((hash + offset) % zoneSize)。これで worktree が 20 個あっても frontend が backend のゾーンに侵入しません。
  • .env.local には SERVICE_NAME_PORTPORT を書き込み、Next.js などは PORT をそのまま読むだけで OK。

実装は src/port/PortAllocator.ts の 40 行足らずですが、設計を決めるまでが長かったです。最初は「base + offset」で組んでいたものの、速攻で 3100 が backend とぶつかって泣きそうになり、ゾーン制に逃げ込みました。


5. Worktree ごとにウィンドウの色が変わる快感

誤操作を防ぐには視覚的なフィードバックが一番効く、ということで Activity Bar / Status Bar / Title Bar をブランチごとに recolor しています。

  • ColorGenerator がブランチ名の文字コードから hash を取り、Blue / Green / Yellow の 3 系統を決める。
  • 彩度と明度は 35〜55% の範囲でランダム気味に揺らし、「見た目が全部一緒」に見えないように工夫。
  • ThemeUpdaterworkbench.colorCustomizations を workspace 単位で更新。開くたびに色が変わるので「あ、このウィンドウは hotfix のやつだ」と一発で分かるようになりました。

ライトテーマ環境だとまだ見づらい配色があるので、テーマ別のパレットを作るのが今後の課題です。


6. コマンドでワークフローをまとめる

提供しているコマンドは以下の 7 つ。ほぼ「必要になった順」に増えていきました。

Command 使いどころ
GitPortree: Refresh TreeView を再読み込み。Git の状態が変わったらすぐ押すボタン。
GitPortree: Create Worktree ベースブランチを QuickPick → 新ブランチ名 → パス入力 → git worktree add → ポート設定 → カラー適用まで自動化。
GitPortree: Open Worktree TreeItem をクリックした瞬間に VS Code がその worktree を新ウィンドウで開く。
GitPortree: Remove Worktree git worktree remove <path> を実行し、完了通知。
GitPortree: Copy Port Info service: port の一覧をクリップボードに。チームに瞬時に共有できる。
GitPortree: Change Worktree 最近開いた worktree を QuickPick から選び直せる。
GitPortree: Delete Worktree Branch GitPortree が管理しているブランチを安全に削除。

Finder/Terminal/Split で開くアクションはまだ未実装ですが、需要があるので優先度を上げる予定です。


7. 実装でハマったところと工夫

  • Git CLI の同期/非同期問題: git status を全 worktree で並列に投げると CPU が悲鳴を上げたので、Promise.all の数を制御しつつキャッシュも導入。WorktreeScanner が一番手強い部分でした。
  • .env.local の扱い: 上書きで壊したくなかったので EnvWriter で一旦マップを作ってから出力。差分マージやバックアップは今後の宿題ですが、少なくともキー重複は避けられます。
  • 色の適用タイミング: Workspace を開く前に ThemeUpdater を走らせると VS Code が設定書き換え中で怒るケースがあり、openWorktree の直前に await するように変更して解決しました。
  • Marketplace の Validation: README に英語が含まれていないと rejection される (2025/12 時点) ので、「英語+日本語のミックス」から「英語のみ」へ書き換えました。

8. Publish パイプラインも自動化

開発しながら以下を整備しました。

  1. pnpm run compile で TypeScript をビルド。
  2. pnpm run vscode:prepublish でアイコン生成+コンパイルをまとめて実行。
  3. vsce package.vsix を出す。生成物はリポジトリにコミットせず、リリースタグに添付。
  4. vsce publish patch/minor で Marketplace にアップロード。

vsce publish が失敗した時は ~/.vsce のトークンを消して再ログインすると直る、というトラブルシューティングも経験しました。初回より 2 回目以降のほうがずっと速いです。


9. まとめ

Git worktree を「見える化・自動化・色分け」したい人には GitPortree がけっこう刺さると思います。Marketplace 初挑戦で学んだことも詰め込んだので、「自分も拡張を出してみようかな」と思っている方の背中も押せたら嬉しいです。フィードバックや PR はいつでも歓迎しています!

Discussion