kakakakakku blog

Weekly Tech Blog : Keep on Learning 👍

git worktree コマンドを使って複数ブランチを並行して操作する

個人で使っている Git リポジトリ(GitHub リポジトリ)の中に「複数ブランチを並行して操作する頻度が高いリポジトリ」がある.例えば,以下のように「4個」のブランチがあり,どれも操作する可能性がある場合など.今までは頻繁にコミット(git commit コマンド)をしてからブランチを切り替えたり,一時的に退避(git stash コマンド)をしていたけど,頻度が高くなると少し面倒だった.

  • master or main ブランチ
  • branch-a ブランチ
  • branch-b ブランチ
  • branch-c ブランチ

git-worktree(git worktree コマンド)

操作を改善するために調べたところ「git-worktree」という機能があった.今まで知らなかった!そして Git 2.5(2015年7月リリース)から使える機能だった📣「git-worktree(git worktree コマンド)」は,複数ブランチを並行して操作するための機能で,ドキュメントには Manage multiple working trees と書いてある.より正確に表現するなら,指定したブランチを指定したディレクトリ(基本的にどこでも!)にチェックアウトできる.最近使っていて本当に便利なので紹介する💡

git-scm.com

git-worktree : 基本操作(list / add / remove

さっそく基本操作から試していく!今回は検証用の Git リポジトリ sandbox-git-worktree を使う.まず git worktree list コマンドを実行すると「作業ツリー」の一覧を確認できる.最初は master 1個となる.

$ git worktree list
/Users/kakakakakku/ghq/github.com/kakakakakku/sandbox-git-worktree  670f24f [master]

次に git worktree add コマンドを実行して「作業ツリー」を追加する.今回は dummy という名前にする.すると,自動的に dummy ディレクトリが作られる.そして dummy ディレクトリに移動すると master ブランチから dummy ブランチに切り替わっている.

$ git branch --show-current
master

$ git worktree add dummy
Preparing worktree (new branch 'dummy')
HEAD is now at 670f24f Initial commit

$ git worktree list
/Users/kakakakakku/ghq/github.com/kakakakakku/sandbox-git-worktree        670f24f [master]
/Users/kakakakakku/ghq/github.com/kakakakakku/sandbox-git-worktree/dummy  670f24f [dummy]

$ tree ../sandbox-git-worktree
../sandbox-git-worktree
├── README.md
└── dummy
    └── README.md

1 directory, 2 files

$ cd dummy

$ git branch --show-current
dummy

不要になったら git worktree remove コマンドを実行して「作業ツリー」を削除できる.

$ cd ../

$ git worktree remove dummy

$ git worktree list
/Users/kakakakakku/ghq/github.com/kakakakakku/sandbox-git-worktree  670f24f [master]

git-worktree : 既存ブランチを使う

git worktree add コマンドは git worktree add <path> <branch> という構文をサポートしているため,既存ブランチを使うこともできる.例えば branch-abranch-bbranch-c が存在する場合,以下のように「作業ツリー」を追加できる.

$ git worktree add wt-branch-a branch-a
$ git worktree add wt-branch-b branch-b
$ git worktree add wt-branch-c branch-c

$ tree ../sandbox-git-worktree
../sandbox-git-worktree
├── README.md
├── wt-branch-a
│   └── README.md
├── wt-branch-b
│   └── README.md
└── wt-branch-c
    └── README.md

3 directories, 4 files

$ git worktree list
/Users/kakakakakku/ghq/github.com/kakakakakku/sandbox-git-worktree              670f24f [master]
/Users/kakakakakku/ghq/github.com/kakakakakku/sandbox-git-worktree/wt-branch-a  670f24f [branch-a]
/Users/kakakakakku/ghq/github.com/kakakakakku/sandbox-git-worktree/wt-branch-b  670f24f [branch-b]
/Users/kakakakakku/ghq/github.com/kakakakakku/sandbox-git-worktree/wt-branch-c  670f24f [branch-c]

git-worktree : .gitignore と組み合わせる運用案

今の例では <path> として指定したディレクトリ名に wt-branch-a のようにプレフィックス wt- を付けていた.なぜ付けたのかと言うと,master ブランチでは以下のように branch-a などのディレクトリが Untracked files として認識されてしまうからで,誤ってコミットしてしまう懸念があった😇

$ git status
On branch master
Your branch is up to date with 'origin/master'.

Untracked files:
  (use "git add <file>..." to include in what will be committed)
    wt-branch-a/
    wt-branch-b/
    wt-branch-c/

nothing added to commit but untracked files present (use "git add" to track)

そこで .gitignore ファイルに wt-*/ と指定することにより「作業ツリー」を除外している.git worktree add コマンドでは <path> として Git リポジトリ以外のディレクトリを指定することもできるけど,個人的には使いにくく,今回紹介した構成で運用していて便利に使えている.

まとめ

「git-worktree(git worktree コマンド)」を使うと,Git リポジトリで複数ブランチを並行して操作できる.Git 2.5(2015年7月リリース)から使える機能だったけど,今まで知らなかった!運用として複数ブランチを並行して操作する頻度が高いなら便利だと思う!最高👌