Git2.5のアップデート内容について


概要

下記の記事を見てGitのバージョン2.5でどのような機能が追加されたのか調べてみました。
Git 2.5, including multiple worktrees and triangular workflows- https://github.com/blog/2042-git-2-5-including-multiple-worktrees-and-triangular-workflows

今回は、 worktreeコマンドと、追跡ブランチを示すシンタックスシュガーのみまとめました

検証前に、Githubにあがっているものを直接インストールしました。

bash
$ git clone https://github.com/git/git/
$ cd git
$ make install

worktree

ローカルリポジトリとして複数管理したいという、ケースがある場合に便利なものみたいです
Git2.4までだと、以下のようにわざわざそれぞれcloneして管理する必要がありました。

bash
$ git clone [email protected]:totomo/test.git test1
$ git clone [email protected]:totomo/test.git test2

worktreeコマンドを使うとさくっと指定した場所に、別のローカルリポジトリを作るみたいなことができます。

bash
# HEADから ~/test2にtest2をカレントブランチとしたローカルリポジトリを複製
$ git worktree add ~/test2

# ~/test2にmasterのHEADの親コミットから切ったtest2というブランチをカレントブランチとするローカルリポジトリを複製
$ git worktree add ~/test2 master^

# ../test2にmasterのHEADの親コミットから切ったhotfixというブランチをカレントブランチとするローカルリポジトリを複製
$ git worktree add ~/test2 -b hotfix master^

# ../test3にすでに他のworktreeコマンドで生成されたローカルリポジトリでcheckoutされているhotfixというブランチをカレントブランチとするローカルリポジトリを複製
$ git worktree add ~/test3 -f hotfix

git cloneで複製した時とは違い各ブランチの状態(HEADの参照先コミットハッシュ、ブランチが増えた場合)などは共有されます。
-fを付けないと他にworktreeコマンドで生成されたローカルリポジトリでcheckoutされているブランチを指定すると、怒られるのでそこだけ注意ですね
--detachオプションで無名ブランチを切ることもできます。
リリース前にcloneする習慣がある人とかは代わりにworktreeコマンドが使えるかもしれないです。
ただし、まだ実験的なもので、いくつかbugがあったり、 submoduleを内包するリポジトリでは利用が推奨されておらず、インターフェースもユーザの意見により今後変更されるかもしれないみたいです。

試しに、少しやってみると

bash
#worktree作成
$ pwd
/Users/toku/test
$ git worktree add ~/test2
Enter /Users/toku/test2 (identifier test2)
Switched to a new branch 'test2'

# test2ブランチにコミット
$ cd ../test2
$ git commit -am "Add empty modification" --allow-empty
$ $git rev-list HEAD -1
e0da2d47eb2dff09fe75f8ae87669b6bf9306731

# 元のディレクトリにtest2ブランチへのコミットが共有されているか確認
$ cd ../test
$ git rev-list test2 -1
e0da2d47eb2dff09fe75f8ae87669b6bf9306731

shorthand <reference>@{push}

<reference>@{push}という表記でupstreamブランチを指定することができます。
例えば、masterブランチの追跡ブランチがもつHEADとローカルリポジトリのmasterブランチのHEADにおけるコミットの差分は

bash
$ git log master@{push}...master
#カレントブランチがmasterの場合は、省略可能
$ git log @{push}...master

<reference>を初略した場合はカレントブランチの追跡ブランチのHEADが参照されます。