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/remove、lsof、.env.localの編集… カーソルが VS Code とターミナルの間を無限に往復して、思考が切れる。
この「小さなストレス」を全部なくすために、見える化・ポート自動化・カラー切替 の 3 点セットを作ろう、と勢いで決めました。
2. 初めての Marketplace 公開でやったこと
「とりあえず GitHub に置くだけ」と違い、Marketplace 公開はちょっと儀式があります。今回やった手順はこんな感じでした。
- Publisher 登録: Microsoft アカウントで Partner Center にログインし、VS Code Publisher を作成。意外とここが一番緊張しました。
-
アイコン準備: 128/64/32 の PNG を揃える必要があったので
scripts/generate-icon.jsを書いて、単色ベースにロゴを載せる形で自動生成。 - README を英語化: Marketplace に並ぶので英語で伝わるようにリライト。今回 README も完全英語版にしたのはこのためです。
-
.vsixビルド:pnpm run compile→vsce package。リリースタグごとにgitportree-0.0.x.vsixを出力して、READMEの手動インストール手順にも添付。 -
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 ポートゾーンという発想
frontend と backend のポートがぶつかるのを避けるには「ゾーン」を決めるしかないと思い、サービスごとに 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_PORTとPORTを書き込み、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% の範囲でランダム気味に揺らし、「見た目が全部一緒」に見えないように工夫。
-
ThemeUpdaterがworkbench.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 パイプラインも自動化
開発しながら以下を整備しました。
-
pnpm run compileで TypeScript をビルド。 -
pnpm run vscode:prepublishでアイコン生成+コンパイルをまとめて実行。 -
vsce packageで.vsixを出す。生成物はリポジトリにコミットせず、リリースタグに添付。 -
vsce publish patch/minorで Marketplace にアップロード。
vsce publish が失敗した時は ~/.vsce のトークンを消して再ログインすると直る、というトラブルシューティングも経験しました。初回より 2 回目以降のほうがずっと速いです。
9. まとめ
Git worktree を「見える化・自動化・色分け」したい人には GitPortree がけっこう刺さると思います。Marketplace 初挑戦で学んだことも詰め込んだので、「自分も拡張を出してみようかな」と思っている方の背中も押せたら嬉しいです。フィードバックや PR はいつでも歓迎しています!
Discussion