git worktree はstashのいらないbranchのようなものだ。
git 2.7から使える。
branchを作る代わりに worktreeという名前のフォルダを作る
以下のメリットがある。
・複数のブランチを、別々のエディタで呼び出し、並列的に修正可能。
・ブランチの切り替えという概念がなくなるため作業効率が上がる。 つまり、git stashの必要がなくなる
以下のデメリットがある
・branchを作るのと違いgitignoreが適用されるため、1設定必要。
git worktreeがエンジニアの生産性を大幅に上げることを証明する。
1.まず、作業フォルダを作る。
mkdir workspace; cd workspace
2. 何かプロジェクトを作成。
react-native init AwesomeProject; cd AwesomeProject
3. 以下のコマンドで、branchとworktreeを一緒に作る。
git worktree add -b Foo ../Foo origin/master
Foo = 新しく作られるbranch名
../Foo = 新しく作られるworktree名
origin/master = origin/masterからbranchとworktreeを生やす。
現状以下のような構成になっている。
workspace
--AwesomeProject
----.git
--Foo (worktree)
----.git
4.Fooフォルダに移動してgitが使えることを確認。
cd ../Foo; git log;
試しにFooの中でcommitしてgit pushしてみよう。
以上!!!
実務で使うときは、以下のように、あるプロジェクトのmasterと、そのworktreeだけを含むフォルダを作るといい。
その際、masterは削除できないように設定しておくともっといい。
AwesomeProject
--AwesomeProject (master)
----.git
--Foo (worktree)
----.git
--HotFix (worktree)
----.git
便利なのはworktree間で.git以下のフォルダが同期していること。
そしてbranchが別々のフォルダにあることでそもそもgit stashをせずに作業が出来ること。
stashでなく、新しいエディタで、「直接」branchを開ける。
worktreeを消したい時は、rm -rf Fooだ。
なんて単純ながら革新的だろう。学習コストがほぼいらず、単純に生産性が上がる。
ただ.gitignoreで除外されるファイルはworktreeで同期しない。
gitignoreされてしまう。
そう、git worktreeはgitignoreが適用されてしまう。
それを回避するためにはrsync!
git worktree add -b Foo ../Foo master; rsync -a --exclude='.git' ../awesomeProject(コピー元のプロジェクトの名前)/ ../Foo
解説すると、localのmasterからFooというbranchを切り、Fooというフォルダの中にそのbranchを入れる。
rsyncは複雑なことができるcpコマンドだ。
localのmasterをFooというフォルダに.git以外のフォルダをコピーする。
30秒ほどかかるのが欠点。gitignoreされたファイルだけ、選択してコピーするやり方がわかるbashの達人の方がいらっしゃったらコメントしてください。
npmがインストールされている人は、
npx kabatree newBranch
で上記と同じことをしてくれる。
(私が制作しているnpmライブラリです。)
もし、git worktreeの仕組みが分からなかったら、worktreeの.gitとmasterの.gitを見てみよう。worktreeは単純な仕組みなので、すぐに理解できる。