数ヶ月の期間を経た後、git 2.2.0 がリリースされました。これは重大発表です。今回の内容には、あなたの git ワークフローを改善させる沢山の新機能が搭載されているからです。以下、アトラシアンが見出した利点を挙げていきます。

git archive が pathspecs を学習

git archive は、リポジトリ内容の ZIP あるいは TAR アーカイブを特定の修正によって生成させるコマンドです。アトラシアンでは、一部のチームがお客様に対して当社ツールのソースコードを分配する際に、これを利用しています。2.2.0 においては、pathspec (antglob に類似) を利用する事で、生成されたアーカイブにどのファイルを含めるか制限できます。これは、ドキュメンテーションや静的な Web リソース等、リポジトリから一定のファイルを抽出する際に便利です。例えば、git プロジェクトのリポジトリにおいて以下のコマンドを実行する事で、docs.zip という名称のアーカイブに git 2.2.0 向け HTML man ページを抽出できます。

1
git archive -o docs.zip v2.2.0 ‘Documentation/*.html’

git config がちょっと親切に

初めての git ユーザー向けに、git config はユーザー名、ホスト名および環境変数に基づいて、ユーザー名およびメールアドレスと共に .gitconfig を自動生成します (例えば、セットの場合は $EMAIL という具合)。これは既存ユーザーには影響を及ぼしません。しかし、git を初めて利用するユーザーがスムーズな体験を得られるよう、絶えず頑張ってくれている git チームには感心させられます。

git stash list でパッチ表示が可能に

git stash は、ワーキングコピーの変更点をまとめて一時退避してくれる便利なコマンドです。このため、コンテキストを切り替えて即座に他の内容に取りかかる事ができます。git stash list を後で使用して、以前 stash した内容を表示する事も可能です。これはすばらしいですね!私の場合、複数のプロジェクトに携わっているため常に気が散ってしまい、stash に何がしまわれているかを思い出すのは至難の業です。但し、デフォルトのアウトプットでは、必ずしも最高に便利という訳ではありません。

1
2
3
4
5
$ git stash list
stash@{0}: WIP on master: 1347163 Merge branch ‘release/1.1.4’
stash@{1}: On feature/ACDEV-1172-fileless-connect-addons: oh god why
stash@{2}: On feature/ACDEV-1208-move-shcemagen: docs refactor take 2
stash@{3}: On feature/ACDEV-1208-move-shcemagen: ugly munging of schema

多くの場合、私は何かをすぐに修正しなくてはならないプレッシャーの下で git stash を実行しているため、必ずしも分かりやすいメッセージが思いつく訳ではありません (上記 stash@{0} のケースであれば、私が何も指定しないため、git が “WIP (訳注: Work In Progress。作業中という意味)” で置き換えています)。これらのメッセージはその性質上一過性のものなので、長い目で見るとさほど重要ではありません。しかし、各 stash において何が行われたか、厳密に把握するのが若干難しくなります

ドキュメンテーションによると、アウトプットをフォーマットする際に git log コマンドに設定するあらゆるオプションを git stash list に適用できます。この知識があれば、各 stash の diff をプリントアウトする際に、-p フラグ (あるいは --patch) を git stash list にパスできるものと考えるのが普通でしょう。

しかし、2.2.0 以前では、あなたは間違っている事になるのです。

1
2
3
4
5
$ git stash list -p
stash@{0}: WIP on master: 1347163 Merge branch ‘release/1.1.4’
stash@{1}: On feature/ACDEV-1172-fileless-connect-addons: oh god why
stash@{2}: On feature/ACDEV-1208-move-shcemagen: docs refactor take 2
stash@{3}: On feature/ACDEV-1208-move-shcemagen: ugly munging of schema

git stash list -p が何ら便利な内容を表示しなかった理由は、git において stash が格納されている方法にあります。git に格納されているその他ほぼ全てのもの同様、これも DAG の一部として格納されています。実際には、stash は二つのコミットとして格納されています。

  1. git stash 実行時にステージされた変更点を含むコミット、また
  2. git stash 実行時にステージされなかった変更点を含むコミット。このコミットは “ステージされた変更点” のコミット、および以前の HEAD を親とします。

最近何かを stash したのであれば、以下を実行する事でこの構造を確認できます。

1
2
3
4
5
6
7
8
git log –graph –oneline stash@{0}

* eebf8fa WIP on <branch_name>: <prev_commit_message>
|\
| * 56206d3 index on <branch_name>: 2b2e5c3 <stash_message>
|/
* 2b2e5c3 <prev_commit_message>
* …

stash は二つの親によるマージコミットです。-p はどの親に対して diff を実行するかが分からないため、パッチの生成を拒否します。2.2.0 においては、git-stash.sh (git stash はシェルスクリプトとして実装されています) が -m および --first-parent フラグを次に実行する git log コマンドに渡すため、git stash list -p を利用して、stash した実際のパッチを表示する事が可能になりました。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ git stash list -p
stash@{0}: WIP on master: 1347163 Merge branch ‘release/1.1.4’
diff –git a/pom.xml b/pom.xml
index 07131d7..dd9b1db 100644
— a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
      <parent>
          <artifactId>atlassian-connect-api-parent</artifactId>
          <groupId>com.atlassian.plugins</groupId>
–         <version>1.1.4-RC-SNAPSHOT</version>
+         <version>1.1.4</version>
      </parent>
      <modelVersion>4.0.0</modelVersion>
stash@{1}: On feature/ACDEV-1172-fileless-connect-addons: oh god why

git fast-export の匿名化が可能に

これは、git 関連ツールを開発している人間にとって便利な話しで (我々のように!)、ワークフロー機能としてはさほど重要ではありません。git fast-export は、機密性の高いリポジトリコンテンツを当たり障りない文字列に置き換える、--anonymize フラグが使えるようになりました。これによって当社のサポートエンジニアは、お客様が git もしくは当社ソフトウェアにおいて問題に直面した際、リボジトリの匿名化バージョンを送ってもらう事ができるようになりました。

この新しいフラグは、困難な git 問題に直面して、実際のソースコードを晒さずにフォーラム上でリポジトリ構造を投稿したい場合にも便利です。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
$ git fast-export v2.2.0~1..v2.2.0
blob
mark :1
data 105
* whitespace=!indent,trail,space
*.[ch] whitespace=indent,trail,space
*.sh whitespace=indent,trail,space
blob
mark :2
data 3667
/GIT-BUILD-OPTIONS
/GIT-CFLAGS
/GIT-LDFLAGS

$ git fast-export –anonymize v2.2.0~1..v2.2.0
blob
mark :1
data 16
anonymous blob 0
blob
mark :2
data 16
anonymous blob 1

署名済プッシュ

この項目は、セキュリティを重視する方々にとって朗報です。Git はしばらくの間、タグとコミットの署名をサポートしてきましたが、これは特定の人物が一定の ref もしくはコミットを作成した事を認証するものでした。Mike Gerwitz の凄まじい git ホラー物語 を読めば、これらの技術の1つや2つ、デプロイした方がいいと考える良いきっかけとなるでしょう。

git 2.2.0 においては、プッシュ中に生じる実際の ref の更新という行為を署名できます。これは、リポジトリの ref に対する中間者攻撃やその他の未承認アップデートを防止する上で、重要なステップとなります。git push は、プッシュ開始時に送信される “プッシュ認証” に GPG 署名を適用する、--signed フラグが使えるようになりました。サーバー側では、git receive-pack (受信 git プッシュを扱うコマンド) が GPG 署名済のプッシュ認証の検証します。検証が失敗するとプッシュが拒否され、成功した場合は監査ログにお使いの git サーバーに対する特定の ref アップデートやオブジェクトを誰がいつプッシュしたか記録されます。

プッシュの GPG 署名(ついでに言えば、コミットやタグ) に関しては、調整にかなりのオーバーヘッドが生じます。また多くのチーム、特に監査ログ性能を備えたセキュアサーバー上で既にホスティングしているチームにとっては、得られるセキュリティ上の恩恵よりもかかった手間の方が大きくなってしまいます (例えば、Atlassian Stash)。ただし、新しい署名オプションに関する詳細を知りたい方は git receive-pack および git push の man ページを確認してみて下さい。

git help everyday

git help everyday を実行すると、git にバンドルされた “20 くらいのコマンドによる Everyday Git ” man ページが表示されます。これは良い内容ですが、比較的 git にまだ慣れていないデベロッパーにとっては少々急かもしれません。もしも git に関する知識を伸ばしたいと考えている場合は、当社の git サイト atlassian.com/ja/git から利用パターンやワークフローのアドバイスを得てから、Pro Git ebook へと突入して git の全貌を目の当たりにするのが良いでしょう。

Pretty-format が実用本位のデコレーションに向けて %D をサポート

git エイリアスに関心がある方は、お使いの git log コマンドを既に pretty format で飾り立てているかもしれません。Filipe Kiss は、git 履歴の重要な要素を多数取り入れた色鮮やかなログエイリアス を作成しています。

pretty-log (1)

これまで、ログ出力に ref 名を取り入れるには、"($refnames)"へと展開する %d 記号の使用がその唯一の方法でした。これだと、本来なら高度にカスタマイズ可能なログ出力形式において中括弧以外の何かを使用したい場合、厄介な事になります。2.2.0 において、%D 記号は通常のコンマで分けられた ref 名 (タグ、ブランチおよび HEAD) のリストに、また特定のコミットに向けた ref が存在しない場合は空の文字列に置き換えます。

パフォーマンス、バグ修正およびその他の改善点

いつもの事ながら、git チームは既に驚くべき速さの VCS から更なるパフォーマンスを引き出し、これまでのリリースにおけるいくつかの問題を修正する事に成功しました。変更内容の全リストに関してはリリースノート を確認するか、または以下から自らリポジトリを確認して変更点を把握して下さい。

1
git log v2.1.0..v2.2.0

今回のアップデートが為になったと感じたら、是非私の Twitter (I’m @kannonboy) をフォローして、不定期の git アップデートや、デベロッパーのワークフローに関する小話をご覧ください。

*本ブログは Atlassian Developers の翻訳です。本文中の日時などは投稿当時のものですのでご了承ください。
*原文 : 2014 年 12 月 1 日投稿 “Git 2.2.0 is out!

About Tim Pettersen

I'm a veteran Atlassian developer with almost a decade of service across the JIRA and Bitbucket teams. I speak and blog about developer workflows, Git, CI/CD, Java, and Atlassian's developer tools. Talk to me about plugin architecture, Node.js, Java, DVCS, or anything cool that you're hacking on!

View all posts by Tim Pettersen »