シナプス技術者ブログ

シナプスの技術者公式ブログ。インターネットで、鹿児島の毎日を笑顔にします。

Git worktreeを使ってみた

こんにちは。サービス開発課の田㞍です。
今回は、最近知った「Git worktree」という機能について紹介します。
少し触ってみたところ、「これは普段感じていたGitの悩みを解決してくれそうだ!」と便利さを実感したので、まとめてみました。

きっかけ

ある日、課のメンバーと開発フォルダの整理について話していたとき、先輩から「Git worktreeも試してみたら?便利だよ」と勧められたのが、この機能を知ったきっかけでした。

まずはおさらい:Gitの基本と「ブランチ」

Gitは、ソースコードの変更履歴を管理する「分散型バージョン管理システム」です。
以下のようなメリットがあり、現代の開発には欠かせないツールです。

  • 【履歴の記録】いつ、誰が、何を変更したか記録する
  • 【安全な分岐】メインライン(main)に影響を与えず安全に開発する
  • 【簡単な復元】過去の状態に復元する

通常、私たちは「ブランチ」を使って並行作業を行いますが、ここには一つの原則があります。

原則:1つの作業ディレクトリ(worktree)では、同時に1つのブランチしかチェックアウトできない

そのため、別のブランチの作業をするには、今いる場所を「切り替え(checkout / switch)」する必要があります。これが、意外と面倒な問題を引き起こすのです。

Git開発でよくある「悩み」

皆さんもこんな経験はありませんか?

急な割り込みタスクが入ったとき

機能A(ブランチA)を開発中。まだ書きかけでコミットできる状態ではない…。
そんな時に「緊急のバグ修正お願いします!」という割り込みが。

「まだコミットできない…とりあえず git stash して…」

バグ修正対応

「終わったから戻ろう。git stash pop して…あれ、どこまでやってたっけ?」

複数人で作業しているとき(コードレビューなど)

チーム開発では、レビュー依頼などで、自分の作業を中断してレビュー対象のブランチをチェックアウトする場面がよくあります。

自分の作業を git stash して他人のコードを確認

終わったらまた戻してgit stash popする…

その瞬間に 「コンフリクト(競合)が発生!」

なんてことになると、本来の作業に戻るだけで一苦労です。

このように、「作業の中断・再開」や「一時退避」が重なると、 「あれ、さっきまで何してたっけ…?」 と頭を切り替えるのに疲れてしまったり、 「stashしたデータが増えすぎて、どれがどれだか分からない!」 といった状況に陥りがちです。

救世主「Git worktree」とは?

Git worktreeは、1つのGitリポジトリから、複数の「作業ディレクトリ(worktree)」を同時に扱えるようにする機能 です。

通常、1つのリポジトリには1つの作業ディレクトリしかありませんが、worktree機能を使うと、「ブランチごとに専用のディレクトリ」 を生成することができます。

普通のGit運用との違い

  • これまで:
    • ブランチを切り替える前に、変更内容を git commitgit stash で保存する必要がある。
    • 同じフォルダの中で中身だけが入れ替わるイメージ。
  • Git worktree:
    • 別のフォルダとしてブランチが展開されている。
    • 作業中の状態(書きかけのコード)をそのまま放置して、別のディレクトリ(別のブランチ)で作業ができる!
    • git stash が不要になる。

リポジトリ構造のイメージ

実際にどうなっているのか、ディレクトリ構造のイメージで見てみましょう。
.git の実体は共有しつつ、作業場所だけが増える仕組みです。

my-project/                     # mainのワークツリー(mainブランチ)
├── .git/                       # 履歴の本体(mainもfeature_Aも全てここで管理)
│   ├── objects/
│   ├── worktrees/              # worktreeの管理情報
│   │   └── feature_A           
│   └── ...
├── index.html
└── style.css

# git worktree add で作成したfeature_Aブランチ用のワークツリー
# プロジェクトフォルダの「隣」などに作成される
../feature_A/                   # feature_A ブランチ専用の作業場
├── .git                        # ← リンクファイル(本体を参照している)
├── index.html
└── style.css

基本的な使い方(コマンド紹介)

使い方は非常にシンプルです。

1. 作成する (Add)

新しい作業ディレクトリを作成し、特定のブランチを紐付けます。

# git worktree add -b <新しいブランチ名> <作成するフォルダパス>
# 例:今のフォルダの「隣」に feature_A という作業場を作る
$ git worktree add -b feature_A ../feature_A

※今のプロジェクトフォルダの中に入れ子にするのではなく、「外(隣)」 に作るのがおすすめです。

2. 一覧を見る (List)

現在稼働しているworktreeの一覧を表示します。

$ git worktree list

3. 削除する (Remove)

使い終わったworktreeを片付けます。

# git worktree remove <フォルダパス>
$ git worktree remove ../feature_A

注意点とTips

実際に使ってみて分かった注意点やTipsをまとめました。

■ 同じブランチは同時にチェックアウトできない

「mainブランチ」を元のフォルダで開きつつ、追加したworktreeでも「mainブランチ」を開く…ということはできません。Gitが安全のために防いでくれます。

■ フォルダは「並列」に置くのがベスト

プロジェクトフォルダの中にworktreeフォルダを作ってしまうと、「Gitが新しいファイルだと勘違いしてコミットしようとする」「エディタの検索結果に両方のブランチのファイルが出てきて混乱する」 といったトラブルの原因になります。
そのため、../feature_A のように指定して、今のプロジェクトフォルダの「外(隣)」に作るのがベストプラクティスとされています。

■ 場所移動 = ブランチ切り替え

これが最大のメリットです。
ターミナルで cd ../feature_A と移動するだけで、もうそこは feature_A ブランチの世界です。VSCodeなどのエディタで複数のウィンドウを開いておけば、ウィンドウを切り替えるだけでブランチ切り替えが完了します。

■ 削除はコマンドで行う

フォルダをFinderやエクスプローラーで直接ゴミ箱に入れてはいけません。Git内部の管理情報と不整合が起きてしまいます。必ず git worktree remove コマンドを使って後始末をしましょう。

まとめ

Git worktreeは、開発者の悩みの種である「頻繁なブランチ切り替え」や「stash地獄」を解決してくれる強力なツールだと感じました。

最大のメリットは、何と言っても「今やっている作業の手を止めずに、別の作業を並行して進められる」ことです。

書きかけのコードやエディタの状態を崩すことなく、別のフォルダでサッと新しいタスクに取り掛かれるため、レビュー依頼や急な修正などの「割り込みタスク」へのストレスが大幅に減ります。

まだ使い始めたばかりですが、これから実際の開発フローにも取り入れていこうと思います。皆さんもぜひ試してみてください!

参考リンク