masterブランチでちょっとした変更をしたいんだけど、devブランチで作業しているから切り替えるのはめんどくさい。
そんな時はgit worktreeを使ってみてください。複数のブランチを切り替えずに操作できます。
※git worktreeを使うにはGit 2.7.0以降が必要です。それ以前のバージョンだとgit worktree listがありません。
ブランチの追加
操作したいブランチはこんな風に持ってくることができます。
git worktree add <作業ディレクトリ> <ブランチ名>
すると、作業ディレクトリ以下に指定したブランチの中身がリンクされます。
たとえば、git worktree add ./worktree-dev dev
とコマンドを打つと、./worktree-devディレクトリが作成され、その下にdevブランチの内容ができるわけです。
git worktreeは今いるブランチに影響を与えません。
つまり、作業中であっても操作したいブランチを持ってこれます(厳密にはsubmoduleと同じリンクディレクトリができます)。
commitなどはさっきの作業ディレクトリ以下に移動して行うというルールがあるだけで、基本的には今まで通りでOKです。
ちなみに、すでにブランチがある場合は作業ディレクトリを省略すると、ブランチ名のディレクトリで作成してくれます。
git worktree add dev
ブランチの削除
使い終わったブランチは作業ディレクトリを削除してください。
そののちに
git worktree prune
とコマンドを打てばキレイになくなります。
ブランチの一覧
現在リンクされているブランチを確認するにはこんな感じ。
git worktree list
# こんな感じで一覧が見れます
# /Users/shibukk/git-worktree-test 6d44d5d [master]
# /Users/shibukk/git-worktree-test/worktree-dev 894cec9 [dev]
応用編
git worktreeを使えば、さくっと修正してpull requestを投げるためのブランチを1行で作れます。
-b
は新規ブランチを一緒に作成するオプションです。
git worktree add hotfix-1 -b hotfix-1
なので、bashrcにこんな感じで指定のディレクトリにブランチを作成する関数を用意しておき、.gitignore
でそのディレクトリを無視するようにしておくと便利です。
function gwt() {
GIT_CDUP_DIR=`git rev-parse --show-cdup`
git worktree add ${GIT_CDUP_DIR}git-worktrees/$1 -b $1
}
git-worktrees/*
# これだけでpull request用のブランチができる
gwt <新規ブランチ名>
なお、git rev-parse --show-cdup
でリポジトリのrootを探すようにしているので、どのディレクトリにいてもgit-worktrees以下に作ってくれます。
ちなみに移動や削除もあると便利なので、以下の記事のシェルスクリプトを参考にすると良さそうです。
git worktreeの操作を便利にする
注意点
ローカルブランチがないとエラーになります。
リモートブランチにはあるという場合は、-b
を使えば問題ありません。
また、既に作業ツリーが存在しているブランチをチェックアウトしようとするとfatal: 'hotfix-1' already exists
みたいなエラーになるので、このエラーが出た場合はgit worktree list
を使って作業ツリーがないか確認してみてください。
作業ツリーがあった場合は上記のブランチ削除を実行すればOKです。