Git 2.6 からわずか 2 カ月後、膨大な機能と修正、そして性能の向上を果たした Git 2.7 がリリースされました。ここでは Bitbucket チームが興味を持った新しい機能を紹介します。

git worktree の完成

Git 2.5 で導入された素晴らしい git worktree コマンドを使うと、複数のリポジトリブランチからのチェックアウトやブランチ上での作業を、異なるディレクトリで同時に行うことができます。たとえば、簡単な修正をする必要があるけどワーキングコピーを汚したくない場合、次のように新しいブランチを新しいディレクトリにチェックアウトすることができます。

Screen Shot 2016-01-07 at 11.22.40 AM

Git 2.7 には、リポジトリのワークツリー (および関連するブランチ) を表示する git worktree list サブコマンドが追加されています。

2

ワークツリーをサポートする git bisect コマンドも改良されました。「良い」コミットと「悪い」コミットを追跡する bisect の参照が .git/refs/bisect から .git/refs/worktrees/$worktree_name/refs/bisect へ移動したため、複数のワークツリーで同時に bisect が実行できます。

Git 2.7 では、完全性のためにディスク上でワークツリーのクローンを作ることもできます。これにより、独立した新しい Git リポジトリ (他のワークツリーではない) が作成されます。

実際、Git ワークツリーはブランチのためだけのものではありません! 私はこの記事用に Git の機能を調べる際、Git v2.6.0 と v2.7.0 のタグを並べて比較するために、それらを異なるワークツリーへチェックアウトしてビルドしました。

3

git stash のいくつかの改善

git rebase が好きな方は --autostash オプションをご存じでしょう。これは、ワーキングコピー内で行われたローカルの変更をリベース前に自動でスタッシュして、リベースの完了後に再度適用するものです。

4

これによりダーティなワークツリーからリベースすることができて便利です。また、これをデフォルトで行うための rebase.autostash という便利な config フラグもあり、次のようにしてグローバルにできます。

rsz_5

rebase.autostash は、実際には Git 1.8.4 から利用できますが、2.7 では --no-autostash オプションでこのフラグをキャンセルすることが可能です。これを使うとダーティなワークツリーを警告するだけのようなので、主に完全性のために用意されているのだと思われます。

6

何か見落としているかもしれませんが、適切なユースケースをご存じでしたら 教えてください!

config フラグと言えば、Git 2.7 には stash.showPatch も導入されています。git stash show のデフォルトの動作では、スタッシュしたファイルの概要を表示します。

7

-p を渡すと git stash show が「パッチモード」になり、すべての diff が表示されます。

8

stash.showPatch はこの動作をデフォルトにします。以下のようにしてこれを有効にできます。

9

stash.showPatch を有効にしたもののファイルの概要のみを表示したくなった場合は、代わりに --stat オプションを渡すことで元の動作に戻すことができます。

10

余談ですが、--no-patch が妥当なオプションですが、期待通りに stash.showPatch を無効にしてくれません。

git filter-branch の高速化 (およびプログレスバー)

git filter-branch は、git history を書き換えるために幅広く使えるツールです。すべてのコミットオブジェクトは親の参照 (そして否応なくあらゆる祖先の参照) を持っているため、特定のコミットを書き換えることは、すべての 子孫を書き換えることにもなります。つまり、古いコミットを対象とする場合は、history に対する些細な書き換え作業さえも時間を要することになるのです。

Git 2.7 には新しい便利なプログレスバーが導入され、filter-branch コマンドが完了するまでどの程度の時間がかかるのかを見積もることができます。

filter-branch-progress-bar

おまけに、インデックスやツリーを修正しない filter-branch コマンドが、今ではインデックスの読み込みを飛ばして劇的に高速化しています。上の GIF 画像では、commit-filter コマンドを使用して、各コミット名と関連のある Git author を私の本名 (“Tim Pettersen”) からハンドルネーム (“Kannonboy”) に書き換えています。またツリーには触っていません。Bitbucket Server の最初の 1000 コミットを書き換えるために費やした時間は、Git 2.7.0 ではわずか 38 妙程度となり、それに対して Git 2.6.0 では約 64 秒となりました。驚くことに約 40% も高速化したのです。性能向上のテストではさらに驚くことに約 60% の節約を示しました。

.gitignore 内での無効化の改善

.gitignore ファイルで、リポジトリ内のワークツリーにある特定のファイルを除外することができますが、「無視しない」ファイルに ! を指定することで、以下のようにこのパターンを無効にできます。

11

これで cat.json 以外のすべての json ファイルを無視します。

しかし、Git 2.6 では無視されたディレクトリ内のファイルを無効にすることはできませんでした。

12

Git 2.7 では、上に示す 2 つ目の例もうまく機能します。今では、無視されているディレクトリ内の「無視しない」ファイルに ! を適用できます。

待って、まだあります!

2.7 で実装された Git の小さな長所がいくつかあります。それらは、Junio C Hamano のリリースノートでご確認頂くか、ご自身で Git リポジトリを調べてみてください。

13

この記事について、あるいは Git や Bitbucket についてご質問がある方は、私の Twitter @kannonboy までご連絡ください。




*本ブログは Atlassian Developers の翻訳です。本文中の日時などは投稿当時のものですのでご了承ください。
*原文 : 2016 年 1 月 5 日投稿 “Neat new features in Git 2.7

About Tim Pettersen

I served a few years as a developer on the JIRA, FishEye/Crucible and Stash teams. In early 2013 I switched to Developer Advocacy to spend some time traveling the world and meeting other like-minded developers (like you!). These days I speak and blog about developer workflows, git, continuous integration/deployment and Atlassian's developer tools: especially Stash. I regularly tweet about these things and other Atlassian arcana as @kannonboy.

View all posts by Tim Pettersen »