4月27日、Collaboraが「Git hooks, upgraded: What's new in Git 2.54 and coming in 2.55」と題した記事を公開した。この記事では、Git 2.54の新機能とGit 2.55で予定されているhooks機能の大幅強化について詳しく紹介されている。以下に、その内容を紹介する。
Git設定ファイルでhooksを管理する新機能
Git 2.54で最も注目すべき新機能は、設定ベースでhooksを管理できるようになった点だ。従来はリポジトリごとに.git/hooks/ディレクトリにスクリプトを配置する必要があったが、これがgit configで一元管理できるようになった。
[hook "linter"]
event = pre-push
command = ~/bin/linter --cpp20
[hook "no-leaks"]
event = pre-push
command = ~/bin/leak-detector
この例では、pre-pushイベントに対してリンターとメモリリーク検出器の2つのhooksを設定している。Git 2.54では、これらは設定に記述された順序で順次実行される。
この機能の真価は、Git設定のスコープ機能と組み合わせた時に発揮される。システムレベル(git config --system)では組織全体でhooksを統一でき、グローバルレベル(git config --global)では個人の開発環境に合わせたhooksを、ローカルレベル(git config --local)ではプロジェクト固有のhooksを設定できる。
Git 2.55で予定される並列実行機能
Git 2.55では、設定したhooksを並列実行できる機能が追加される予定だ。現在nextブランチに取り込まれており、2.55リリースでの提供が期待されている。
[hook "linter"]
event = pre-push
command = ~/bin/linter --cpp20
parallel = true
[hook "no-leaks"]
event = pre-push
command = ~/bin/leak-detector
parallel = true
[hook]
jobs = 2
parallel = trueの設定により、複数のhooksが同時実行される。hook.jobsで並列度を制御でき、-1を設定すると利用可能なCPUコア数が自動使用される。
並列実行はオプトイン方式が採用されている。既存のhooksが同一プログラムを実行したり、同じファイルに書き込む可能性があるためだ。
ただし、pre-commitやprepare-commit-msgなど、コミットメッセージバッファのような共有リソースを使用するhooksは安全上の理由で並列実行できない制限がある。
submoduleパス衝突問題の解決
Git 2.54では、submoduleの命名におけるパス衝突問題も解決された。従来はfooとfoo/barのように階層的に重なるsubmodule名を付けると、gitdirレベルで衝突してエラーになっていた。
$ git submodule add --name foo ../child path-a
$ git submodule add --name foo/bar ../child path-b
error: submodule git dir '.../.git/modules/foo/bar' is inside git dir '.../.git/modules/foo'
この問題は、大文字小文字を区別しないファイルシステムではFooとfooでも発生し、セキュリティ上の懸念もあった(特定のsubmodule名により他のリポジトリのhooksディレクトリを上書きできる可能性)。
解決策としてextensions.submodulePathConfig設定とsubmodule.<name>.gitdir設定が導入され、submoduleのgitdirを透過的にエンコードして衝突を回避できるようになった。
今後の展望
記事の著者らは、これらの新機能がGitのhooks運用を劇的に改善すると評価している。特に、組織レベルでhooksを標準化しつつ、開発者個人の環境に応じた柔軟性も保てる点が画期的だ。
今後は残りのhooksを新しいhook.h APIに移行し、古いhook APIを廃止する予定だという。また、JGit、libgit2、gitoxideなどの代替Git実装でも対応が進むことが期待されている。
詳細はGit hooks, upgraded: What's new in Git 2.54 and coming in 2.55を参照していただきたい。